Commit 120b753f authored by alph's avatar alph Committed by Commit bot

Introduce v8::CpuProfiler::New and v8::CpuProfiler::Dispose API.

Isolate is not going to retain a CPU profiler.
The client will be creating an instance of profiler when needed.

Deprectate v8::Isolate::GetCpuProfiler()

BUG=v8:4789

Review-Url: https://codereview.chromium.org/2117343006
Cr-Commit-Position: refs/heads/master@{#37613}
parent 29b89b48
...@@ -207,13 +207,24 @@ class V8_EXPORT CpuProfile { ...@@ -207,13 +207,24 @@ class V8_EXPORT CpuProfile {
void Delete(); void Delete();
}; };
/** /**
* Interface for controlling CPU profiling. Instance of the * Interface for controlling CPU profiling. Instance of the
* profiler can be retrieved using v8::Isolate::GetCpuProfiler. * profiler can be created using v8::CpuProfiler::New method.
*/ */
class V8_EXPORT CpuProfiler { class V8_EXPORT CpuProfiler {
public: public:
/**
* Creates a new CPU profiler for the |isolate|. The isolate must be
* initialized. The profiler object must be disposed after use by calling
* |Dispose| method.
*/
static CpuProfiler* New(Isolate* isolate);
/**
* Disposes the CPU profiler object.
*/
void Dispose();
/** /**
* Changes default CPU profiler sampling interval to the specified number * Changes default CPU profiler sampling interval to the specified number
* of microseconds. Default interval is 1000us. This method must be called * of microseconds. Default interval is 1000us. This method must be called
......
...@@ -5932,7 +5932,8 @@ class V8_EXPORT Isolate { ...@@ -5932,7 +5932,8 @@ class V8_EXPORT Isolate {
* is initialized. It is the embedder's responsibility to stop all CPU * is initialized. It is the embedder's responsibility to stop all CPU
* profiling activities if it has started any. * profiling activities if it has started any.
*/ */
CpuProfiler* GetCpuProfiler(); V8_DEPRECATE_SOON("CpuProfiler should be created with CpuProfiler::New call.",
CpuProfiler* GetCpuProfiler());
/** Returns true if this isolate has a current context. */ /** Returns true if this isolate has a current context. */
bool InContext(); bool InContext();
......
...@@ -8496,6 +8496,12 @@ int CpuProfile::GetSamplesCount() const { ...@@ -8496,6 +8496,12 @@ int CpuProfile::GetSamplesCount() const {
return reinterpret_cast<const i::CpuProfile*>(this)->samples_count(); return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
} }
CpuProfiler* CpuProfiler::New(Isolate* isolate) {
return reinterpret_cast<CpuProfiler*>(
new i::CpuProfiler(reinterpret_cast<i::Isolate*>(isolate)));
}
void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
void CpuProfiler::SetSamplingInterval(int us) { void CpuProfiler::SetSamplingInterval(int us) {
DCHECK_GE(us, 0); DCHECK_GE(us, 0);
......
...@@ -921,7 +921,6 @@ class Isolate { ...@@ -921,7 +921,6 @@ class Isolate {
CodeEventDispatcher* code_event_dispatcher() const { CodeEventDispatcher* code_event_dispatcher() const {
return code_event_dispatcher_.get(); return code_event_dispatcher_.get();
} }
CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
HeapProfiler* heap_profiler() const { return heap_profiler_; } HeapProfiler* heap_profiler() const { return heap_profiler_; }
#ifdef DEBUG #ifdef DEBUG
...@@ -1264,6 +1263,10 @@ class Isolate { ...@@ -1264,6 +1263,10 @@ class Isolate {
return ""; return "";
} }
// TODO(alph): Remove along with the deprecated GetCpuProfiler().
friend v8::CpuProfiler* v8::Isolate::GetCpuProfiler();
CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
base::Atomic32 id_; base::Atomic32 id_;
EntryStackItem* entry_stack_; EntryStackItem* entry_stack_;
int stack_trace_nesting_level_; int stack_trace_nesting_level_;
......
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
v8::CpuProfile* ProfilerExtension::last_profile = NULL; v8::CpuProfiler* ProfilerExtension::profiler_ = nullptr;
v8::CpuProfile* ProfilerExtension::last_profile = nullptr;
const char* ProfilerExtension::kSource = const char* ProfilerExtension::kSource =
"native function startProfiling();" "native function startProfiling();"
"native function stopProfiling();" "native function stopProfiling();"
...@@ -58,24 +59,22 @@ v8::Local<v8::FunctionTemplate> ProfilerExtension::GetNativeFunctionTemplate( ...@@ -58,24 +59,22 @@ v8::Local<v8::FunctionTemplate> ProfilerExtension::GetNativeFunctionTemplate(
void ProfilerExtension::StartProfiling( void ProfilerExtension::StartProfiling(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
last_profile = NULL; last_profile = nullptr;
v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler(); profiler_->StartProfiling(args.Length() > 0
cpu_profiler->StartProfiling((args.Length() > 0) ? args[0].As<v8::String>()
? args[0].As<v8::String>() : v8::String::Empty(args.GetIsolate()));
: v8::String::Empty(args.GetIsolate()));
} }
void ProfilerExtension::StopProfiling( void ProfilerExtension::StopProfiling(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler(); last_profile = profiler_->StopProfiling(
last_profile = cpu_profiler->StopProfiling((args.Length() > 0) args.Length() > 0 ? args[0].As<v8::String>()
? args[0].As<v8::String>() : v8::String::Empty(args.GetIsolate()));
: v8::String::Empty(args.GetIsolate()));
} }
void ProfilerExtension::CollectSample( void ProfilerExtension::CollectSample(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetIsolate()->GetCpuProfiler()->CollectSample(); profiler_->CollectSample();
} }
} // namespace internal } // namespace internal
......
...@@ -35,11 +35,20 @@ ...@@ -35,11 +35,20 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class CpuProfiler;
class ProfilerExtension : public v8::Extension { class ProfilerExtension : public v8::Extension {
public: public:
ProfilerExtension() : v8::Extension("v8/profiler", kSource) { } ProfilerExtension() : v8::Extension("v8/profiler", kSource) { }
virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate, v8::Local<v8::String> name); v8::Isolate* isolate, v8::Local<v8::String> name);
static void set_profiler(v8::CpuProfiler* profiler) { profiler_ = profiler; }
static void set_profiler(CpuProfiler* profiler) {
profiler_ = reinterpret_cast<v8::CpuProfiler*>(profiler);
}
static v8::CpuProfiler* profiler() { return profiler_; }
static v8::CpuProfile* last_profile; static v8::CpuProfile* last_profile;
private: private:
...@@ -47,6 +56,7 @@ class ProfilerExtension : public v8::Extension { ...@@ -47,6 +56,7 @@ class ProfilerExtension : public v8::Extension {
static void StopProfiling(const v8::FunctionCallbackInfo<v8::Value>& args); static void StopProfiling(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CollectSample(const v8::FunctionCallbackInfo<v8::Value>& args); static void CollectSample(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::CpuProfiler* profiler_;
static const char* kSource; static const char* kSource;
}; };
......
...@@ -96,11 +96,11 @@ void RunWithProfiler(void (*test)()) { ...@@ -96,11 +96,11 @@ void RunWithProfiler(void (*test)()) {
LocalContext env; LocalContext env;
v8::HandleScope scope(env->GetIsolate()); v8::HandleScope scope(env->GetIsolate());
v8::Local<v8::String> profile_name = v8_str("my_profile1"); v8::Local<v8::String> profile_name = v8_str("my_profile1");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); v8::CpuProfiler* cpu_profiler = v8::CpuProfiler::New(env->GetIsolate());
cpu_profiler->StartProfiling(profile_name); cpu_profiler->StartProfiling(profile_name);
(*test)(); (*test)();
reinterpret_cast<i::CpuProfiler*>(cpu_profiler)->DeleteAllProfiles(); reinterpret_cast<i::CpuProfiler*>(cpu_profiler)->DeleteAllProfiles();
cpu_profiler->Dispose();
} }
......
This diff is collapsed.
...@@ -345,7 +345,8 @@ class TestSetup { ...@@ -345,7 +345,8 @@ class TestSetup {
TEST(RecordTickSample) { TEST(RecordTickSample) {
TestSetup test_setup; TestSetup test_setup;
CpuProfilesCollection profiles(CcTest::i_isolate()); CpuProfilesCollection profiles(CcTest::i_isolate());
profiles.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler()); CpuProfiler profiler(CcTest::i_isolate());
profiles.set_cpu_profiler(&profiler);
profiles.StartProfiling("", false); profiles.StartProfiling("", false);
ProfileGenerator generator(&profiles); ProfileGenerator generator(&profiles);
CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa");
...@@ -416,7 +417,8 @@ static void CheckNodeIds(ProfileNode* node, unsigned* expectedId) { ...@@ -416,7 +417,8 @@ static void CheckNodeIds(ProfileNode* node, unsigned* expectedId) {
TEST(SampleIds) { TEST(SampleIds) {
TestSetup test_setup; TestSetup test_setup;
CpuProfilesCollection profiles(CcTest::i_isolate()); CpuProfilesCollection profiles(CcTest::i_isolate());
profiles.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler()); CpuProfiler profiler(CcTest::i_isolate());
profiles.set_cpu_profiler(&profiler);
profiles.StartProfiling("", true); profiles.StartProfiling("", true);
ProfileGenerator generator(&profiles); ProfileGenerator generator(&profiles);
CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa");
...@@ -472,7 +474,8 @@ TEST(SampleIds) { ...@@ -472,7 +474,8 @@ TEST(SampleIds) {
TEST(NoSamples) { TEST(NoSamples) {
TestSetup test_setup; TestSetup test_setup;
CpuProfilesCollection profiles(CcTest::i_isolate()); CpuProfilesCollection profiles(CcTest::i_isolate());
profiles.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler()); CpuProfiler profiler(CcTest::i_isolate());
profiles.set_cpu_profiler(&profiler);
profiles.StartProfiling("", false); profiles.StartProfiling("", false);
ProfileGenerator generator(&profiles); ProfileGenerator generator(&profiles);
CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa");
...@@ -516,17 +519,18 @@ TEST(RecordStackTraceAtStartProfiling) { ...@@ -516,17 +519,18 @@ TEST(RecordStackTraceAtStartProfiling) {
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
v8::Context::Scope context_scope(env); v8::Context::Scope context_scope(env);
std::unique_ptr<i::CpuProfiler> iprofiler(
new i::CpuProfiler(CcTest::i_isolate()));
i::ProfilerExtension::set_profiler(iprofiler.get());
CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler();
CHECK_EQ(0, profiler->GetProfilesCount());
CompileRun( CompileRun(
"function c() { startProfiling(); }\n" "function c() { startProfiling(); }\n"
"function b() { c(); }\n" "function b() { c(); }\n"
"function a() { b(); }\n" "function a() { b(); }\n"
"a();\n" "a();\n"
"stopProfiling();"); "stopProfiling();");
CHECK_EQ(1, profiler->GetProfilesCount()); CHECK_EQ(1, iprofiler->GetProfilesCount());
CpuProfile* profile = profiler->GetProfile(0); CpuProfile* profile = iprofiler->GetProfile(0);
const ProfileTree* topDown = profile->top_down(); const ProfileTree* topDown = profile->top_down();
const ProfileNode* current = topDown->root(); const ProfileNode* current = topDown->root();
const_cast<ProfileNode*>(current)->Print(0); const_cast<ProfileNode*>(current)->Print(0);
...@@ -558,7 +562,8 @@ TEST(RecordStackTraceAtStartProfiling) { ...@@ -558,7 +562,8 @@ TEST(RecordStackTraceAtStartProfiling) {
TEST(Issue51919) { TEST(Issue51919) {
CpuProfilesCollection collection(CcTest::i_isolate()); CpuProfilesCollection collection(CcTest::i_isolate());
collection.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler()); CpuProfiler profiler(CcTest::i_isolate());
collection.set_cpu_profiler(&profiler);
i::EmbeddedVector<char*, i::EmbeddedVector<char*,
CpuProfilesCollection::kMaxSimultaneousProfiles> titles; CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) { for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
...@@ -593,10 +598,9 @@ TEST(ProfileNodeScriptId) { ...@@ -593,10 +598,9 @@ TEST(ProfileNodeScriptId) {
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
v8::Context::Scope context_scope(env); v8::Context::Scope context_scope(env);
std::unique_ptr<CpuProfiler> iprofiler(new CpuProfiler(CcTest::i_isolate()));
i::ProfilerExtension::set_profiler(iprofiler.get());
v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Local<v8::Script> script_a = v8::Local<v8::Script> script_a =
v8_compile(v8_str("function a() { startProfiling(); }\n")); v8_compile(v8_str("function a() { startProfiling(); }\n"));
script_a->Run(v8::Isolate::GetCurrent()->GetCurrentContext()) script_a->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
...@@ -646,16 +650,12 @@ static const char* line_number_test_source_profile_time_functions = ...@@ -646,16 +650,12 @@ static const char* line_number_test_source_profile_time_functions =
"bar_at_the_second_line();\n" "bar_at_the_second_line();\n"
"function lazy_func_at_6th_line() {}"; "function lazy_func_at_6th_line() {}";
int GetFunctionLineNumber(LocalContext* env, const char* name) { int GetFunctionLineNumber(CpuProfiler& profiler, LocalContext& env,
CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); const char* name) {
CodeMap* code_map = profiler->generator()->code_map(); CodeMap* code_map = profiler.generator()->code_map();
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
(*(*env)) env->Global()->Get(env.local(), v8_str(name)).ToLocalChecked())));
->Global()
->Get(v8::Isolate::GetCurrent()->GetCurrentContext(),
v8_str(name))
.ToLocalChecked())));
CodeEntry* func_entry = code_map->FindEntry(func->abstract_code()->address()); CodeEntry* func_entry = code_map->FindEntry(func->abstract_code()->address());
if (!func_entry) if (!func_entry)
FATAL(name); FATAL(name);
...@@ -674,31 +674,31 @@ TEST(LineNumber) { ...@@ -674,31 +674,31 @@ TEST(LineNumber) {
CompileRun(line_number_test_source_existing_functions); CompileRun(line_number_test_source_existing_functions);
CpuProfiler* profiler = isolate->cpu_profiler(); CpuProfiler profiler(isolate);
profiler->StartProfiling("LineNumber"); profiler.StartProfiling("LineNumber");
CompileRun(line_number_test_source_profile_time_functions); CompileRun(line_number_test_source_profile_time_functions);
profiler->processor()->StopSynchronously(); profiler.processor()->StopSynchronously();
bool is_lazy = i::FLAG_lazy && !(i::FLAG_ignition && i::FLAG_ignition_eager); bool is_lazy = i::FLAG_lazy && !(i::FLAG_ignition && i::FLAG_ignition_eager);
CHECK_EQ(1, GetFunctionLineNumber(&env, "foo_at_the_first_line")); CHECK_EQ(1, GetFunctionLineNumber(profiler, env, "foo_at_the_first_line"));
CHECK_EQ(is_lazy ? 0 : 4, CHECK_EQ(is_lazy ? 0 : 4,
GetFunctionLineNumber(&env, "lazy_func_at_forth_line")); GetFunctionLineNumber(profiler, env, "lazy_func_at_forth_line"));
CHECK_EQ(2, GetFunctionLineNumber(&env, "bar_at_the_second_line")); CHECK_EQ(2, GetFunctionLineNumber(profiler, env, "bar_at_the_second_line"));
CHECK_EQ(is_lazy ? 0 : 6, CHECK_EQ(is_lazy ? 0 : 6,
GetFunctionLineNumber(&env, "lazy_func_at_6th_line")); GetFunctionLineNumber(profiler, env, "lazy_func_at_6th_line"));
profiler->StopProfiling("LineNumber"); profiler.StopProfiling("LineNumber");
} }
TEST(BailoutReason) { TEST(BailoutReason) {
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
v8::Context::Scope context_scope(env); v8::Context::Scope context_scope(env);
std::unique_ptr<CpuProfiler> iprofiler(new CpuProfiler(CcTest::i_isolate()));
i::ProfilerExtension::set_profiler(iprofiler.get());
v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
CHECK_EQ(0, iprofiler->GetProfilesCount()); CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Local<v8::Script> script = v8::Local<v8::Script> script =
v8_compile(v8_str("function Debugger() {\n" v8_compile(v8_str("function Debugger() {\n"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment