Revision: 4317
Author: [email protected]
Date: Tue Mar 30 04:38:39 2010
Log: C++ profiles processor: put under #ifdef and fix issues.

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

Modified:
 /branches/bleeding_edge/SConstruct
 /branches/bleeding_edge/src/circular-queue.h
 /branches/bleeding_edge/src/cpu-profiler-inl.h
 /branches/bleeding_edge/src/cpu-profiler.cc
 /branches/bleeding_edge/src/cpu-profiler.h
 /branches/bleeding_edge/src/profile-generator-inl.h
 /branches/bleeding_edge/src/profile-generator.cc
 /branches/bleeding_edge/src/profile-generator.h
 /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc
 /branches/bleeding_edge/test/cctest/test-profile-generator.cc

=======================================
--- /branches/bleeding_edge/SConstruct  Fri Mar 26 00:47:41 2010
+++ /branches/bleeding_edge/SConstruct  Tue Mar 30 04:38:39 2010
@@ -1,4 +1,4 @@
-# Copyright 2008 the V8 project authors. All rights reserved.
+# Copyright 2010 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -105,6 +105,9 @@
     'profilingsupport:on': {
       'CPPDEFINES':   ['ENABLE_LOGGING_AND_PROFILING'],
     },
+    'cppprofilesprocessor:on': {
+      'CPPDEFINES':   ['ENABLE_CPP_PROFILES_PROCESSOR'],
+    },
     'debuggersupport:on': {
       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT'],
     }
@@ -674,6 +677,11 @@
     'default': 'on',
     'help': 'enable profiling of JavaScript code'
   },
+  'cppprofilesprocessor': {
+    'values': ['on', 'off'],
+    'default': 'off',
+    'help': 'enable C++ profiles processor'
+  },
   'debuggersupport': {
     'values': ['on', 'off'],
     'default': 'on',
=======================================
--- /branches/bleeding_edge/src/circular-queue.h        Mon Mar 22 07:23:45 2010
+++ /branches/bleeding_edge/src/circular-queue.h        Tue Mar 30 04:38:39 2010
@@ -119,6 +119,8 @@
   byte* positions_;
   ProducerPosition* producer_pos_;
   ConsumerPosition* consumer_pos_;
+
+  DISALLOW_COPY_AND_ASSIGN(SamplingCircularQueue);
 };


=======================================
--- /branches/bleeding_edge/src/cpu-profiler-inl.h      Fri Mar 19 02:46:53 2010
+++ /branches/bleeding_edge/src/cpu-profiler-inl.h      Tue Mar 30 04:38:39 2010
@@ -28,6 +28,8 @@
 #ifndef V8_CPU_PROFILER_INL_H_
 #define V8_CPU_PROFILER_INL_H_

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "circular-queue-inl.h"
 #include "profile-generator-inl.h"

@@ -36,15 +38,15 @@
 namespace v8 {
 namespace internal {

-
 TickSample* ProfilerEventsProcessor::TickSampleEvent() {
   TickSampleEventRecord* evt =
-      reinterpret_cast<TickSampleEventRecord*>(ticks_buffer_.Enqueue());
+      TickSampleEventRecord::cast(ticks_buffer_.Enqueue());
   evt->order = enqueue_order_;  // No increment!
   return &evt->sample;
 }
-

 } }  // namespace v8::internal

+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
+
 #endif  // V8_CPU_PROFILER_INL_H_
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Mon Mar 22 07:23:45 2010
+++ /branches/bleeding_edge/src/cpu-profiler.cc Tue Mar 30 04:38:39 2010
@@ -25,6 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "v8.h"

 #include "cpu-profiler-inl.h"
