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 14const char kBenchmarkingExtensionName[] = "v8/Benchmarking"; 15 16namespace extensions_v8 { 17 18class 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.counterForRenderer = function(name) {" 33 " native function GetCounterForRenderer();" 34 " return GetCounterForRenderer(name);" 35 "};" 36 "chrome.benchmarking.isSingleProcess = function() {" 37 " native function IsSingleProcess();" 38 " return IsSingleProcess();" 39 "};" 40 "chrome.Interval = function() {" 41 " var start_ = 0;" 42 " var stop_ = 0;" 43 " native function HiResTime();" 44 " this.start = function() {" 45 " stop_ = 0;" 46 " start_ = HiResTime();" 47 " };" 48 " this.stop = function() {" 49 " stop_ = HiResTime();" 50 " if (start_ == 0)" 51 " stop_ = 0;" 52 " };" 53 " this.microseconds = function() {" 54 " var stop = stop_;" 55 " if (stop == 0 && start_ != 0)" 56 " stop = HiResTime();" 57 " return Math.ceil(stop - start_);" 58 " };" 59 "}" 60 ) {} 61 62 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( 63 v8::Isolate* isolate, 64 v8::Handle<v8::String> name) OVERRIDE { 65 if (name->Equals(v8::String::NewFromUtf8(isolate, "GetCounter"))) { 66 return v8::FunctionTemplate::New(isolate, GetCounter); 67 } else if (name->Equals( 68 v8::String::NewFromUtf8(isolate, "GetCounterForRenderer"))) { 69 return v8::FunctionTemplate::New(isolate, GetCounterForRenderer); 70 } else if (name->Equals( 71 v8::String::NewFromUtf8(isolate, "IsSingleProcess"))) { 72 return v8::FunctionTemplate::New(isolate, IsSingleProcess); 73 } else if (name->Equals(v8::String::NewFromUtf8(isolate, "HiResTime"))) { 74 return v8::FunctionTemplate::New(isolate, HiResTime); 75 } 76 77 return v8::Handle<v8::FunctionTemplate>(); 78 } 79 80 /* 81 * Extract the counter name from arguments. 82 */ 83 static void ExtractCounterName( 84 const v8::FunctionCallbackInfo<v8::Value>& args, 85 char* name, 86 size_t capacity) { 87 name[0] = 'c'; 88 name[1] = ':'; 89 args[0]->ToString()->WriteUtf8(&name[2], capacity - 3); 90 } 91 92 static void GetCounter(const v8::FunctionCallbackInfo<v8::Value>& args) { 93 if (!args.Length() || !args[0]->IsString() || !base::StatsTable::current()) 94 return; 95 96 char name[256]; 97 ExtractCounterName(args, name, sizeof(name)); 98 int counter = base::StatsTable::current()->GetCounterValue(name); 99 args.GetReturnValue().Set(static_cast<int32_t>(counter)); 100 } 101 102 static void GetCounterForRenderer( 103 const v8::FunctionCallbackInfo<v8::Value>& args) { 104 if (!args.Length() || !args[0]->IsString() || !base::StatsTable::current()) 105 return; 106 107 char name[256]; 108 ExtractCounterName(args, name, sizeof(name)); 109 int counter = base::StatsTable::current()->GetCounterValue( 110 name, 111 base::GetCurrentProcId()); 112 args.GetReturnValue().Set(static_cast<int32_t>(counter)); 113 } 114 115 static void IsSingleProcess(const v8::FunctionCallbackInfo<v8::Value>& args) { 116 args.GetReturnValue().Set( 117 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)); 118 } 119 120 static void HiResTime(const v8::FunctionCallbackInfo<v8::Value>& args) { 121 args.GetReturnValue().Set( 122 static_cast<double>(base::TimeTicks::HighResNow().ToInternalValue())); 123 } 124}; 125 126v8::Extension* BenchmarkingExtension::Get() { 127 return new BenchmarkingWrapper(); 128} 129 130} // namespace extensions_v8 131