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.