Revision: 4197
Author: [email protected]
Date: Fri Mar 19 06:51:01 2010
Log: Add a few tests to ProfilerEventsProcessor.

Review URL: http://codereview.chromium.org/1084009
http://code.google.com/p/v8/source/detail?r=4197

Added:
 /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc
Modified:
 /branches/bleeding_edge/src/cpu-profiler.h
 /branches/bleeding_edge/src/profile-generator.cc
 /branches/bleeding_edge/src/profile-generator.h
 /branches/bleeding_edge/test/cctest/SConscript
 /branches/bleeding_edge/test/cctest/test-profile-generator.cc
 /branches/bleeding_edge/tools/visual_studio/v8_cctest.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_cctest_arm.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_cctest_x64.vcproj

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Fri Mar 19 06:51:01 2010
@@ -0,0 +1,202 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+//
+// Tests of profiles generator and utilities.
+
+#include "v8.h"
+#include "cpu-profiler-inl.h"
+#include "cctest.h"
+
+namespace i = v8::internal;
+
+using i::CodeEntry;
+using i::CpuProfilesCollection;
+using i::ProfileGenerator;
+using i::ProfileNode;
+using i::ProfilerEventsProcessor;
+
+
+TEST(StartStop) {
+  CpuProfilesCollection profiles;
+  ProfileGenerator generator(&profiles);
+  ProfilerEventsProcessor processor(&generator);
+  processor.Start();
+  while (!processor.running()) {
+    i::Thread::YieldCPU();
+  }
+  processor.Stop();
+  processor.Join();
+}
+
+static v8::Persistent<v8::Context> env;
+
+static void InitializeVM() {
+  if (env.IsEmpty()) env = v8::Context::New();
+  v8::HandleScope scope;
+  env->Enter();
+}
+
+static inline i::Address ToAddress(int n) {
+  return reinterpret_cast<i::Address>(n);
+}
+
+static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
+                                   i::Address frame1,
+                                   i::Address frame2 = NULL,
+                                   i::Address frame3 = NULL) {
+  i::TickSample* sample = proc->TickSampleEvent();
+  sample->pc = frame1;
+  sample->function = frame1;
+  sample->frames_count = 0;
+  if (frame2 != NULL) {
+    sample->stack[0] = frame2;
+    sample->frames_count = 1;
+  }
+  if (frame3 != NULL) {
+    sample->stack[1] = frame3;
+    sample->frames_count = 2;
+  }
+}
+
+TEST(CodeEvents) {
+  InitializeVM();
+  CpuProfilesCollection profiles;
+  profiles.AddProfile(0);
+  ProfileGenerator generator(&profiles);
+  ProfilerEventsProcessor processor(&generator);
+  processor.Start();
+  processor.SetUpSamplesProducer();
+  while (!processor.running()) {
+    i::Thread::YieldCPU();
+  }
+
+  // Enqueue code creation events.
+  i::HandleScope scope;
+  const char* aaa_str = "aaa";
+  i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
+      i::Vector<const char>(aaa_str, strlen(aaa_str)));
+  processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
+                            *aaa_name,
+                            i::Heap::empty_string(),
+                            0,
+                            ToAddress(0x1000),
+                            0x100);
+  processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
+                            "bbb",
+                            ToAddress(0x1200),
+                            0x80);
+ processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
+  processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
+                            "ddd",
+                            ToAddress(0x1400),
+                            0x80);
+  processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
+ processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
+  processor.CodeDeleteEvent(ToAddress(0x1600));
+  processor.FunctionCreateEvent(ToAddress(0x1700), ToAddress(0x1000));
+  // Enqueue a tick event to enable code events processing.
+  EnqueueTickSampleEvent(&processor, ToAddress(0x1000));
+
+  processor.Stop();
+  processor.Join();
+
+  // Check the state of profile generator.
+  CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000));
+  CHECK_NE(NULL, entry1);
+  CHECK_EQ(aaa_str, entry1->name());
+  CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200));
+  CHECK_NE(NULL, entry2);
+  CHECK_EQ("bbb", entry2->name());
+  CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300));
+  CHECK_NE(NULL, entry3);
+  CHECK_EQ("args_count: 5", entry3->name());
+  CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400)));
+  CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500));
+  CHECK_NE(NULL, entry4);
+  CHECK_EQ("ddd", entry4->name());
+  CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600)));
+  CodeEntry* entry5 = generator.code_map()->FindEntry(ToAddress(0x1700));
+  CHECK_NE(NULL, entry5);
+  CHECK_EQ(aaa_str, entry5->name());
+
+  processor.TearDownSamplesProducer();
+}
+
+
+template<typename T>
+static int CompareProfileNodes(const T* p1, const T* p2) {
+  return strcmp((*p1)->entry()->name(), (*p2)->entry()->name());
+}
+
+TEST(TickEvents) {
+  CpuProfilesCollection profiles;
+  profiles.AddProfile(0);
+  ProfileGenerator generator(&profiles);
+  ProfilerEventsProcessor processor(&generator);
+  processor.Start();
+  processor.SetUpSamplesProducer();
+  while (!processor.running()) {
+    i::Thread::YieldCPU();
+  }
+
+  processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
+                            "bbb",
+                            ToAddress(0x1200),
+                            0x80);
+ processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
+  processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
+                            "ddd",
+                            ToAddress(0x1400),
+                            0x80);
+  EnqueueTickSampleEvent(&processor, ToAddress(0x1210));
+  EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220));
+  EnqueueTickSampleEvent(&processor,
+                         ToAddress(0x1404),
+                         ToAddress(0x1305),
+                         ToAddress(0x1230));
+
+  processor.Stop();
+  processor.Join();
+
+  // Check call trees.
+  i::List<ProfileNode*> top_down_root_children;
+ profiles.profile()->top_down()->root()->GetChildren(&top_down_root_children);
+  CHECK_EQ(1, top_down_root_children.length());
+  CHECK_EQ("bbb", top_down_root_children.last()->entry()->name());
+  i::List<ProfileNode*> top_down_bbb_children;
+  top_down_root_children.last()->GetChildren(&top_down_bbb_children);
+  CHECK_EQ(1, top_down_bbb_children.length());
+  CHECK_EQ("args_count: 5", top_down_bbb_children.last()->entry()->name());
+  i::List<ProfileNode*> top_down_stub_children;
+  top_down_bbb_children.last()->GetChildren(&top_down_stub_children);
+  CHECK_EQ(1, top_down_stub_children.length());
+  CHECK_EQ("ddd", top_down_stub_children.last()->entry()->name());
+  i::List<ProfileNode*> top_down_ddd_children;
+  top_down_stub_children.last()->GetChildren(&top_down_ddd_children);
+  CHECK_EQ(0, top_down_ddd_children.length());
+
+  i::List<ProfileNode*> bottom_up_root_children;
+  profiles.profile()->bottom_up()->root()->GetChildren(
+      &bottom_up_root_children);
+  CHECK_EQ(3, bottom_up_root_children.length());
+  bottom_up_root_children.Sort(&CompareProfileNodes);
+  CHECK_EQ("args_count: 5", bottom_up_root_children[0]->entry()->name());
+  CHECK_EQ("bbb", bottom_up_root_children[1]->entry()->name());
+  CHECK_EQ("ddd", bottom_up_root_children[2]->entry()->name());
+  i::List<ProfileNode*> bottom_up_stub_children;
+  bottom_up_root_children[0]->GetChildren(&bottom_up_stub_children);
+  CHECK_EQ(1, bottom_up_stub_children.length());
+  CHECK_EQ("bbb", bottom_up_stub_children.last()->entry()->name());
+  i::List<ProfileNode*> bottom_up_bbb_children;
+  bottom_up_root_children[1]->GetChildren(&bottom_up_bbb_children);
+  CHECK_EQ(0, bottom_up_bbb_children.length());
+  i::List<ProfileNode*> bottom_up_ddd_children;
+  bottom_up_root_children[2]->GetChildren(&bottom_up_ddd_children);
+  CHECK_EQ(1, bottom_up_ddd_children.length());
+ CHECK_EQ("args_count: 5", bottom_up_ddd_children.last()->entry()->name());
+  i::List<ProfileNode*> bottom_up_ddd_stub_children;
+  bottom_up_ddd_children.last()->GetChildren(&bottom_up_ddd_stub_children);
+  CHECK_EQ(1, bottom_up_ddd_stub_children.length());
+  CHECK_EQ("bbb", bottom_up_ddd_stub_children.last()->entry()->name());
+
+  processor.TearDownSamplesProducer();
+}
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.h  Fri Mar 19 06:49:28 2010
+++ /branches/bleeding_edge/src/cpu-profiler.h  Fri Mar 19 06:51:01 2010
@@ -135,6 +135,7 @@
   // Thread control.
   virtual void Run();
   inline void Stop() { running_ = false; }