@@ -32,7 +34,6 @@
 namespace v8 {
 namespace internal {

-
 static const int kEventsBufferSize = 256*KB;
 static const int kTickSamplesBufferChunkSize = 64*KB;
 static const int kTickSamplesBufferChunksCount = 16;
@@ -163,7 +164,7 @@
 bool ProfilerEventsProcessor::ProcessTicks(unsigned dequeue_order) {
   while (true) {
     const TickSampleEventRecord* rec =
- reinterpret_cast<TickSampleEventRecord*>(ticks_buffer_.StartDequeue());
+        TickSampleEventRecord::cast(ticks_buffer_.StartDequeue());
     if (rec == NULL) return false;
     if (rec->order == dequeue_order) {
       generator_->RecordTickSample(rec->sample);
@@ -194,6 +195,7 @@
// Perform processing until we have tick events, skip remaining code events. while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
 }
-

 } }  // namespace v8::internal
+
+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.h  Mon Mar 22 07:23:45 2010
+++ /branches/bleeding_edge/src/cpu-profiler.h  Tue Mar 30 04:38:39 2010
@@ -28,13 +28,14 @@
 #ifndef V8_CPU_PROFILER_H_
 #define V8_CPU_PROFILER_H_

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "circular-queue.h"
 #include "profile-generator.h"

 namespace v8 {
 namespace internal {

-
 #define CODE_EVENTS_TYPE_LIST(V)                \
   V(CODE_CREATION, CodeCreateEventRecord)       \
   V(CODE_MOVE,     CodeMoveEventRecord)         \
@@ -101,7 +102,7 @@
 };


-class TickSampleEventRecord {
+class TickSampleEventRecord BASE_EMBEDDED {
  public:
// In memory, the first machine word of a TickSampleEventRecord will be the
   // first entry of TickSample, that is -- a program counter field.
@@ -110,18 +111,12 @@
   TickSample sample;
   unsigned order;

-#if defined(__GNUC__) && (__GNUC__ < 4)
-  // Added to avoid 'all member functions in class are private' warning.
-  INLINE(unsigned get_order() const) { return order; }
-  // Added to avoid 'class only defines private constructors and
-  // has no friends' warning.
-  friend class TickSampleEventRecordFriend;
-#endif
- private:
-  // Disable instantiation.
-  TickSampleEventRecord();
-
-  DISALLOW_COPY_AND_ASSIGN(TickSampleEventRecord);
+  static TickSampleEventRecord* cast(void* value) {
+    return reinterpret_cast<TickSampleEventRecord*>(value);
+  }
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(TickSampleEventRecord);
 };


@@ -179,7 +174,8 @@
   unsigned enqueue_order_;
 };

-
 } }  // namespace v8::internal

+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
+
 #endif  // V8_CPU_PROFILER_H_
=======================================
--- /branches/bleeding_edge/src/profile-generator-inl.h Fri Mar 19 02:46:53 2010 +++ /branches/bleeding_edge/src/profile-generator-inl.h Tue Mar 30 04:38:39 2010
@@ -28,12 +28,13 @@
 #ifndef V8_PROFILE_GENERATOR_INL_H_
 #define V8_PROFILE_GENERATOR_INL_H_

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "profile-generator.h"

 namespace v8 {
 namespace internal {

-
 CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
                      const char* name,
                      const char* resource_name,
@@ -76,6 +77,14 @@
 }


+bool CpuProfilesCollection::is_last_profile() {
+  // Called from VM thread, and only it can mutate the list,
+  // so no locking is needed here.
+  return current_profiles_.length() == 1;
+}
+
 } }  // namespace v8::internal

+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
+
 #endif  // V8_PROFILE_GENERATOR_INL_H_
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Fri Mar 19 06:51:01 2010 +++ /branches/bleeding_edge/src/profile-generator.cc Tue Mar 30 04:38:39 2010
@@ -25,15 +25,15 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "v8.h"

 #include "profile-generator-inl.h"

