v8/test/cctest/test-log-utils.cc
mikhail.naganov@gmail.com e48095b87c Implement a dynamically growing memory log buffer with an upper limit.
The goal of this change is to allow longer profiling sessions and preserve memory when profiler isn't started. The buffer starts with 64K and grows until it reaches the upper limit, which is currently set to 50MB --- according to my evaluations, this is enough for at least 20 minutes of GMail profiling. As we're planning to introduce compression for the profiler log, this time boundary will be significantly increased soon.

To make possible unit testing of the new component, I've factored out Logger's utility classes into a separate source file: log-utils.h/cc. Log and LogMessageBuilder are moved there from log.cc without any semantical changes.

Review URL: http://codereview.chromium.org/115814


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-05-28 07:08:09 +00:00

109 lines
3.7 KiB
C++

// Copyright 2006-2009 the V8 project authors. All rights reserved.
//
// Tests of logging utilities from log-utils.h
#ifdef ENABLE_LOGGING_AND_PROFILING
#include "v8.h"
#include "log-utils.h"
#include "cctest.h"
using v8::internal::EmbeddedVector;
using v8::internal::LogDynamicBuffer;
using v8::internal::Vector;
// Fills 'ref_buffer' with test data: a sequence of two-digit
// hex numbers: '0001020304...'. Then writes 'ref_buffer' contents to 'dynabuf'.
static void WriteData(LogDynamicBuffer* dynabuf, Vector<char>* ref_buffer) {
static const char kHex[] = "0123456789ABCDEF";
CHECK_GT(ref_buffer->length(), 0);
CHECK_GT(513, ref_buffer->length());
for (int i = 0, half_len = ref_buffer->length() >> 1; i < half_len; ++i) {
(*ref_buffer)[i << 1] = kHex[i >> 4];
(*ref_buffer)[(i << 1) + 1] = kHex[i & 15];
}
if (ref_buffer->length() & 1) {
ref_buffer->last() = kHex[ref_buffer->length() >> 5];
}
CHECK_EQ(ref_buffer->length(),
dynabuf->Write(ref_buffer->start(), ref_buffer->length()));
}
static int ReadData(
LogDynamicBuffer* dynabuf, int start_pos, i::Vector<char>* buffer) {
return dynabuf->Read(start_pos, buffer->start(), buffer->length());
}
// Helper function used by CHECK_EQ to compare Vectors.
static inline void CheckEqualsHelper(const char* file, int line,
const char* expected_source,
const Vector<char>& expected,
const char* value_source,
const Vector<char>& value) {
if (expected.length() != value.length()) {
V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
"# Vectors lengths differ: %d expected, %d found",
expected_source, value_source,
expected.length(), value.length());
}
if (strncmp(expected.start(), value.start(), expected.length()) != 0) {
V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
"# Vectors contents differ:\n"
"# Expected: %.*s\n"
"# Found: %.*s",
expected_source, value_source,
expected.length(), expected.start(),
value.length(), value.start());
}
}
TEST(DynaBufSingleBlock) {
LogDynamicBuffer dynabuf(32, 32);
EmbeddedVector<char, 32> ref_buf;
WriteData(&dynabuf, &ref_buf);
EmbeddedVector<char, 32> buf;
CHECK_EQ(32, dynabuf.Read(0, buf.start(), buf.length()));
CHECK_EQ(32, ReadData(&dynabuf, 0, &buf));
CHECK_EQ(ref_buf, buf);
// Verify that we can't read and write past the end.
CHECK_EQ(0, dynabuf.Read(32, buf.start(), buf.length()));
CHECK_EQ(0, dynabuf.Write(buf.start(), buf.length()));
}
TEST(DynaBufCrossBlocks) {
LogDynamicBuffer dynabuf(32, 128);
EmbeddedVector<char, 48> ref_buf;
WriteData(&dynabuf, &ref_buf);
CHECK_EQ(48, dynabuf.Write(ref_buf.start(), ref_buf.length()));
// Verify that we can't write data when remaining buffer space isn't enough.
CHECK_EQ(0, dynabuf.Write(ref_buf.start(), ref_buf.length()));
EmbeddedVector<char, 48> buf;
CHECK_EQ(48, ReadData(&dynabuf, 0, &buf));
CHECK_EQ(ref_buf, buf);
CHECK_EQ(48, ReadData(&dynabuf, 48, &buf));
CHECK_EQ(ref_buf, buf);
CHECK_EQ(0, ReadData(&dynabuf, 48 * 2, &buf));
}
TEST(DynaBufReadTruncation) {
LogDynamicBuffer dynabuf(32, 128);
EmbeddedVector<char, 128> ref_buf;
WriteData(&dynabuf, &ref_buf);
EmbeddedVector<char, 128> buf;
CHECK_EQ(128, ReadData(&dynabuf, 0, &buf));
CHECK_EQ(ref_buf, buf);
// Try to read near the end with a buffer larger than remaining data size.
EmbeddedVector<char, 48> tail_buf;
CHECK_EQ(32, ReadData(&dynabuf, 128 - 32, &tail_buf));
CHECK_EQ(ref_buf.SubVector(128 - 32, 128), tail_buf.SubVector(0, 32));
}
#endif // ENABLE_LOGGING_AND_PROFILING