From: yurys@chromium.org Date: Tue, 11 Jun 2013 15:00:41 +0000 (+0000) Subject: Test that functions created using v8::FunctionTemplate::New correctly displayed in... X-Git-Tag: upstream/4.7.83~13905 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eb037a86fd665d56adbda3a839ba778e88bd6b9d;p=platform%2Fupstream%2Fv8.git Test that functions created using v8::FunctionTemplate::New correctly displayed in CPU profiles BUG=244580 R=jkummerow@chromium.org, loislo@chromium.org Review URL: https://codereview.chromium.org/16771002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15066 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc index a121799..a615fe9 100644 --- a/test/cctest/test-cpu-profiler.cc +++ b/test/cctest/test-cpu-profiler.cc @@ -648,15 +648,15 @@ static const char* native_accessor_test_source = "function start(count) {\n" "}\n"; -class FooAccessorsData { +class TestApiCallbacks { public: - explicit FooAccessorsData(int min_duration_ms) + explicit TestApiCallbacks(int min_duration_ms) : min_duration_ms_(min_duration_ms), is_warming_up_(false) {} static v8::Handle Getter(v8::Local name, const v8::AccessorInfo& info) { - FooAccessorsData* data = fromInfo(info); + TestApiCallbacks* data = fromInfo(info); data->Wait(); return v8::Int32::New(2013); } @@ -664,7 +664,12 @@ class FooAccessorsData { static void Setter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) { - FooAccessorsData* data = fromInfo(info); + TestApiCallbacks* data = fromInfo(info); + data->Wait(); + } + + static void Callback(const v8::FunctionCallbackInfo& info) { + TestApiCallbacks* data = fromInfo(info); data->Wait(); } @@ -681,9 +686,15 @@ class FooAccessorsData { } } - static FooAccessorsData* fromInfo(const v8::AccessorInfo& info) { + static TestApiCallbacks* fromInfo(const v8::AccessorInfo& info) { + void* data = v8::External::Cast(*info.Data())->Value(); + return reinterpret_cast(data); + } + + static TestApiCallbacks* fromInfo( + const v8::FunctionCallbackInfo& info) { void* data = v8::External::Cast(*info.Data())->Value(); - return reinterpret_cast(data); + return reinterpret_cast(data); } int min_duration_ms_; @@ -704,11 +715,11 @@ TEST(NativeAccessorUninitializedIC) { v8::Local instance_template = func_template->InstanceTemplate(); - FooAccessorsData accessors(100); + TestApiCallbacks accessors(100); v8::Local data = v8::External::New(&accessors); instance_template->SetAccessor( - v8::String::New("foo"), &FooAccessorsData::Getter, - &FooAccessorsData::Setter, data); + v8::String::New("foo"), &TestApiCallbacks::Getter, + &TestApiCallbacks::Setter, data); v8::Local func = func_template->GetFunction(); v8::Local instance = func->NewInstance(); env->Global()->Set(v8::String::New("instance"), instance); @@ -752,11 +763,11 @@ TEST(NativeAccessorMonomorphicIC) { v8::Local instance_template = func_template->InstanceTemplate(); - FooAccessorsData accessors(1); + TestApiCallbacks accessors(1); v8::Local data = v8::External::New(&accessors); instance_template->SetAccessor( - v8::String::New("foo"), &FooAccessorsData::Getter, - &FooAccessorsData::Setter, data); + v8::String::New("foo"), &TestApiCallbacks::Getter, + &TestApiCallbacks::Setter, data); v8::Local func = func_template->GetFunction(); v8::Local instance = func->NewInstance(); env->Global()->Set(v8::String::New("instance"), instance); @@ -798,3 +809,111 @@ TEST(NativeAccessorMonomorphicIC) { cpu_profiler->DeleteAllCpuProfiles(); } + + +static const char* native_method_test_source = "function start(count) {\n" +" for (var i = 0; i < count; i++) {\n" +" instance.fooMethod();\n" +" }\n" +"}\n"; + + +TEST(NativeMethodUninitializedIC) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + + TestApiCallbacks callbacks(100); + v8::Local data = v8::External::New(&callbacks); + + v8::Local func_template = v8::FunctionTemplate::New(); + func_template->SetClassName(v8::String::New("Test_InstanceCostructor")); + v8::Local proto_template = + func_template->PrototypeTemplate(); + v8::Local signature = v8::Signature::New(func_template); + proto_template->Set(v8::String::New("fooMethod"), v8::FunctionTemplate::New( + &TestApiCallbacks::Callback, data, signature, 0)); + + v8::Local func = func_template->GetFunction(); + v8::Local instance = func->NewInstance(); + env->Global()->Set(v8::String::New("instance"), instance); + + v8::Script::Compile(v8::String::New(native_method_test_source))->Run(); + v8::Local function = v8::Local::Cast( + env->Global()->Get(v8::String::New("start"))); + + v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); + v8::Local profile_name = v8::String::New("my_profile"); + + cpu_profiler->StartCpuProfiling(profile_name); + int32_t repeat_count = 1; + v8::Handle args[] = { v8::Integer::New(repeat_count) }; + function->Call(env->Global(), ARRAY_SIZE(args), args); + const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name); + + CHECK_NE(NULL, profile); + // Dump collected profile to have a better diagnostic in case of failure. + reinterpret_cast( + const_cast(profile))->Print(); + + const v8::CpuProfileNode* root = profile->GetTopDownRoot(); + const v8::CpuProfileNode* startNode = GetChild(root, "start"); + GetChild(startNode, "fooMethod"); + + cpu_profiler->DeleteAllCpuProfiles(); +} + + +TEST(NativeMethodMonomorphicIC) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + + TestApiCallbacks callbacks(1); + v8::Local data = v8::External::New(&callbacks); + + v8::Local func_template = v8::FunctionTemplate::New(); + func_template->SetClassName(v8::String::New("Test_InstanceCostructor")); + v8::Local proto_template = + func_template->PrototypeTemplate(); + v8::Local signature = v8::Signature::New(func_template); + proto_template->Set(v8::String::New("fooMethod"), v8::FunctionTemplate::New( + &TestApiCallbacks::Callback, data, signature, 0)); + + v8::Local func = func_template->GetFunction(); + v8::Local instance = func->NewInstance(); + env->Global()->Set(v8::String::New("instance"), instance); + + v8::Script::Compile(v8::String::New(native_method_test_source))->Run(); + v8::Local function = v8::Local::Cast( + env->Global()->Get(v8::String::New("start"))); + { + // Make sure method ICs are in monomorphic state before starting + // profiling. + callbacks.set_warming_up(true); + int32_t warm_up_iterations = 3; + v8::Handle args[] = { v8::Integer::New(warm_up_iterations) }; + function->Call(env->Global(), ARRAY_SIZE(args), args); + callbacks.set_warming_up(false); + } + + v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); + v8::Local profile_name = v8::String::New("my_profile"); + + cpu_profiler->StartCpuProfiling(profile_name); + int32_t repeat_count = 100; + v8::Handle args[] = { v8::Integer::New(repeat_count) }; + function->Call(env->Global(), ARRAY_SIZE(args), args); + const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name); + + CHECK_NE(NULL, profile); + // Dump collected profile to have a better diagnostic in case of failure. + reinterpret_cast( + const_cast(profile))->Print(); + + const v8::CpuProfileNode* root = profile->GetTopDownRoot(); + GetChild(root, "start"); + // TODO(yurys): in CallIC should be changed to report external callback + // invocation. + // GetChild(startNode, "fooMethod"); + + cpu_profiler->DeleteAllCpuProfiles(); +}