-
 namespace v8 {
 namespace internal {

-
 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
   HashMap::Entry* map_entry =
       children_.Lookup(entry, CodeEntryHash(entry), false);
@@ -47,23 +47,16 @@
       children_.Lookup(entry, CodeEntryHash(entry), true);
   if (map_entry->value == NULL) {
     // New node added.
-    map_entry->value = new ProfileNode(entry);
+    ProfileNode* new_node = new ProfileNode(entry);
+    map_entry->value = new_node;
+    children_list_.Add(new_node);
   }
   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) {
-  OS::Print("%4u %4u %*c %s\n",
+  OS::Print("%5u %5u %*c %s\n",
             total_ticks_, self_ticks_,
             indent, ' ',
             entry_ != NULL ? entry_->name() : "");
@@ -123,39 +116,46 @@

 namespace {

-struct Position {
-  Position(ProfileNode* a_node, HashMap::Entry* a_p)
-      : node(a_node), p(a_p) { }
+class Position {
+ public:
+  explicit Position(ProfileNode* node)
+      : node(node), child_idx_(0) { }
   INLINE(ProfileNode* current_child()) {
-    return reinterpret_cast<ProfileNode*>(p->value);
-  }
+    return node->children()->at(child_idx_);
+  }
+  INLINE(bool has_current_child()) {
+    return child_idx_ < node->children()->length();
+  }
+  INLINE(void next_child()) { ++child_idx_; }
+
   ProfileNode* node;
-  HashMap::Entry* p;
+ private:
+  int child_idx_;
 };

 }  // namespace


+// Non-recursive implementation of breadth-first post-order tree traversal.
 template <typename Callback>
 void ProfileTree::TraverseBreadthFirstPostOrder(Callback* callback) {
   List<Position> stack(10);
-  stack.Add(Position(root_, root_->children_.Start()));
+  stack.Add(Position(root_));
   do {
     Position& current = stack.last();
-    if (current.p != NULL) {
-      stack.Add(Position(current.current_child(),
-                         current.current_child()->children_.Start()));
+    if (current.has_current_child()) {
+      stack.Add(Position(current.current_child()));
     } else {
       callback->AfterAllChildrenTraversed(current.node);
       if (stack.length() > 1) {
         Position& parent = stack[stack.length() - 2];
         callback->AfterChildTraversed(parent.node, current.node);
-        parent.p = parent.node->children_.Next(parent.p);
+        parent.next_child();
         // Remove child from the stack.
         stack.RemoveLast();
       }
     }
-  } while (stack.length() > 1 || stack.last().p != NULL);
+  } while (stack.length() > 1 || stack.last().has_current_child());
 }


@@ -175,7 +175,6 @@
 }  // namespace


-// Non-recursive implementation of breadth-first tree traversal.
 void ProfileTree::CalculateTotalTicks() {
   CalculateTotalTicksCallback cb;
   TraverseBreadthFirstPostOrder(&cb);
@@ -240,10 +239,24 @@
   }
   return NULL;
 }
+
+
+void CodeMap::CodeTreePrinter::Call(
+    const Address& key, const CodeMap::CodeEntryInfo& value) {
+  OS::Print("%p %5d %s\n", key, value.size, value.entry->name());
+}
+
+
+void CodeMap::Print() {
+  CodeTreePrinter printer;
+  tree_.ForEach(&printer);
+}


 CpuProfilesCollection::CpuProfilesCollection()
-    : function_and_resource_names_(StringsMatch) {
+    : function_and_resource_names_(StringsMatch),
+      profiles_uids_(CpuProfilesMatch),
+      current_profiles_semaphore_(OS::CreateSemaphore(1)) {
 }


@@ -262,6 +275,8 @@


 CpuProfilesCollection::~CpuProfilesCollection() {
+  delete current_profiles_semaphore_;
+  current_profiles_.Iterate(DeleteCpuProfile);
   profiles_.Iterate(DeleteCpuProfile);
   code_entries_.Iterate(DeleteCodeEntry);
   args_count_names_.Iterate(DeleteArgsCountName);
@@ -273,8 +288,63 @@
 }


-void CpuProfilesCollection::AddProfile(unsigned uid) {
-  profiles_.Add(new CpuProfile());
+bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid) {
+  ASSERT(uid > 0);
+  current_profiles_semaphore_->Wait();
+  for (int i = 0; i < current_profiles_.length(); ++i) {
+    if (strcmp(current_profiles_[i]->title(), title) == 0) {
+      // Ignore attempts to start profile with the same title.
+      current_profiles_semaphore_->Signal();
+      return false;
+    }
+  }
+  current_profiles_.Add(new CpuProfile(title, uid));
+  current_profiles_semaphore_->Signal();
+  return true;
+}
+
+
+bool CpuProfilesCollection::StartProfiling(String* title, unsigned uid) {
+  return StartProfiling(GetName(title), uid);
+}
+
+
+CpuProfile* CpuProfilesCollection::StopProfiling(const char* title) {
+  const int title_len = strlen(title);
+  CpuProfile* profile = NULL;
+  current_profiles_semaphore_->Wait();
+  for (int i = current_profiles_.length() - 1; i >= 0; --i) {
+ if (title_len == 0 || strcmp(current_profiles_[i]->title(), title) == 0) {
+      profile = current_profiles_.Remove(i);
+      break;
+    }
+  }
+  current_profiles_semaphore_->Signal();
+
+  if (profile != NULL) {
+    profile->CalculateTotalTicks();
+    profiles_.Add(profile);
+    HashMap::Entry* entry =
+        profiles_uids_.Lookup(reinterpret_cast<void*>(profile->uid()),
+                              static_cast<uint32_t>(profile->uid()),
+                              true);
+    ASSERT(entry->value == NULL);
+    entry->value = profile;
+  }
+  return profile;
+}
+
+
+CpuProfile* CpuProfilesCollection::StopProfiling(String* title) {
+  return StopProfiling(GetName(title));
+}
+
+
+CpuProfile* CpuProfilesCollection::GetProfile(unsigned uid) {
+ HashMap::Entry* entry = profiles_uids_.Lookup(reinterpret_cast<void*>(uid),
+                                                static_cast<uint32_t>(uid),
+                                                false);
+ return entry != NULL ? reinterpret_cast<CpuProfile*>(entry->value) : NULL;
 }


@@ -293,7 +363,10 @@

CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
                                                const char* name) {
-  CodeEntry* entry = new CodeEntry(tag, name, "", 0);
+  CodeEntry* entry = new CodeEntry(tag,
+                                   name,
+                                   "",
+                                   kNoLineNumberInfo);
   code_entries_.Add(entry);
   return entry;
 }
@@ -301,7 +374,10 @@

CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
                                                int args_count) {
-  CodeEntry* entry = new CodeEntry(tag, GetName(args_count), "", 0);
+  CodeEntry* entry = new CodeEntry(tag,
+                                   GetName(args_count),
+                                   "",
+                                   kNoLineNumberInfo);
   code_entries_.Add(entry);
   return entry;
 }
