1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/renderer/benchmarking_extension.h" 6 7 #include "base/command_line.h" 8 #include "base/metrics/stats_table.h" 9 #include "base/time/time.h" 10 #include "content/public/common/content_switches.h" 11 #include "content/public/renderer/render_thread.h" 12 #include "v8/include/v8.h" 13 14 const char kBenchmarkingExtensionName[] = "v8/Benchmarking"; 15 16 namespace extensions_v8 { 17 18 class BenchmarkingWrapper : public v8::Extension { 19 public: 20 BenchmarkingWrapper() : 21 v8::Extension(kBenchmarkingExtensionName, 22 "if (typeof(chrome) == 'undefined') {" 23 " chrome = {};" 24 "};" 25 "if (typeof(chrome.benchmarking) == 'undefined') {" 26 " chrome.benchmarking = {};" 27 "};" 28 "chrome.benchmarking.counter = function(name) {" 29 " native function GetCounter();" 30 " return GetCounter(name);" 31 "};" 32 "chrome.benchmarking.isSingleProcess = function() {" 33 " native function IsSingleProcess();" 34 " return IsSingleProcess();" 35 "};" 36 "chrome.Interval = function() {" 37 " var start_ = 0;" 38 " var stop_ = 0;" 39 " native function HiResTime();" 40 " this.start = function() {" 41 " stop_ = 0;" 42 " start_ = HiResTime();" 43 " };" 44 " this.stop = function() {" 45 " stop_ = HiResTime();" 46 " if (start_ == 0)" 47 " stop_ = 0;" 48 " };" 49 " this.microseconds = function() {" 50 " var stop = stop_;" 51 " if (stop == 0 && start_ != 0)" 52 " stop = HiResTime();" 53 " return Math.ceil(stop - start_);" 54 " };" 55 "}" 56 ) {} 57 58 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 59 v8::Handle<v8::String> name) OVERRIDE { 60 if (name->Equals(v8::String::New("GetCounter"))) { 61 return v8::FunctionTemplate::New(GetCounter); 62 } else if (name->Equals(v8::String::New("IsSingleProcess"))) { 63 return v8::FunctionTemplate::New(IsSingleProcess); 64 } else if (name->Equals(v8::String::New("HiResTime"))) { 65 return v8::FunctionTemplate::New(HiResTime); 66 } 67 68 return v8::Handle<v8::FunctionTemplate>(); 69 } 70 71 static void GetCounter(const v8::FunctionCallbackInfo<v8::Value>& args) { 72 if (!args.Length() || !args[0]->IsString() || !base::StatsTable::current()) 73 return; 74 75 // Extract the name argument 76 char name[256]; 77 name[0] = 'c'; 78 name[1] = ':'; 79 args[0]->ToString()->WriteUtf8(&name[2], sizeof(name) - 3); 80 81 int counter = base::StatsTable::current()->GetCounterValue(name); 82 args.GetReturnValue().Set(static_cast<int32_t>(counter)); 83 } 84 85 static void IsSingleProcess(const v8::FunctionCallbackInfo<v8::Value>& args) { 86 args.GetReturnValue().Set( 87 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)); 88 } 89 90 static void HiResTime(const v8::FunctionCallbackInfo<v8::Value>& args) { 91 args.GetReturnValue().Set( 92 static_cast<double>(base::TimeTicks::HighResNow().ToInternalValue())); 93 } 94 }; 95 96 v8::Extension* BenchmarkingExtension::Get() { 97 return new BenchmarkingWrapper(); 98 } 99 100 } // namespace extensions_v8 101