Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: test/cctest/test-cpu-profiler.cc

Issue 424973004: Extend CPU profiler with mapping ticks to source lines (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed the comments Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/profile-generator.cc ('K') | « src/profile-generator-inl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-cpu-profiler.cc
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index a3e7b8d773a7bc51b11a981ed428621fa872d51f..60995264b672ec282af12691bb8769e91da07ebc 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -1064,6 +1064,121 @@ TEST(BoundFunctionCall) {
}
+static i::Code* GetFunctionCodeFromHeap(i::Isolate* isolate,
+ const char* name) {
+ CHECK_NE(NULL, isolate);
+ i::Heap* heap = isolate->heap();
+ CHECK_NE(NULL, heap);
+
+ heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
+ "Logger::LogCompiledFunctions");
yurys 2014/08/08 08:13:23 "GetFunctionCodeFromHeap"
+
+ i::HandleScope scope(isolate);
+ i::HeapIterator iterator(heap);
+ i::DisallowHeapAllocation no_gc;
+
+ // Iterate the heap to find shared function info objects.
+ for (i::HeapObject* obj = iterator.next();
+ obj != NULL;
+ obj = iterator.next()) {
+ if (!obj->IsSharedFunctionInfo()) continue;
+ i::SharedFunctionInfo* sfi = i::SharedFunctionInfo::cast(obj);
+ if (sfi->is_compiled()
+ && (!sfi->script()->IsScript()
+ || i::Script::cast(sfi->script())->HasValidSource())) {
+ i::Handle<i::String> func_name(sfi->DebugName());
+ i::SmartArrayPointer<char> str =
+ sfi->DebugName()->ToCString(i::DISALLOW_NULLS,
+ i::ROBUST_STRING_TRAVERSAL);
+ if (strcmp(str.get(), name) == 0)
+ return sfi->code();
+ }
+ }
+
+ return NULL;
+}
+
+
+// This tests checks distribution of the samples through the source lines.
+TEST(TickLines) {
+ CcTest::InitializeVM();
+ LocalContext env;
+ i::Isolate* isolate = CcTest::i_isolate();
+ CpuProfiler* profiler = isolate->cpu_profiler();
+ i::HandleScope scope(isolate);
+
+ i::EmbeddedVector<char, 512> source;
+ const char* foo_name = "foo";
+ i::SNPrintF(source,
+ "(function %s(timeout) {\n"
+ " this.mmm = 0;\n"
+ " var start = Date.now();\n"
+ " while (Date.now() - start < timeout) {\n"
+ " var n = 100*1000;\n"
+ " while(n > 1) {\n"
+ " n--;\n"
+ " this.mmm += n * n * n;\n"
+ " }\n"
+ " }\n"
+ "})(this)\n", foo_name);
yurys 2014/08/08 08:13:23 'this' passed as timeout looks like an error.
+
+ // Compile the source. The compiled functions with relocation info are
+ // located in the heap.
+ CompileRun(source.start());
+
+ // The profiler consumes code creation events for all compiled functions
+ // found in the heap.
+ profiler->StartProfiling("", false);
+
+ // Enqueue the tick events to add 'foo' function to the profile.
+ i::Code* foo_code = GetFunctionCodeFromHeap(isolate, foo_name);
+ CHECK_NE(NULL, foo_code);
+ i::Address address = foo_code->instruction_start();
+ CHECK_NE(NULL, address);
+ EnqueueTickSampleEvent(profiler->processor(), address);
+ v8::base::OS::Sleep(100); // Ensure that a new node is added to the profile.
yurys 2014/08/08 08:13:23 We need to use some explicit event instead of Slee
+
+ // Get a code entry for 'foo' function.
+ ProfileGenerator* generator = profiler->generator();
+ CodeEntry* foo = generator->code_map()->FindEntry(address);
yurys 2014/08/08 08:13:23 This is not thread-safe as code_map is used on the
+ CHECK_NE(NULL, foo);
+
+ CpuProfile* profile = profiler->StopProfiling("");
+ CHECK_NE(NULL, profile);
+
+ // Firstly, check the underlying code entry for 'foo' function.
+ CHECK_EQ(foo_name, foo->name());
+ const i::JITLineInfoTable* foo_line_info = foo->line_info();
+ CHECK_NE(NULL, foo_line_info);
+ CHECK_EQ(false, foo_line_info->Empty());
+
+ // Secondly, check the hit source lines are accessible using V8 Public APIs.
+ const i::ProfileTree* tree = profile->top_down();
+ ProfileNode* root = tree->root();
+ CHECK_NE(NULL, root);
+ ProfileNode* foo_node = root->FindChild(foo);
+ CHECK_NE(NULL, foo_node);
+
+ // Add 10 faked ticks to source line #5.
+ int hit_line = 5;
+ int hit_count = 10;
+ for (int i = 0; i < hit_count; i++)
+ foo_node->IncrementLineTicks(hit_line);
+
+ unsigned int line_count = foo_node->GetHitLineCount();
+ CHECK_EQ(2, line_count); // Expect two hit source lines - #1 and #5.
+ ScopedVector<v8::CpuProfileNode::LineTick> entries(line_count);
+ CHECK_EQ(true, foo_node->GetLineTicks(&entries[0], line_count));
+ int value = 0;
+ for (int i = 0; i < entries.length(); i++)
+ if (entries[i].line == hit_line) {
+ value = entries[i].hit_count;
+ break;
+ }
+ CHECK_EQ(hit_count, value);
+}
+
+
static const char* call_function_test_source = "function bar(iterations) {\n"
"}\n"
"function start(duration) {\n"
« src/profile-generator.cc ('K') | « src/profile-generator-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698