@@ -343,6 +419,19 @@
   }
   return args_count_names_[args_count];
 }
+
+
+void CpuProfilesCollection::AddPathToCurrentProfiles(
+    const Vector<CodeEntry*>& path) {
+  // As starting / stopping profiles is rare relatively to this
+  // method, we don't bother minimizing the duration of lock holding,
+  // e.g. copying contents of the list to a local vector.
+  current_profiles_semaphore_->Wait();
+  for (int i = 0; i < current_profiles_.length(); ++i) {
+    current_profiles_[i]->AddPath(path);
+  }
+  current_profiles_semaphore_->Signal();
+}


 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
@@ -377,8 +466,9 @@
     *entry++ = code_map_.FindEntry(*stack_pos);
   }

-  profile()->AddPath(entries);
-}
-
+  profiles_->AddPathToCurrentProfiles(entries);
+}

 } }  // namespace v8::internal
+
+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
=======================================
--- /branches/bleeding_edge/src/profile-generator.h     Fri Mar 19 06:51:01 2010
+++ /branches/bleeding_edge/src/profile-generator.h     Tue Mar 30 04:38:39 2010
@@ -28,12 +28,13 @@
 #ifndef V8_PROFILE_GENERATOR_H_
 #define V8_PROFILE_GENERATOR_H_

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "hashmap.h"

 namespace v8 {
 namespace internal {

-
 class CodeEntry {
  public:
   // CodeEntry doesn't own name strings, just references them.
@@ -44,6 +45,8 @@

   INLINE(bool is_js_function());
   INLINE(const char* name()) { return name_; }
+  INLINE(const char* resource_name()) { return name_; }
+  INLINE(int line_number()) { return line_number_; }

  private:
   Logger::LogEventsAndTags tag_;
@@ -67,7 +70,7 @@
   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);
+ INLINE(const List<ProfileNode*>* children() const) { return &children_list_; }

   void Print(int indent);

@@ -85,14 +88,13 @@
   unsigned self_ticks_;
   // CodeEntry* -> ProfileNode*
   HashMap children_;
-
-  friend class ProfileTree;
+  List<ProfileNode*> children_list_;

   DISALLOW_COPY_AND_ASSIGN(ProfileNode);
 };


-class ProfileTree BASE_EMBEDDED {
+class ProfileTree {
  public:
   ProfileTree() : root_(new ProfileNode(NULL)) { }
   ~ProfileTree();
@@ -101,7 +103,7 @@
   void AddPathFromStart(const Vector<CodeEntry*>& path);
   void CalculateTotalTicks();

-  ProfileNode* root() { return root_; }
+  ProfileNode* root() const { return root_; }

   void ShortPrint();
   void Print() {
@@ -120,18 +122,24 @@

 class CpuProfile {
  public:
-  CpuProfile() { }
+  CpuProfile(const char* title, unsigned uid)
+      : title_(title), uid_(uid) { }
+
   // Add pc -> ... -> main() call path to the profile.
   void AddPath(const Vector<CodeEntry*>& path);
   void CalculateTotalTicks();

-  INLINE(ProfileTree* top_down()) { return &top_down_; }
-  INLINE(ProfileTree* bottom_up()) { return &bottom_up_; }
+  INLINE(const char* title() const) { return title_; }
+  INLINE(unsigned uid() const) { return uid_; }
+  INLINE(const ProfileTree* top_down() const) { return &top_down_; }
+  INLINE(const ProfileTree* bottom_up() const) { return &bottom_up_; }

   void ShortPrint();
   void Print();

  private:
+  const char* title_;
+  unsigned uid_;
   ProfileTree top_down_;
   ProfileTree bottom_up_;

@@ -139,7 +147,7 @@
 };


-class CodeMap BASE_EMBEDDED {
+class CodeMap {
  public:
   CodeMap() { }
   INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size));
@@ -148,6 +156,8 @@
   void AddAlias(Address alias, Address addr);
   CodeEntry* FindEntry(Address addr);

+  void Print();
+
  private:
   struct CodeEntryInfo {
     CodeEntryInfo(CodeEntry* an_entry, unsigned a_size)
@@ -167,6 +177,11 @@
   };
   typedef SplayTree<CodeTreeConfig> CodeTree;

+  class CodeTreePrinter {
+   public:
+    void Call(const Address& key, const CodeEntryInfo& value);
+  };
+
   CodeTree tree_;

   DISALLOW_COPY_AND_ASSIGN(CodeMap);
@@ -178,14 +193,24 @@
   CpuProfilesCollection();
   ~CpuProfilesCollection();

-  void AddProfile(unsigned uid);
+  bool StartProfiling(const char* title, unsigned uid);
+  bool StartProfiling(String* title, unsigned uid);
+  CpuProfile* StopProfiling(const char* title);
+  CpuProfile* StopProfiling(String* title);
+  INLINE(List<CpuProfile*>* profiles()) { return &profiles_; }
+  CpuProfile* GetProfile(unsigned uid);
+  inline bool is_last_profile();

   CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
String* name, String* resource_name, int line_number);
   CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name);
   CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count);

-  INLINE(CpuProfile* profile()) { return profiles_.last(); }
+  // Called from profile generator thread.
+  void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path);
+
+  // This will be moved to V8 API.
+  static const int kNoLineNumberInfo = -1;

  private:
   const char* GetName(String* name);
