Chromium Code Reviews| 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 |