Index: test/cctest/test-profile-generator.cc |
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc |
index b438d252e0a8dd45f12153c1f930e73f2d803b16..418fd36588e8cda5d68f3362e23dc2884c963f73 100644 |
--- a/test/cctest/test-profile-generator.cc |
+++ b/test/cctest/test-profile-generator.cc |
@@ -7,12 +7,14 @@ |
#include "v8.h" |
#include "profile-generator-inl.h" |
#include "cctest.h" |
+#include "../include/v8-profiler.h" |
namespace i = v8::internal; |
using i::CodeEntry; |
using i::CodeMap; |
using i::CpuProfile; |
+using i::CpuProfiler; |
using i::CpuProfilesCollection; |
using i::ProfileNode; |
using i::ProfileTree; |
@@ -668,4 +670,109 @@ TEST(SampleRateCalculator) { |
CHECK_EQ(kSamplingIntervalMs * 0.66666, calc3.ticks_per_ms()); |
} |
+ |
+// --- P r o f i l e r E x t e n s i o n --- |
+ |
+class ProfilerExtension : public v8::Extension { |
+ public: |
+ ProfilerExtension() : v8::Extension("v8/profiler", kSource) { } |
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( |
+ v8::Handle<v8::String> name); |
+ static v8::Handle<v8::Value> StartProfiling(const v8::Arguments& args); |
+ static v8::Handle<v8::Value> StopProfiling(const v8::Arguments& args); |
+ private: |
+ static const char* kSource; |
+}; |
+ |
+ |
+const char* ProfilerExtension::kSource = |
+ "native function startProfiling();" |
+ "native function stopProfiling();"; |
+ |
+v8::Handle<v8::FunctionTemplate> ProfilerExtension::GetNativeFunction( |
+ v8::Handle<v8::String> name) { |
+ if (name->Equals(v8::String::New("startProfiling"))) { |
+ return v8::FunctionTemplate::New(ProfilerExtension::StartProfiling); |
+ } else if (name->Equals(v8::String::New("stopProfiling"))) { |
+ return v8::FunctionTemplate::New(ProfilerExtension::StopProfiling); |
+ } else { |
+ CHECK(false); |
+ return v8::Handle<v8::FunctionTemplate>(); |
+ } |
+} |
+ |
+ |
+v8::Handle<v8::Value> ProfilerExtension::StartProfiling( |
+ const v8::Arguments& args) { |
+ if (args.Length() > 0) |
+ v8::CpuProfiler::StartProfiling(args[0].As<v8::String>()); |
+ else |
+ v8::CpuProfiler::StartProfiling(v8::String::New("")); |
+ return v8::Undefined(); |
+} |
+ |
+ |
+v8::Handle<v8::Value> ProfilerExtension::StopProfiling( |
+ const v8::Arguments& args) { |
+ if (args.Length() > 0) |
+ v8::CpuProfiler::StopProfiling(args[0].As<v8::String>()); |
+ else |
+ v8::CpuProfiler::StopProfiling(v8::String::New("")); |
+ return v8::Undefined(); |
+} |
+ |
+ |
+static ProfilerExtension kProfilerExtension; |
+v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension); |
+static v8::Persistent<v8::Context> env; |
+ |
+static const ProfileNode* PickChild(const ProfileNode* parent, |
+ const char* name) { |
+ for (int i = 0; i < parent->children()->length(); ++i) { |
+ const ProfileNode* child = parent->children()->at(i); |
+ if (strcmp(child->entry()->name(), name) == 0) return child; |
+ } |
+ return NULL; |
+} |
+ |
+ |
+TEST(RecordStackTraceAtStartProfiling) { |
+ if (env.IsEmpty()) { |
+ v8::HandleScope scope; |
+ const char* extensions[] = { "v8/profiler" }; |
+ v8::ExtensionConfiguration config(1, extensions); |
+ env = v8::Context::New(&config); |
+ } |
+ v8::HandleScope scope; |
+ env->Enter(); |
+ |
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount()); |
+ CompileRun( |
+ "function c() { startProfiling(); }\n" |
+ "function b() { c(); }\n" |
+ "function a() { b(); }\n" |
+ "a();\n" |
+ "stopProfiling();"); |
+ CHECK_EQ(1, CpuProfiler::GetProfilesCount()); |
+ CpuProfile* profile = |
+ CpuProfiler::GetProfile(NULL, 0); |
+ const ProfileTree* topDown = profile->top_down(); |
+ const ProfileNode* current = topDown->root(); |
+ // The tree should look like this: |
+ // (root) |
+ // (anonymous function) |
+ // a |
+ // b |
+ // c |
+ current = PickChild(current, "(anonymous function)"); |
+ CHECK_NE(NULL, const_cast<ProfileNode*>(current)); |
+ current = PickChild(current, "a"); |
+ CHECK_NE(NULL, const_cast<ProfileNode*>(current)); |
+ current = PickChild(current, "b"); |
+ CHECK_NE(NULL, const_cast<ProfileNode*>(current)); |
+ current = PickChild(current, "c"); |
+ CHECK_NE(NULL, const_cast<ProfileNode*>(current)); |
+ CHECK_EQ(0, current->children()->length()); |
+} |
+ |
#endif // ENABLE_LOGGING_AND_PROFILING |