@@ -195,6 +220,10 @@
     return strcmp(reinterpret_cast<char*>(key1),
                   reinterpret_cast<char*>(key2)) == 0;
   }
+
+  INLINE(static bool CpuProfilesMatch(void* key1, void* key2)) {
+    return key1 == key2;
+  }

   // String::Hash -> const char*
   HashMap function_and_resource_names_;
@@ -202,6 +231,12 @@
   List<char*> args_count_names_;
   List<CodeEntry*> code_entries_;
   List<CpuProfile*> profiles_;
+  // uid -> CpuProfile*
+  HashMap profiles_uids_;
+
+  // Accessed by VM thread and profile generator thread.
+  List<CpuProfile*> current_profiles_;
+  Semaphore* current_profiles_semaphore_;

   DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection);
 };
@@ -233,15 +268,14 @@
   INLINE(CodeMap* code_map()) { return &code_map_; }

  private:
-  INLINE(CpuProfile* profile()) { return profiles_->profile(); }
-
   CpuProfilesCollection* profiles_;
   CodeMap code_map_;

   DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
 };

-
 } }  // namespace v8::internal

+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
+
 #endif  // V8_PROFILE_GENERATOR_H_
=======================================
--- /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Mon Mar 22 07:23:45 2010 +++ /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Tue Mar 30 04:38:39 2010
@@ -2,6 +2,8 @@
 //
 // Tests of profiles generator and utilities.

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "v8.h"
 #include "cpu-profiler-inl.h"
 #include "cctest.h"
