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/strings/string_util.h" | |
8 #include "content/common/memory_benchmark_messages.h" | 7 #include "content/common/memory_benchmark_messages.h" |
9 #include "content/renderer/render_thread_impl.h" | 8 #include "content/renderer/render_thread_impl.h" |
| 9 #include "gin/arguments.h" |
| 10 #include "gin/handle.h" |
| 11 #include "gin/object_template_builder.h" |
| 12 #include "third_party/WebKit/public/web/WebFrame.h" |
| 13 #include "third_party/WebKit/public/web/WebKit.h" |
10 | 14 |
11 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) | 15 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) |
12 | |
13 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" | 16 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" |
14 | 17 #endif |
15 namespace { | |
16 | |
17 const char kMemoryBenchmarkingExtensionName[] = "v8/MemoryBenchmarking"; | |
18 | |
19 } | |
20 | |
21 namespace { | |
22 | |
23 class MemoryBenchmarkingWrapper : public v8::Extension { | |
24 public: | |
25 MemoryBenchmarkingWrapper() : | |
26 v8::Extension(kMemoryBenchmarkingExtensionName, | |
27 "if (typeof(chrome) == 'undefined') {" | |
28 " chrome = {};" | |
29 "};" | |
30 "if (typeof(chrome.memoryBenchmarking) == 'undefined') {" | |
31 " chrome.memoryBenchmarking = {};" | |
32 "};" | |
33 "chrome.memoryBenchmarking.isHeapProfilerRunning = function() {" | |
34 " native function IsHeapProfilerRunning();" | |
35 " return IsHeapProfilerRunning();" | |
36 "};" | |
37 "chrome.memoryBenchmarking.heapProfilerDump = " | |
38 " function(process_type, reason) {" | |
39 " native function HeapProfilerDump();" | |
40 " HeapProfilerDump(process_type, reason);" | |
41 "};" | |
42 ) {} | |
43 | |
44 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( | |
45 v8::Isolate* isolate, | |
46 v8::Handle<v8::String> name) OVERRIDE { | |
47 if (name->Equals(v8::String::NewFromUtf8(isolate, "IsHeapProfilerRunning"))) | |
48 return v8::FunctionTemplate::New(isolate, IsHeapProfilerRunning); | |
49 else if (name->Equals(v8::String::NewFromUtf8(isolate, "HeapProfilerDump"))) | |
50 return v8::FunctionTemplate::New(isolate, HeapProfilerDump); | |
51 | |
52 return v8::Handle<v8::FunctionTemplate>(); | |
53 } | |
54 | |
55 static void IsHeapProfilerRunning( | |
56 const v8::FunctionCallbackInfo<v8::Value>& args) { | |
57 args.GetReturnValue().Set(::IsHeapProfilerRunning()); | |
58 } | |
59 | |
60 static void HeapProfilerDump( | |
61 const v8::FunctionCallbackInfo<v8::Value>& args) { | |
62 std::string process_type; | |
63 if (args.Length() && args[0]->IsString()) | |
64 process_type = *v8::String::Utf8Value(args[0]); | |
65 std::string reason("benchmarking_extension"); | |
66 if (args.Length() > 1 && args[1]->IsString()) | |
67 reason = *v8::String::Utf8Value(args[1]); | |
68 if (process_type == "browser") { | |
69 content::RenderThreadImpl::current()->Send( | |
70 new MemoryBenchmarkHostMsg_HeapProfilerDump(reason)); | |
71 } else { | |
72 ::HeapProfilerDump(reason.c_str()); | |
73 } | |
74 } | |
75 }; | |
76 | |
77 } // namespace | |
78 | 18 |
79 namespace content { | 19 namespace content { |
80 | 20 |
81 v8::Extension* MemoryBenchmarkingExtension::Get() { | 21 gin::WrapperInfo MemoryBenchmarkingExtension::kWrapperInfo = { |
82 return new MemoryBenchmarkingWrapper(); | 22 gin::kEmbedderNativeGin}; |
| 23 |
| 24 // static |
| 25 void MemoryBenchmarkingExtension::Install(blink::WebFrame* frame) { |
| 26 v8::Isolate* isolate = blink::mainThreadIsolate(); |
| 27 v8::HandleScope handle_scope(isolate); |
| 28 v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); |
| 29 if (context.IsEmpty()) |
| 30 return; |
| 31 |
| 32 v8::Context::Scope context_scope(context); |
| 33 gin::Handle<MemoryBenchmarkingExtension> controller = |
| 34 gin::CreateHandle(isolate, new MemoryBenchmarkingExtension()); |
| 35 v8::Handle<v8::Object> global = context->Global(); |
| 36 v8::Handle<v8::Object> chrome = |
| 37 global->Get(gin::StringToV8(isolate, "chrome"))->ToObject(); |
| 38 if (chrome.IsEmpty()) { |
| 39 chrome = v8::Object::New(isolate); |
| 40 global->Set(gin::StringToV8(isolate, "chrome"), chrome); |
| 41 } |
| 42 chrome->Set(gin::StringToV8(isolate, "memoryBenchmarking"), |
| 43 controller.ToV8()); |
| 44 } |
| 45 |
| 46 MemoryBenchmarkingExtension::MemoryBenchmarkingExtension() {} |
| 47 |
| 48 MemoryBenchmarkingExtension::~MemoryBenchmarkingExtension() {} |
| 49 |
| 50 gin::ObjectTemplateBuilder |
| 51 MemoryBenchmarkingExtension::GetObjectTemplateBuilder(v8::Isolate* isolate) { |
| 52 return gin::Wrappable<MemoryBenchmarkingExtension>::GetObjectTemplateBuilder( |
| 53 isolate) |
| 54 .SetMethod("isHeapProfilerRunning", |
| 55 &MemoryBenchmarkingExtension::IsHeapProfilerRunning) |
| 56 .SetMethod("heapProfilerDump", |
| 57 &MemoryBenchmarkingExtension::HeapProfilerDump); |
| 58 } |
| 59 |
| 60 bool MemoryBenchmarkingExtension::IsHeapProfilerRunning() { |
| 61 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) |
| 62 return ::IsHeapProfilerRunning(); |
| 63 #else |
| 64 return false; |
| 65 #endif |
| 66 } |
| 67 |
| 68 void MemoryBenchmarkingExtension::HeapProfilerDump(gin::Arguments* args) { |
| 69 std::string process_type; |
| 70 std::string reason("benchmarking_extension"); |
| 71 |
| 72 if (args->PeekNext()->IsString()) { |
| 73 args->GetNext(&process_type); |
| 74 if (args->PeekNext()->IsString()) |
| 75 args->GetNext(&reason); |
| 76 } |
| 77 |
| 78 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) |
| 79 if (process_type == "browser") { |
| 80 content::RenderThreadImpl::current()->Send( |
| 81 new MemoryBenchmarkHostMsg_HeapProfilerDump(reason)); |
| 82 } else { |
| 83 ::HeapProfilerDump(reason.c_str()); |
| 84 } |
| 85 #endif |
83 } | 86 } |
84 | 87 |
85 } // namespace content | 88 } // namespace content |
86 | |
87 #endif // defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) | |
OLD | NEW |