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.