+  INLINE(bool running()) { return running_; }

   // Events adding methods. Called by VM threads.
   void CodeCreateEvent(Logger::LogEventsAndTags tag,
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Fri Mar 19 02:46:53 2010 +++ /branches/bleeding_edge/src/profile-generator.cc Fri Mar 19 06:51:01 2010
@@ -51,6 +51,15 @@
   }
   return reinterpret_cast<ProfileNode*>(map_entry->value);
 }
+
+
+void ProfileNode::GetChildren(List<ProfileNode*>* children) {
+  for (HashMap::Entry* p = children_.Start();
+       p != NULL;
+       p = children_.Next(p)) {
+    children->Add(reinterpret_cast<ProfileNode*>(p->value));
+  }
+}


 void ProfileNode::Print(int indent) {
=======================================
--- /branches/bleeding_edge/src/profile-generator.h     Fri Mar 19 02:46:53 2010
+++ /branches/bleeding_edge/src/profile-generator.h     Fri Mar 19 06:51:01 2010
@@ -64,9 +64,10 @@
   INLINE(void IncrementSelfTicks()) { ++self_ticks_; }
INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; }

-  INLINE(CodeEntry* entry()) { return entry_; }
-  INLINE(unsigned total_ticks()) { return total_ticks_; }
-  INLINE(unsigned self_ticks()) { return self_ticks_; }
+  INLINE(CodeEntry* entry() const) { return entry_; }
+  INLINE(unsigned total_ticks() const) { return total_ticks_; }
+  INLINE(unsigned self_ticks() const) { return self_ticks_; }
+  void GetChildren(List<ProfileNode*>* children);

   void Print(int indent);

