15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2011, Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptProfiler.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/RetainedDOMInfo.h" 35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptValue.h" 36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Binding.h" 37f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8Node.h" 38f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8Window.h" 39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/WrapperTypeInfo.h" 40e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/Document.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/BindingVisitors.h" 42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/ThreadSpecific.h" 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <v8-profiler.h> 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <v8.h> 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 47c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)typedef HashMap<String, double> ProfileNameIdleTimeMap; 50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 5106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void ScriptProfiler::setSamplingInterval(int intervalUs) 5206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 5306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 5406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) v8::CpuProfiler* profiler = isolate->GetCpuProfiler(); 5506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (profiler) 5606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) profiler->SetSamplingInterval(intervalUs); 5706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 5806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 5993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void ScriptProfiler::start(const String& title) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ProfileNameIdleTimeMap* profileNameIdleTimeMap = ScriptProfiler::currentProfileNameIdleTimeMap(); 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (profileNameIdleTimeMap->contains(title)) 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) profileNameIdleTimeMap->add(title, 0); 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 6693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 6753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::CpuProfiler* profiler = isolate->GetCpuProfiler(); 6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!profiler) 6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return; 7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HandleScope handleScope(isolate); 7143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) profiler->StartProfiling(v8String(isolate, title), true); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)PassRefPtrWillBeRawPtr<ScriptProfile> ScriptProfiler::stop(const String& title) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::CpuProfiler* profiler = isolate->GetCpuProfiler(); 7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!profiler) 79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HandleScope handleScope(isolate); 8143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) v8::CpuProfile* profile = profiler->StopProfiling(v8String(isolate, title)); 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!profile) 83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) String profileTitle = toCoreString(profile->GetTitle()); 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) double idleTime = 0.0; 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ProfileNameIdleTimeMap* profileNameIdleTimeMap = ScriptProfiler::currentProfileNameIdleTimeMap(); 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ProfileNameIdleTimeMap::iterator profileIdleTime = profileNameIdleTimeMap->find(profileTitle); 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (profileIdleTime != profileNameIdleTimeMap->end()) { 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) idleTime = profileIdleTime->value * 1000.0; 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) profileNameIdleTimeMap->remove(profileIdleTime); 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptProfile::create(profile, idleTime); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptProfiler::collectGarbage() 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) v8::Isolate::GetCurrent()->LowMemoryNotification(); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 102d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ScriptValue ScriptProfiler::objectByHeapObjectId(unsigned id) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HeapProfiler* profiler = isolate->GetHeapProfiler(); 10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HandleScope handleScope(isolate); 10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Value> value = profiler->FindObjectById(id); 10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (value.IsEmpty() || !value->IsObject()) 109d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return ScriptValue(); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Object> object = value.As<v8::Object>(); 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount) { 1145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex); 1155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // Skip wrapper boilerplates which are like regular wrappers but don't have 1165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // native object. 1175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (!wrapper.IsEmpty() && wrapper->IsUndefined()) 118d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return ScriptValue(); 1195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 1205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 121f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu ScriptState* scriptState = ScriptState::from(object->CreationContext()); 122d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return ScriptValue(scriptState, object); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned ScriptProfiler::getHeapObjectId(const ScriptValue& value) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HeapProfiler* profiler = isolate->GetHeapProfiler(); 12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::SnapshotObjectId id = profiler->GetObjectId(value.v8Value()); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return id; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void ScriptProfiler::clearHeapObjectIds() 13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::HeapProfiler* profiler = isolate->GetHeapProfiler(); 13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) profiler->ClearObjectIds(); 13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class ActivityControlAdapter FINAL : public v8::ActivityControl { 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ActivityControlAdapter(ScriptProfiler::HeapSnapshotProgress* progress) 145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch : m_progress(progress), m_firstReport(true) { } 14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual ControlOption ReportProgressValue(int done, int total) OVERRIDE 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ControlOption result = m_progress->isCanceled() ? kAbort : kContinue; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_firstReport) { 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_firstReport = false; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_progress->Start(total); 152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } else { 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_progress->Worked(done); 154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (done >= total) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_progress->Done(); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptProfiler::HeapSnapshotProgress* m_progress; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_firstReport; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class GlobalObjectNameResolver FINAL : public v8::HeapProfiler::ObjectNameResolver { 165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public: 16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual const char* GetName(v8::Handle<v8::Object> object) OVERRIDE 167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 16876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) LocalDOMWindow* window = toDOMWindow(object, v8::Isolate::GetCurrent()); 16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!window) 17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return 0; 17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) CString url = window->document()->url().string().utf8(); 17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_strings.append(url); 17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return url.data(); 174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)private: 177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Vector<CString> m_strings; 178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}; 179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void ScriptProfiler::startTrackingHeapObjects(bool trackAllocations) 18353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Isolate::GetCurrent()->GetHeapProfiler()->StartTrackingHeapObjects(trackAllocations); 18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 18753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace { 18853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 18953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class HeapStatsStream : public v8::OutputStream { 19053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public: 19153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) HeapStatsStream(ScriptProfiler::OutputStream* stream) : m_stream(stream) { } 19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) virtual void EndOfStream() OVERRIDE { } 19353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 19453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) virtual WriteResult WriteAsciiChunk(char* data, int size) OVERRIDE 19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) { 19653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ASSERT(false); 19753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return kAbort; 19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 20053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) virtual WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* updateData, int count) OVERRIDE 20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) { 20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) Vector<uint32_t> rawData(count * 3); 20353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) for (int i = 0; i < count; ++i) { 20453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) int offset = i * 3; 20553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) rawData[offset] = updateData[i].index; 20653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) rawData[offset + 1] = updateData[i].count; 20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) rawData[offset + 2] = updateData[i].size; 20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_stream->write(rawData.data(), rawData.size()); 21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return kContinue; 21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 21253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private: 21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ScriptProfiler::OutputStream* m_stream; 21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}; 21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 21853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)unsigned ScriptProfiler::requestHeapStatsUpdate(ScriptProfiler::OutputStream* stream) 22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) HeapStatsStream heapStatsStream(stream); 22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return v8::Isolate::GetCurrent()->GetHeapProfiler()->GetHeapStats(&heapStatsStream); 22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScriptProfiler::stopTrackingHeapObjects() 22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Isolate::GetCurrent()->GetHeapProfiler()->StopTrackingHeapObjects(); 22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// FIXME: This method should receive a ScriptState, from which we should retrieve an Isolate. 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<ScriptHeapSnapshot> ScriptProfiler::takeHeapSnapshot(const String& title, HeapSnapshotProgress* control) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HeapProfiler* profiler = isolate->GetHeapProfiler(); 23553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!profiler) 236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 23753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HandleScope handleScope(isolate); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(control); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ActivityControlAdapter adapter(control); 240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) GlobalObjectNameResolver resolver; 241a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const v8::HeapSnapshot* snapshot = profiler->TakeHeapSnapshot(v8String(isolate, title), &adapter, &resolver); 242d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return snapshot ? ScriptHeapSnapshot::create(snapshot) : nullptr; 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static v8::RetainedObjectInfo* retainedDOMInfo(uint16_t classId, v8::Handle<v8::Value> wrapper) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(classId == WrapperTypeInfo::NodeClassId); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!wrapper->IsObject()) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci Node* node = V8Node::toImpl(wrapper.As<v8::Object>()); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node ? new RetainedDOMInfo(node) : 0; 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptProfiler::initialize() 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HeapProfiler* profiler = isolate->GetHeapProfiler(); 25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (profiler) 2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci profiler->SetWrapperClassInfoProvider(WrapperTypeInfo::NodeClassId, &retainedDOMInfo); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptProfiler::visitNodeWrappers(WrappedNodeVisitor* visitor) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 264926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // visitNodeWrappers() should receive a ScriptState and retrieve an Isolate 265926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // from the ScriptState. 266926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::HandleScope handleScope(isolate); 268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class DOMNodeWrapperVisitor : public v8::PersistentHandleVisitor { 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DOMNodeWrapperVisitor(WrappedNodeVisitor* visitor, v8::Isolate* isolate) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_visitor(visitor) 273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isolate(isolate) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_t classId) OVERRIDE 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (classId != WrapperTypeInfo::NodeClassId) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // Casting to Handle is safe here, since the Persistent cannot get 2825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // GCd during visiting. 2835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Object>* wrapper = reinterpret_cast<v8::Handle<v8::Object>*>(value); 28409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT_UNUSED(m_isolate, V8Node::hasInstance(*wrapper, m_isolate)); 2855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ASSERT((*wrapper)->IsObject()); 2867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_visitor->visitNode(V8Node::toImpl(*wrapper)); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WrappedNodeVisitor* m_visitor; 291926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Isolate* m_isolate; 292926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } wrapperVisitor(visitor, isolate); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::V8::VisitHandlesWithClassIds(&wrapperVisitor); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 297926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ProfileNameIdleTimeMap* ScriptProfiler::currentProfileNameIdleTimeMap() 298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) AtomicallyInitializedStatic(WTF::ThreadSpecific<ProfileNameIdleTimeMap>*, map = new WTF::ThreadSpecific<ProfileNameIdleTimeMap>); 300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return *map; 301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 303e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void ScriptProfiler::setIdle(bool isIdle) 304e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){ 305e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 306e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (v8::CpuProfiler* profiler = isolate->GetCpuProfiler()) 307e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) profiler->SetIdle(isIdle); 308e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} 309e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 310c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 311