@@ -9,6 +11,7 @@
 namespace i = v8::internal;

 using i::CodeEntry;
+using i::CpuProfile;
 using i::CpuProfilesCollection;
 using i::ProfileGenerator;
 using i::ProfileNode;
@@ -60,7 +63,7 @@
 TEST(CodeEvents) {
   InitializeVM();
   CpuProfilesCollection profiles;
-  profiles.AddProfile(0);
+  profiles.StartProfiling("", 1);
   ProfileGenerator generator(&profiles);
   ProfilerEventsProcessor processor(&generator);
   processor.Start();
@@ -126,7 +129,7 @@

 TEST(TickEvents) {
   CpuProfilesCollection profiles;
-  profiles.AddProfile(0);
+  profiles.StartProfiling("", 1);
   ProfileGenerator generator(&profiles);
   ProfilerEventsProcessor processor(&generator);
   processor.Start();
@@ -152,45 +155,50 @@

   processor.Stop();
   processor.Join();
+  CpuProfile* profile = profiles.StopProfiling("");
+  CHECK_NE(NULL, profile);

   // 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());
+  const i::List<ProfileNode*>* top_down_root_children =
+      profile->top_down()->root()->children();
+  CHECK_EQ(1, top_down_root_children->length());
+  CHECK_EQ("bbb", top_down_root_children->last()->entry()->name());
+  const i::List<ProfileNode*>* top_down_bbb_children =
+      top_down_root_children->last()->children();
+  CHECK_EQ(1, top_down_bbb_children->length());
+ CHECK_EQ("args_count: 5", top_down_bbb_children->last()->entry()->name());
+  const i::List<ProfileNode*>* top_down_stub_children =
+      top_down_bbb_children->last()->children();
+  CHECK_EQ(1, top_down_stub_children->length());
+  CHECK_EQ("ddd", top_down_stub_children->last()->entry()->name());
+  const i::List<ProfileNode*>* top_down_ddd_children =
+      top_down_stub_children->last()->children();
+  CHECK_EQ(0, top_down_ddd_children->length());
+
+  const i::List<ProfileNode*>* bottom_up_root_children_unsorted =
+      profile->bottom_up()->root()->children();
+  CHECK_EQ(3, bottom_up_root_children_unsorted->length());
+  i::List<ProfileNode*> bottom_up_root_children(3);
+  bottom_up_root_children.AddAll(*bottom_up_root_children_unsorted);
   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());
-}
+  const i::List<ProfileNode*>* bottom_up_stub_children =
+      bottom_up_root_children[0]->children();
+  CHECK_EQ(1, bottom_up_stub_children->length());
+  CHECK_EQ("bbb", bottom_up_stub_children->last()->entry()->name());
+  const i::List<ProfileNode*>* bottom_up_bbb_children =
+      bottom_up_root_children[1]->children();
+  CHECK_EQ(0, bottom_up_bbb_children->length());
+  const i::List<ProfileNode*>* bottom_up_ddd_children =
+      bottom_up_root_children[2]->children();
+  CHECK_EQ(1, bottom_up_ddd_children->length());
+ CHECK_EQ("args_count: 5", bottom_up_ddd_children->last()->entry()->name());
+  const i::List<ProfileNode*>* bottom_up_ddd_stub_children =
+      bottom_up_ddd_children->last()->children();
+  CHECK_EQ(1, bottom_up_ddd_stub_children->length());
+  CHECK_EQ("bbb", bottom_up_ddd_stub_children->last()->entry()->name());
+}
+
+#endif  // ENABLE_CPP_PROFILES_PROCESSOR
=======================================
--- /branches/bleeding_edge/test/cctest/test-profile-generator.cc Fri Mar 19 06:51:01 2010 +++ /branches/bleeding_edge/test/cctest/test-profile-generator.cc Tue Mar 30 04:38:39 2010
@@ -2,6 +2,8 @@
 //
 // Tests of profiles generator and utilities.

