| Index: test/cctest/test-log.cc
|
| diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
|
| index eca2c2b67982799eb063e1d644217d1e4d0b604b..9853af32444fa4c40365b4c7110ced67dc3bcd46 100644
|
| --- a/test/cctest/test-log.cc
|
| +++ b/test/cctest/test-log.cc
|
| @@ -170,21 +170,110 @@ static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) {
|
| #endif // __linux__
|
|
|
|
|
| -static int CheckThatProfilerWorks(int log_pos) {
|
| - Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU);
|
| +namespace {
|
| +
|
| +class ScopedLoggerInitializer {
|
| + public:
|
| + explicit ScopedLoggerInitializer(bool log, bool prof_lazy)
|
| + : saved_log_(i::FLAG_log),
|
| + saved_prof_lazy_(i::FLAG_prof_lazy),
|
| + saved_prof_(i::FLAG_prof),
|
| + saved_prof_auto_(i::FLAG_prof_auto),
|
| + trick_to_run_init_flags_(init_flags_(log, prof_lazy)),
|
| + need_to_set_up_logger_(i::V8::IsRunning()),
|
| + scope_(),
|
| + env_(v8::Context::New()) {
|
| + if (need_to_set_up_logger_) Logger::Setup();
|
| + env_->Enter();
|
| + }
|
| +
|
| + ~ScopedLoggerInitializer() {
|
| + env_->Exit();
|
| + Logger::TearDown();
|
| + i::FLAG_prof_lazy = saved_prof_lazy_;
|
| + i::FLAG_prof = saved_prof_;
|
| + i::FLAG_prof_auto = saved_prof_auto_;
|
| + i::FLAG_log = saved_log_;
|
| + }
|
| +
|
| + v8::Handle<v8::Context>& env() { return env_; }
|
| +
|
| + private:
|
| + static bool init_flags_(bool log, bool prof_lazy) {
|
| + i::FLAG_log = log;
|
| + i::FLAG_prof = true;
|
| + i::FLAG_prof_lazy = prof_lazy;
|
| + i::FLAG_prof_auto = false;
|
| + i::FLAG_logfile = "*";
|
| + return prof_lazy;
|
| + }
|
| +
|
| + const bool saved_log_;
|
| + const bool saved_prof_lazy_;
|
| + const bool saved_prof_;
|
| + const bool saved_prof_auto_;
|
| + const bool trick_to_run_init_flags_;
|
| + const bool need_to_set_up_logger_;
|
| + v8::HandleScope scope_;
|
| + v8::Handle<v8::Context> env_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer);
|
| +};
|
| +
|
| +
|
| +class LogBufferMatcher {
|
| + public:
|
| + LogBufferMatcher() {
|
| + // Skip all initially logged stuff.
|
| + log_pos_ = GetLogLines(0, &buffer_);
|
| + }
|
| +
|
| + int log_pos() { return log_pos_; }
|
| +
|
| + int GetNextChunk() {
|
| + int chunk_size = GetLogLines(log_pos_, &buffer_);
|
| + CHECK_GT(buffer_.length(), chunk_size);
|
| + buffer_[chunk_size] = '\0';
|
| + log_pos_ += chunk_size;
|
| + return chunk_size;
|
| + }
|
| +
|
| + const char* Find(const char* substr) {
|
| + return strstr(buffer_.start(), substr);
|
| + }
|
| +
|
| + const char* Find(const i::Vector<char>& substr) {
|
| + return Find(substr.start());
|
| + }
|
| +
|
| + bool IsInSequence(const char* s1, const char* s2) {
|
| + const char* s1_pos = Find(s1);
|
| + const char* s2_pos = Find(s2);
|
| + CHECK_NE(NULL, s1_pos);
|
| + CHECK_NE(NULL, s2_pos);
|
| + return s1_pos < s2_pos;
|
| + }
|
| +
|
| + void PrintBuffer() {
|
| + puts(buffer_.start());
|
| + }
|
| +
|
| + private:
|
| + EmbeddedVector<char, 102400> buffer_;
|
| + int log_pos_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +
|
| +static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
|
| CHECK(LoggerTestHelper::IsSamplerActive());
|
|
|
| // Verify that the current map of compiled functions has been logged.
|
| - EmbeddedVector<char, 102400> buffer;
|
| - int map_log_size = GetLogLines(log_pos, &buffer);
|
| - printf("map_log_size: %d\n", map_log_size);
|
| - CHECK_GT(map_log_size, 0);
|
| - CHECK_GT(buffer.length(), map_log_size);
|
| - log_pos += map_log_size;
|
| - // Check buffer contents.
|
| - buffer[map_log_size] = '\0';
|
| + CHECK_GT(matcher->GetNextChunk(), 0);
|
| const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/
|
| - CHECK_NE(NULL, strstr(buffer.start(), code_creation));
|
| + CHECK_NE(NULL, matcher->Find(code_creation));
|
|
|
| #ifdef __linux__
|
| // Intercept SIGPROF handler to make sure that the test process
|
| @@ -204,7 +293,7 @@ static int CheckThatProfilerWorks(int log_pos) {
|
| i::OS::SNPrintF(script_src,
|
| "function f%d(x) { return %d * x; }"
|
| "for (var i = 0; i < 10000; ++i) { f%d(i); }",
|
| - log_pos, log_pos, log_pos);
|
| + matcher->log_pos(), matcher->log_pos(), matcher->log_pos());
|
| // Run code for 200 msecs to get some ticks.
|
| const double end_time = i::OS::TimeCurrentMillis() + 200;
|
| while (i::OS::TimeCurrentMillis() < end_time) {
|
| @@ -213,7 +302,7 @@ static int CheckThatProfilerWorks(int log_pos) {
|
| i::OS::Sleep(1);
|
| }
|
|
|
| - Logger::PauseProfiler(v8::PROFILER_MODULE_CPU);
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
|
| CHECK(!LoggerTestHelper::IsSamplerActive());
|
|
|
| // Wait 50 msecs to allow Profiler thread to process the last
|
| @@ -221,68 +310,39 @@ static int CheckThatProfilerWorks(int log_pos) {
|
| i::OS::Sleep(50);
|
|
|
| // Now we must have compiler and tick records.
|
| - int log_size = GetLogLines(log_pos, &buffer);
|
| - printf("log_size: %d\n", log_size);
|
| - CHECK_GT(log_size, 0);
|
| - CHECK_GT(buffer.length(), log_size);
|
| - log_pos += log_size;
|
| - // Check buffer contents.
|
| - buffer[log_size] = '\0';
|
| - printf("%s", buffer.start());
|
| + CHECK_GT(matcher->GetNextChunk(), 0);
|
| + matcher->PrintBuffer();
|
| + CHECK_NE(NULL, matcher->Find(code_creation));
|
| const char* tick = "\ntick,";
|
| - CHECK_NE(NULL, strstr(buffer.start(), code_creation));
|
| - const bool ticks_found = strstr(buffer.start(), tick) != NULL;
|
| + const bool ticks_found = matcher->Find(tick) != NULL;
|
| CHECK_EQ(was_sigprof_received, ticks_found);
|
| -
|
| - return log_pos;
|
| }
|
|
|
|
|
| TEST(ProfLazyMode) {
|
| - const bool saved_prof_lazy = i::FLAG_prof_lazy;
|
| - const bool saved_prof = i::FLAG_prof;
|
| - const bool saved_prof_auto = i::FLAG_prof_auto;
|
| - i::FLAG_prof = true;
|
| - i::FLAG_prof_lazy = true;
|
| - i::FLAG_prof_auto = false;
|
| - i::FLAG_logfile = "*";
|
| -
|
| - // If tests are being run manually, V8 will be already initialized
|
| - // by the bottom test.
|
| - const bool need_to_set_up_logger = i::V8::IsRunning();
|
| - v8::HandleScope scope;
|
| - v8::Handle<v8::Context> env = v8::Context::New();
|
| - if (need_to_set_up_logger) Logger::Setup();
|
| - env->Enter();
|
| + ScopedLoggerInitializer initialize_logger(false, true);
|
|
|
| // No sampling should happen prior to resuming profiler.
|
| CHECK(!LoggerTestHelper::IsSamplerActive());
|
|
|
| - EmbeddedVector<char, 102400> buffer;
|
| + LogBufferMatcher matcher;
|
| // Nothing must be logged until profiling is resumed.
|
| - int log_pos = GetLogLines(0, &buffer);
|
| - CHECK_EQ(0, log_pos);
|
| + CHECK_EQ(0, matcher.log_pos());
|
|
|
| CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
|
|
|
| // Nothing must be logged while profiling is suspended.
|
| - CHECK_EQ(0, GetLogLines(log_pos, &buffer));
|
| + CHECK_EQ(0, matcher.GetNextChunk());
|
|
|
| - log_pos = CheckThatProfilerWorks(log_pos);
|
| + CheckThatProfilerWorks(&matcher);
|
|
|
| CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
|
|
|
| // No new data beyond last retrieved position.
|
| - CHECK_EQ(0, GetLogLines(log_pos, &buffer));
|
| + CHECK_EQ(0, matcher.GetNextChunk());
|
|
|
| // Check that profiling can be resumed again.
|
| - CheckThatProfilerWorks(log_pos);
|
| -
|
| - env->Exit();
|
| - Logger::TearDown();
|
| - i::FLAG_prof_lazy = saved_prof_lazy;
|
| - i::FLAG_prof = saved_prof;
|
| - i::FLAG_prof_auto = saved_prof_auto;
|
| + CheckThatProfilerWorks(&matcher);
|
| }
|
|
|
|
|
| @@ -480,25 +540,8 @@ static v8::Handle<v8::Value> ObjMethod1(const v8::Arguments& args) {
|
| }
|
|
|
| TEST(LogCallbacks) {
|
| - const bool saved_prof_lazy = i::FLAG_prof_lazy;
|
| - const bool saved_prof = i::FLAG_prof;
|
| - const bool saved_prof_auto = i::FLAG_prof_auto;
|
| - i::FLAG_prof = true;
|
| - i::FLAG_prof_lazy = false;
|
| - i::FLAG_prof_auto = false;
|
| - i::FLAG_logfile = "*";
|
| -
|
| - // If tests are being run manually, V8 will be already initialized
|
| - // by the bottom test.
|
| - const bool need_to_set_up_logger = i::V8::IsRunning();
|
| - v8::HandleScope scope;
|
| - v8::Handle<v8::Context> env = v8::Context::New();
|
| - if (need_to_set_up_logger) Logger::Setup();
|
| - env->Enter();
|
| -
|
| - // Skip all initially logged stuff.
|
| - EmbeddedVector<char, 102400> buffer;
|
| - int log_pos = GetLogLines(0, &buffer);
|
| + ScopedLoggerInitializer initialize_logger(false, false);
|
| + LogBufferMatcher matcher;
|
|
|
| v8::Persistent<v8::FunctionTemplate> obj =
|
| v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
|
| @@ -511,16 +554,14 @@ TEST(LogCallbacks) {
|
| signature),
|
| static_cast<v8::PropertyAttribute>(v8::DontDelete));
|
|
|
| - env->Global()->Set(v8_str("Obj"), obj->GetFunction());
|
| + initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
|
| CompileAndRunScript("Obj.prototype.method1.toString();");
|
|
|
| i::Logger::LogCompiledFunctions();
|
| - log_pos = GetLogLines(log_pos, &buffer);
|
| - CHECK_GT(log_pos, 0);
|
| - buffer[log_pos] = 0;
|
| + CHECK_GT(matcher.GetNextChunk(), 0);
|
|
|
| const char* callback_rec = "code-creation,Callback,";
|
| - char* pos = strstr(buffer.start(), callback_rec);
|
| + char* pos = const_cast<char*>(matcher.Find(callback_rec));
|
| CHECK_NE(NULL, pos);
|
| pos += strlen(callback_rec);
|
| EmbeddedVector<char, 100> ref_data;
|
| @@ -530,12 +571,6 @@ TEST(LogCallbacks) {
|
| CHECK_EQ(ref_data.start(), pos);
|
|
|
| obj.Dispose();
|
| -
|
| - env->Exit();
|
| - Logger::TearDown();
|
| - i::FLAG_prof_lazy = saved_prof_lazy;
|
| - i::FLAG_prof = saved_prof;
|
| - i::FLAG_prof_auto = saved_prof_auto;
|
| }
|
|
|
|
|
| @@ -555,25 +590,8 @@ static v8::Handle<v8::Value> Prop2Getter(v8::Local<v8::String> property,
|
| }
|
|
|
| TEST(LogAccessorCallbacks) {
|
| - const bool saved_prof_lazy = i::FLAG_prof_lazy;
|
| - const bool saved_prof = i::FLAG_prof;
|
| - const bool saved_prof_auto = i::FLAG_prof_auto;
|
| - i::FLAG_prof = true;
|
| - i::FLAG_prof_lazy = false;
|
| - i::FLAG_prof_auto = false;
|
| - i::FLAG_logfile = "*";
|
| -
|
| - // If tests are being run manually, V8 will be already initialized
|
| - // by the bottom test.
|
| - const bool need_to_set_up_logger = i::V8::IsRunning();
|
| - v8::HandleScope scope;
|
| - v8::Handle<v8::Context> env = v8::Context::New();
|
| - if (need_to_set_up_logger) Logger::Setup();
|
| - env->Enter();
|
| -
|
| - // Skip all initially logged stuff.
|
| - EmbeddedVector<char, 102400> buffer;
|
| - int log_pos = GetLogLines(0, &buffer);
|
| + ScopedLoggerInitializer initialize_logger(false, false);
|
| + LogBufferMatcher matcher;
|
|
|
| v8::Persistent<v8::FunctionTemplate> obj =
|
| v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
|
| @@ -583,34 +601,112 @@ TEST(LogAccessorCallbacks) {
|
| inst->SetAccessor(v8::String::New("prop2"), Prop2Getter);
|
|
|
| i::Logger::LogAccessorCallbacks();
|
| - log_pos = GetLogLines(log_pos, &buffer);
|
| - CHECK_GT(log_pos, 0);
|
| - buffer[log_pos] = 0;
|
| - printf("%s", buffer.start());
|
| + CHECK_GT(matcher.GetNextChunk(), 0);
|
| + matcher.PrintBuffer();
|
|
|
| EmbeddedVector<char, 100> prop1_getter_record;
|
| i::OS::SNPrintF(prop1_getter_record,
|
| "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"",
|
| Prop1Getter);
|
| - CHECK_NE(NULL, strstr(buffer.start(), prop1_getter_record.start()));
|
| + CHECK_NE(NULL, matcher.Find(prop1_getter_record));
|
| EmbeddedVector<char, 100> prop1_setter_record;
|
| i::OS::SNPrintF(prop1_setter_record,
|
| "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"",
|
| Prop1Setter);
|
| - CHECK_NE(NULL, strstr(buffer.start(), prop1_setter_record.start()));
|
| + CHECK_NE(NULL, matcher.Find(prop1_setter_record));
|
| EmbeddedVector<char, 100> prop2_getter_record;
|
| i::OS::SNPrintF(prop2_getter_record,
|
| "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"",
|
| Prop2Getter);
|
| - CHECK_NE(NULL, strstr(buffer.start(), prop2_getter_record.start()));
|
| + CHECK_NE(NULL, matcher.Find(prop2_getter_record));
|
|
|
| obj.Dispose();
|
| +}
|
|
|
| - env->Exit();
|
| - Logger::TearDown();
|
| - i::FLAG_prof_lazy = saved_prof_lazy;
|
| - i::FLAG_prof = saved_prof;
|
| - i::FLAG_prof_auto = saved_prof_auto;
|
| +
|
| +TEST(LogTags) {
|
| + ScopedLoggerInitializer initialize_logger(true, false);
|
| + LogBufferMatcher matcher;
|
| +
|
| + const char* open_tag = "open-tag,";
|
| + const char* close_tag = "close-tag,";
|
| +
|
| + // Check compatibility with the old style behavior.
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + CHECK_EQ(NULL, matcher.Find(open_tag));
|
| + CHECK_EQ(NULL, matcher.Find(close_tag));
|
| +
|
| + const char* open_tag1 = "open-tag,1\n";
|
| + const char* close_tag1 = "close-tag,1\n";
|
| +
|
| + // Check non-nested tag case.
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + CHECK_GT(matcher.GetNextChunk(), 0);
|
| + CHECK(matcher.IsInSequence(open_tag1, close_tag1));
|
| +
|
| + const char* open_tag2 = "open-tag,2\n";
|
| + const char* close_tag2 = "close-tag,2\n";
|
| +
|
| + // Check nested tags case.
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + CHECK_GT(matcher.GetNextChunk(), 0);
|
| + // open_tag1 < open_tag2 < close_tag2 < close_tag1
|
| + CHECK(matcher.IsInSequence(open_tag1, open_tag2));
|
| + CHECK(matcher.IsInSequence(open_tag2, close_tag2));
|
| + CHECK(matcher.IsInSequence(close_tag2, close_tag1));
|
| +
|
| + // Check overlapped tags case.
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + CHECK_GT(matcher.GetNextChunk(), 0);
|
| + // open_tag1 < open_tag2 < close_tag1 < close_tag2
|
| + CHECK(matcher.IsInSequence(open_tag1, open_tag2));
|
| + CHECK(matcher.IsInSequence(open_tag2, close_tag1));
|
| + CHECK(matcher.IsInSequence(close_tag1, close_tag2));
|
| +
|
| + const char* open_tag3 = "open-tag,3\n";
|
| + const char* close_tag3 = "close-tag,3\n";
|
| +
|
| + // Check pausing overflow case.
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
|
| + CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 3);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 3);
|
| + CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
|
| + // Must be no tags, because logging must be disabled.
|
| + CHECK_EQ(NULL, matcher.Find(open_tag3));
|
| + CHECK_EQ(NULL, matcher.Find(close_tag3));
|
| }
|
|
|
|
|
|
|