=======================================
--- /branches/bleeding_edge/test/cctest/SConscript      Fri Mar 19 05:15:24 2010
+++ /branches/bleeding_edge/test/cctest/SConscript      Fri Mar 19 06:51:01 2010
@@ -42,6 +42,7 @@
     'test-circular-queue.cc',
     'test-compiler.cc',
     'test-conversions.cc',
+    'test-cpu-profiler.cc',
     'test-dataflow.cc',
     'test-debug.cc',
     'test-decls.cc',
=======================================
--- /branches/bleeding_edge/test/cctest/test-profile-generator.cc Fri Mar 19 02:46:53 2010 +++ /branches/bleeding_edge/test/cctest/test-profile-generator.cc Fri Mar 19 06:51:01 2010
@@ -412,9 +412,9 @@
   ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1);
   CHECK_NE(NULL, node2);
   CHECK_EQ(entry1, node2->entry());
- // ProfileNode* node3 = top_down_test_helper.Walk(entry1, entry2, entry3);
-  // CHECK_NE(NULL, node3);
-  // CHECK_EQ(entry2, node3->entry());
+  ProfileNode* node3 = top_down_test_helper.Walk(entry1, entry2, entry3);
+  CHECK_NE(NULL, node3);
+  CHECK_EQ(entry3, node3->entry());
   ProfileNode* node4 = top_down_test_helper.Walk(entry1, entry3, entry1);
   CHECK_NE(NULL, node4);
   CHECK_EQ(entry1, node4->entry());
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_cctest.vcproj Wed Mar 17 06:15:42 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_cctest.vcproj Fri Mar 19 06:51:01 2010
@@ -166,6 +166,10 @@
                <File
                        RelativePath="..\..\test\cctest\test-conversions.cc"
                        >
+               </File>
+               <File
+                       RelativePath="..\..\test\cctest\test-cpu-profiler.cc"
+                       >
                </File>
                <File
                        RelativePath="..\..\test\cctest\test-debug.cc"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_cctest_arm.vcproj Wed Mar 17 06:15:42 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_cctest_arm.vcproj Fri Mar 19 06:51:01 2010
@@ -166,6 +166,10 @@
                <File
                        RelativePath="..\..\test\cctest\test-conversions.cc"
                        >
+               </File>
+               <File
+                       RelativePath="..\..\test\cctest\test-cpu-profiler.cc"
+                       >
                </File>
                <File
                        RelativePath="..\..\test\cctest\test-debug.cc"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_cctest_x64.vcproj Wed Mar 17 06:15:42 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_cctest_x64.vcproj Fri Mar 19 06:51:01 2010
@@ -166,6 +166,10 @@
                <File
                        RelativePath="..\..\test\cctest\test-conversions.cc"
                        >
+               </File>
+               <File
+                       RelativePath="..\..\test\cctest\test-cpu-profiler.cc"
+                       >
                </File>
                <File
                        RelativePath="..\..\test\cctest\test-debug.cc"

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

To unsubscribe from this group, send email to v8-dev+unsubscribegooglegroups.com or reply 
to this email with the words "REMOVE ME" as the subject.

Reply via email to