+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
 #include "v8.h"
 #include "profile-generator-inl.h"
 #include "cctest.h"
@@ -10,6 +12,7 @@

 using i::CodeEntry;
 using i::CodeMap;
+using i::CpuProfile;
 using i::CpuProfilesCollection;
 using i::ProfileNode;
 using i::ProfileTree;
@@ -45,7 +48,7 @@

 class ProfileTreeTestHelper {
  public:
-  explicit ProfileTreeTestHelper(ProfileTree* tree)
+  explicit ProfileTreeTestHelper(const ProfileTree* tree)
       : tree_(tree) { }

   ProfileNode* Walk(CodeEntry* entry1,
@@ -65,7 +68,7 @@
   }

  private:
-  ProfileTree* tree_;
+  const ProfileTree* tree_;
 };

 }  // namespace
@@ -366,7 +369,7 @@

 TEST(RecordTickSample) {
   CpuProfilesCollection profiles;
-  profiles.AddProfile(0);
+  profiles.StartProfiling("", 1);
   ProfileGenerator generator(&profiles);
CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
@@ -375,11 +378,6 @@
   generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
   generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);

- ProfileTreeTestHelper top_down_test_helper(profiles.profile()->top_down());
-  CHECK_EQ(NULL, top_down_test_helper.Walk(entry1));
-  CHECK_EQ(NULL, top_down_test_helper.Walk(entry2));
-  CHECK_EQ(NULL, top_down_test_helper.Walk(entry3));
-
   // We are building the following calls tree:
   //      -> aaa         - sample1
   //  aaa -> bbb -> ccc  - sample2
@@ -406,6 +404,11 @@
   sample3.frames_count = 2;
   generator.RecordTickSample(sample3);

+  CpuProfile* profile = profiles.StopProfiling("");
+  CHECK_NE(NULL, profile);
+  ProfileTreeTestHelper top_down_test_helper(profile->top_down());
+  CHECK_EQ(NULL, top_down_test_helper.Walk(entry2));
+  CHECK_EQ(NULL, top_down_test_helper.Walk(entry3));
   ProfileNode* node1 = top_down_test_helper.Walk(entry1);
   CHECK_NE(NULL, node1);
   CHECK_EQ(entry1, node1->entry());
@@ -419,3 +422,5 @@
   CHECK_NE(NULL, node4);
   CHECK_EQ(entry1, node4->entry());
 }
+
+#endif  // ENABLE_CPP_PROFILES_PROCESSOR

--
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