Chromium Code Reviews| Index: test/cctest/test-log.cc |
| diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc |
| index d65a995a0d9abee580ce544b433d74d2ef516401..99522e5be757fadcf8c3b4bd6c356a87b36adbdd 100644 |
| --- a/test/cctest/test-log.cc |
| +++ b/test/cctest/test-log.cc |
| @@ -10,6 +10,7 @@ |
| #include "cctest.h" |
| using v8::internal::Address; |
| +using v8::internal::EmbeddedVector; |
| using v8::internal::Logger; |
| namespace i = v8::internal; |
| @@ -84,6 +85,12 @@ TEST(GetMessages) { |
| } |
| +template <typename T> |
|
Søren Thygesen Gjesse
2009/05/25 07:09:15
Why is this a template function? T needs to be cha
Mikhail Naganov
2009/05/25 08:23:43
Yep, you're right. Fixed.
|
| +static int GetLogLines(int start_pos, i::Vector<T>* buffer) { |
| + return Logger::GetLogLines(start_pos, buffer->start(), buffer->length()); |
| +} |
| + |
| + |
| TEST(BeyondWritePosition) { |
| SetUp(); |
| Logger::StringEvent("aaa", "bbb"); |
| @@ -91,14 +98,16 @@ TEST(BeyondWritePosition) { |
| // See Logger::StringEvent. |
| const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n"; |
| const int all_lines_len = strlen(all_lines); |
| - CHECK_EQ(0, Logger::GetLogLines(all_lines_len, NULL, 1)); |
| - CHECK_EQ(0, Logger::GetLogLines(all_lines_len, NULL, 100)); |
| - CHECK_EQ(0, Logger::GetLogLines(all_lines_len + 1, NULL, 1)); |
| - CHECK_EQ(0, Logger::GetLogLines(all_lines_len + 1, NULL, 100)); |
| - CHECK_EQ(0, Logger::GetLogLines(all_lines_len + 100, NULL, 1)); |
| - CHECK_EQ(0, Logger::GetLogLines(all_lines_len + 100, NULL, 100)); |
| - CHECK_EQ(0, Logger::GetLogLines(10 * 1024 * 1024, NULL, 1)); |
| - CHECK_EQ(0, Logger::GetLogLines(10 * 1024 * 1024, NULL, 100)); |
| + EmbeddedVector<char, 100> buffer; |
| + const int beyond_write_pos = all_lines_len; |
| + CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos, buffer.start(), 1)); |
| + CHECK_EQ(0, GetLogLines(beyond_write_pos, &buffer)); |
| + CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos + 1, buffer.start(), 1)); |
| + CHECK_EQ(0, GetLogLines(beyond_write_pos + 1, &buffer)); |
| + CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos + 100, buffer.start(), 1)); |
| + CHECK_EQ(0, GetLogLines(beyond_write_pos + 100, &buffer)); |
| + CHECK_EQ(0, Logger::GetLogLines(10 * 1024 * 1024, buffer.start(), 1)); |
| + CHECK_EQ(0, GetLogLines(10 * 1024 * 1024, &buffer)); |
| TearDown(); |
| } |
| @@ -116,6 +125,121 @@ TEST(MemoryLoggingTurnedOff) { |
| } |
| +static void CompileAndRunScript(const char *src) { |
| + v8::Script::Compile(v8::String::New(src))->Run(); |
| +} |
| + |
| + |
| +namespace v8 { |
| +namespace internal { |
| + |
| +class LoggerTestHelper : public AllStatic { |
| + public: |
| + static bool IsSamplerActive() { return Logger::IsProfilerSamplerActive(); } |
| +}; |
| + |
| +} // namespace v8::internal |
| +} // namespace v8 |
| + |
| +using v8::internal::LoggerTestHelper; |
| + |
| + |
| +static int CheckThatProfilerWorks(int log_pos) { |
| + Logger::ResumeProfiler(); |
| + 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'; |
| + const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/ |
| + CHECK_NE(NULL, strstr(buffer.start(), code_creation)); |
| + |
| + // Force compiler to generate new code by parametrizing source. |
| + EmbeddedVector<char, 100> script_src; |
| + i::OS::SNPrintF(script_src, |
| + "for (var i = 0; i < 1000; ++i) { " |
| + "(function(x) { return %d * x; })(i); }", |
| + log_pos); |
| + // Run code for 100 msecs to get some ticks. |
| + const int64_t started_us = i::OS::Ticks(); |
| + while (i::OS::Ticks() - started_us < 100 * 1000) { |
| + CompileAndRunScript(script_src.start()); |
| + } |
| + |
| + Logger::PauseProfiler(); |
| + CHECK(!LoggerTestHelper::IsSamplerActive()); |
| + |
| + // 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'; |
| + const char* tick = "\ntick,"; |
| + CHECK_NE(NULL, strstr(buffer.start(), code_creation)); |
| + CHECK_NE(NULL, strstr(buffer.start(), tick)); |
| + |
| + 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 test below. |
| + const bool need_to_set_up_logger = i::V8::HasBeenSetup(); |
| + v8::HandleScope scope; |
| + v8::Handle<v8::Context> env = v8::Context::New(); |
| + if (need_to_set_up_logger) Logger::Setup(); |
| + env->Enter(); |
| + |
| + // No sampling should happen prior to resuming profiler. |
| + CHECK(!LoggerTestHelper::IsSamplerActive()); |
| + |
| + // Read initial logged data (static libs map). |
| + EmbeddedVector<char, 102400> buffer; |
| + int log_pos = GetLogLines(0, &buffer); |
| + CHECK_GT(log_pos, 0); |
| + CHECK_GT(buffer.length(), 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)); |
| + |
| + log_pos = CheckThatProfilerWorks(log_pos); |
| + |
| + CompileAndRunScript("var a = (function(x) { return x + 1; })(10);"); |
| + |
| + // No new data beyond last retrieved position. |
| + CHECK_EQ(0, GetLogLines(log_pos, &buffer)); |
| + |
| + // 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; |
| +} |
| + |
| + |
| static inline bool IsStringEqualTo(const char* r, const char* s) { |
| return strncmp(r, s, strlen(r)) == 0; |
| } |
| @@ -487,6 +611,15 @@ static bool AreEntitiesEqual(CodeEntityInfo ref_e, CodeEntityInfo new_e) { |
| // Test that logging of code create / move / delete events |
| // is equivalent to traversal of a resulting heap. |
| TEST(EquivalenceOfLoggingAndTraversal) { |
| + // This test needs to be run on a "clean" V8 to ensure that snapshot log |
| + // is loaded. This is always true when running using tools/test.py because |
| + // it launches a new cctest instance for every test. To be sure that launching |
| + // cctest manually also works, please be sure that no tests below |
| + // are using V8. |
| + // |
| + // P.S. No, V8 can't be re-initialized after disposal, see include/v8.h. |
| + CHECK(!i::V8::HasBeenSetup()); |
| + |
| i::FLAG_logfile = "*"; |
| i::FLAG_log = true; |
| i::FLAG_log_code = true; |
| @@ -499,20 +632,19 @@ TEST(EquivalenceOfLoggingAndTraversal) { |
| v8::HandleScope scope; |
| v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); |
| - v8::Persistent<v8::Context> env = v8::Context::New( |
| + v8::Handle<v8::Context> env = v8::Context::New( |
| 0, v8::Handle<v8::ObjectTemplate>(), global_object); |
| env->Enter(); |
| // Compile and run a function that creates other functions. |
| - v8::Local<v8::Script> script = v8::Script::Compile(v8::String::New( |
| + CompileAndRunScript( |
| "(function f(obj) {\n" |
| " obj.test =\n" |
| " (function a(j) { return function b() { return j; } })(100);\n" |
| - "})(this);")); |
| - script->Run(); |
| + "})(this);"); |
| i::Heap::CollectAllGarbage(); |
| - i::EmbeddedVector<char, 204800> buffer; |
| + EmbeddedVector<char, 204800> buffer; |
| int log_size; |
| ParseLogResult ref_result; |
| @@ -521,7 +653,7 @@ TEST(EquivalenceOfLoggingAndTraversal) { |
| // Make sure that no GCs occur prior to LogCompiledFunctions call. |
| i::AssertNoAllocation no_alloc; |
| - log_size = Logger::GetLogLines(0, buffer.start(), buffer.length()); |
| + log_size = GetLogLines(0, &buffer); |
| CHECK_GT(log_size, 0); |
| CHECK_GT(buffer.length(), log_size); |
| @@ -566,7 +698,7 @@ TEST(EquivalenceOfLoggingAndTraversal) { |
| CHECK(results_equal); |
| env->Exit(); |
| - v8::V8::Dispose(); |
| + Logger::TearDown(); |
| i::FLAG_always_compact = saved_always_compact; |
| } |