OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/memory_benchmarking_extension.h" | 5 #include "content/renderer/memory_benchmarking_extension.h" |
6 | 6 |
7 #include "base/format_macros.h" | |
8 #include "base/strings/stringprintf.h" | |
9 #include "base/thread_task_runner_handle.h" | |
10 #include "base/trace_event/memory_dump_manager.h" | |
11 #include "base/trace_event/memory_dump_request_args.h" | |
7 #include "content/common/memory_benchmark_messages.h" | 12 #include "content/common/memory_benchmark_messages.h" |
8 #include "content/renderer/chrome_object_extensions_utils.h" | 13 #include "content/renderer/chrome_object_extensions_utils.h" |
9 #include "content/renderer/render_thread_impl.h" | 14 #include "content/renderer/render_thread_impl.h" |
10 #include "gin/arguments.h" | 15 #include "gin/arguments.h" |
11 #include "gin/handle.h" | 16 #include "gin/handle.h" |
12 #include "gin/object_template_builder.h" | 17 #include "gin/object_template_builder.h" |
13 #include "third_party/WebKit/public/web/WebFrame.h" | 18 #include "third_party/WebKit/public/web/WebFrame.h" |
14 #include "third_party/WebKit/public/web/WebKit.h" | 19 #include "third_party/WebKit/public/web/WebKit.h" |
20 #include "third_party/WebKit/public/web/WebLocalFrame.h" | |
15 | 21 |
16 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) | 22 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) |
17 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" | 23 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" |
18 #endif | 24 #endif |
19 | 25 |
20 namespace content { | 26 namespace content { |
21 | 27 |
28 namespace { | |
29 | |
30 class CallbackWithContext { | |
31 public: | |
32 CallbackWithContext(v8::Isolate* isolate, v8::Local<v8::Function> callback) | |
33 : task_runner_(base::ThreadTaskRunnerHandle::Get()), isolate_(isolate) { | |
34 callback_.Reset(isolate, callback); | |
35 context_.Reset(isolate, isolate->GetCurrentContext()); | |
36 } | |
37 | |
38 virtual ~CallbackWithContext() { | |
39 callback_.Reset(); | |
40 context_.Reset(); | |
41 } | |
42 | |
43 base::SingleThreadTaskRunner* task_runner() { return task_runner_.get(); } | |
Primiano Tucci (use gerrit)
2015/07/24 14:29:14
nit +const between ) and {
| |
44 | |
45 v8::Isolate* isolate() { return isolate_; } | |
Primiano Tucci (use gerrit)
2015/07/24 14:29:14
ditto (here and below)
| |
46 | |
47 v8::Local<v8::Function> GetCallback() { | |
48 return v8::Local<v8::Function>::New(isolate_, callback_); | |
49 } | |
50 | |
51 v8::Local<v8::Context> GetContext() { | |
52 return v8::Local<v8::Context>::New(isolate_, context_); | |
53 } | |
54 | |
55 private: | |
56 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
57 v8::Isolate* isolate_; | |
58 v8::Persistent<v8::Function> callback_; | |
59 v8::Persistent<v8::Context> context_; | |
60 | |
61 DISALLOW_COPY_AND_ASSIGN(CallbackWithContext); | |
62 }; | |
63 | |
64 void OnMemoryDumpFinishedInternal( | |
65 scoped_ptr<CallbackWithContext> callback_with_context, | |
66 uint64 dump_guid, | |
67 bool success) { | |
68 DCHECK(callback_with_context->task_runner()->BelongsToCurrentThread()); | |
69 | |
70 v8::Isolate* isolate = callback_with_context->isolate(); | |
71 v8::HandleScope handle_scope(isolate); | |
72 v8::Context::Scope context_scope(callback_with_context->GetContext()); | |
73 | |
74 v8::Local<v8::Function> callback = callback_with_context->GetCallback(); | |
75 v8::Local<v8::Value> args[] = { | |
76 gin::StringToV8(isolate, base::StringPrintf("0x%" PRIx64, dump_guid)), | |
77 gin::Converter<bool>::ToV8(isolate, success)}; | |
78 | |
79 blink::WebLocalFrame* frame = blink::WebLocalFrame::frameForCurrentContext(); | |
80 if (!frame) | |
81 return; | |
82 | |
83 (void)frame->callFunctionEvenIfScriptDisabled( | |
84 callback, v8::Object::New(isolate), 2, args); | |
85 } | |
86 | |
87 void OnMemoryDumpFinished(scoped_ptr<CallbackWithContext> callback_with_context, | |
Primiano Tucci (use gerrit)
2015/07/24 14:29:14
You don't need to split the function in OnMemoryDu
| |
88 uint64 dump_guid, | |
89 bool success) { | |
90 if (!callback_with_context->task_runner()->BelongsToCurrentThread()) { | |
91 callback_with_context->task_runner()->PostTask( | |
92 FROM_HERE, | |
93 base::Bind(&OnMemoryDumpFinishedInternal, | |
94 base::Passed(&callback_with_context), dump_guid, success)); | |
95 return; | |
96 } | |
97 OnMemoryDumpFinishedInternal(callback_with_context.Pass(), dump_guid, | |
98 success); | |
99 } | |
100 | |
101 } // namespace | |
102 | |
22 gin::WrapperInfo MemoryBenchmarkingExtension::kWrapperInfo = { | 103 gin::WrapperInfo MemoryBenchmarkingExtension::kWrapperInfo = { |
23 gin::kEmbedderNativeGin}; | 104 gin::kEmbedderNativeGin}; |
24 | 105 |
25 // static | 106 // static |
26 void MemoryBenchmarkingExtension::Install(blink::WebFrame* frame) { | 107 void MemoryBenchmarkingExtension::Install(blink::WebFrame* frame) { |
27 v8::Isolate* isolate = blink::mainThreadIsolate(); | 108 v8::Isolate* isolate = blink::mainThreadIsolate(); |
28 v8::HandleScope handle_scope(isolate); | 109 v8::HandleScope handle_scope(isolate); |
29 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | 110 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); |
30 if (context.IsEmpty()) | 111 if (context.IsEmpty()) |
31 return; | 112 return; |
(...skipping 14 matching lines...) Expand all Loading... | |
46 | 127 |
47 MemoryBenchmarkingExtension::~MemoryBenchmarkingExtension() {} | 128 MemoryBenchmarkingExtension::~MemoryBenchmarkingExtension() {} |
48 | 129 |
49 gin::ObjectTemplateBuilder | 130 gin::ObjectTemplateBuilder |
50 MemoryBenchmarkingExtension::GetObjectTemplateBuilder(v8::Isolate* isolate) { | 131 MemoryBenchmarkingExtension::GetObjectTemplateBuilder(v8::Isolate* isolate) { |
51 return gin::Wrappable<MemoryBenchmarkingExtension>::GetObjectTemplateBuilder( | 132 return gin::Wrappable<MemoryBenchmarkingExtension>::GetObjectTemplateBuilder( |
52 isolate) | 133 isolate) |
53 .SetMethod("isHeapProfilerRunning", | 134 .SetMethod("isHeapProfilerRunning", |
54 &MemoryBenchmarkingExtension::IsHeapProfilerRunning) | 135 &MemoryBenchmarkingExtension::IsHeapProfilerRunning) |
55 .SetMethod("heapProfilerDump", | 136 .SetMethod("heapProfilerDump", |
56 &MemoryBenchmarkingExtension::HeapProfilerDump); | 137 &MemoryBenchmarkingExtension::HeapProfilerDump) |
138 .SetMethod("requestMemoryDump", | |
139 &MemoryBenchmarkingExtension::RequestMemoryDump); | |
57 } | 140 } |
58 | 141 |
59 bool MemoryBenchmarkingExtension::IsHeapProfilerRunning() { | 142 bool MemoryBenchmarkingExtension::IsHeapProfilerRunning() { |
60 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) | 143 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) |
61 return ::IsHeapProfilerRunning(); | 144 return ::IsHeapProfilerRunning(); |
62 #else | 145 #else |
63 return false; | 146 return false; |
64 #endif | 147 #endif |
65 } | 148 } |
66 | 149 |
(...skipping 10 matching lines...) Expand all Loading... | |
77 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) | 160 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) |
78 if (process_type == "browser") { | 161 if (process_type == "browser") { |
79 content::RenderThreadImpl::current()->Send( | 162 content::RenderThreadImpl::current()->Send( |
80 new MemoryBenchmarkHostMsg_HeapProfilerDump(reason)); | 163 new MemoryBenchmarkHostMsg_HeapProfilerDump(reason)); |
81 } else { | 164 } else { |
82 ::HeapProfilerDump(reason.c_str()); | 165 ::HeapProfilerDump(reason.c_str()); |
83 } | 166 } |
84 #endif | 167 #endif |
85 } | 168 } |
86 | 169 |
170 void MemoryBenchmarkingExtension::RequestMemoryDump(gin::Arguments* args) { | |
171 v8::Local<v8::Function> callback; | |
172 if (!args->PeekNext().IsEmpty() && args->PeekNext()->IsFunction()) | |
173 args->GetNext(&callback); | |
174 | |
175 if (callback.IsEmpty()) { | |
176 base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump( | |
177 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED); | |
178 } else { | |
179 scoped_ptr<CallbackWithContext> callback_with_context( | |
180 new CallbackWithContext(args->isolate(), callback)); | |
181 base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump( | |
182 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, | |
183 base::Bind(&OnMemoryDumpFinished, | |
184 base::Passed(&callback_with_context))); | |
185 } | |
186 } | |
187 | |
87 } // namespace content | 188 } // namespace content |
OLD | NEW |