1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/* 2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* Copyright (C) 2009 Google Inc. All rights reserved. 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* 4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* Redistribution and use in source and binary forms, with or without 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* modification, are permitted provided that the following conditions are 6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* met: 7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* 8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* * Redistributions of source code must retain the above copyright 9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* notice, this list of conditions and the following disclaimer. 10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* * Redistributions in binary form must reproduce the above 11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* copyright notice, this list of conditions and the following disclaimer 12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* in the documentation and/or other materials provided with the 13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* distribution. 14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* * Neither the name of Google Inc. nor the names of its 15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* contributors may be used to endorse or promote products derived from 16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* this software without specific prior written permission. 17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* 18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block*/ 30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "config.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "InspectorTimelineAgent.h" 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(INSPECTOR) 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Event.h" 37e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "InspectorFrontend.h" 382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "InspectorState.h" 3981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "InstrumentingAgents.h" 40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "IntRect.h" 41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ResourceRequest.h" 42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ResourceResponse.h" 43cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "TimelineRecordFactory.h" 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/CurrentTime.h> 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore { 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 492fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknamespace TimelineAgentState { 502fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic const char timelineAgentEnabled[] = "timelineAgentEnabled"; 512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 532bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace TimelineRecordType { 542bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char EventDispatch[] = "EventDispatch"; 552bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char Layout[] = "Layout"; 562bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char RecalculateStyles[] = "RecalculateStyles"; 572bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char Paint[] = "Paint"; 582bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char ParseHTML[] = "ParseHTML"; 592bde8e466a4451c7319e3a072d118917957d6554Steve Block 602bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char TimerInstall[] = "TimerInstall"; 612bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char TimerRemove[] = "TimerRemove"; 622bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char TimerFire[] = "TimerFire"; 632bde8e466a4451c7319e3a072d118917957d6554Steve Block 642bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char EvaluateScript[] = "EvaluateScript"; 652bde8e466a4451c7319e3a072d118917957d6554Steve Block 662bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char MarkLoad[] = "MarkLoad"; 672bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char MarkDOMContent[] = "MarkDOMContent"; 682bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char MarkTimeline[] = "MarkTimeline"; 692bde8e466a4451c7319e3a072d118917957d6554Steve Block 702bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char ScheduleResourceRequest[] = "ScheduleResourceRequest"; 712bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char ResourceSendRequest[] = "ResourceSendRequest"; 722bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char ResourceReceiveResponse[] = "ResourceReceiveResponse"; 732bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char ResourceReceivedData[] = "ResourceReceivedData"; 742bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char ResourceFinish[] = "ResourceFinish"; 752bde8e466a4451c7319e3a072d118917957d6554Steve Block 762bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char XHRReadyStateChange[] = "XHRReadyStateChange"; 772bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char XHRLoad[] = "XHRLoad"; 782bde8e466a4451c7319e3a072d118917957d6554Steve Block 792bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char FunctionCall[] = "FunctionCall"; 802bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char GCEvent[] = "GCEvent"; 812bde8e466a4451c7319e3a072d118917957d6554Steve Block} 822bde8e466a4451c7319e3a072d118917957d6554Steve Block 83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::pushGCEventRecords() 84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 8521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!m_gcEvents.size()) 8621939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 8721939df44de1705786c545cd1bf519d47250322dBen Murdoch 8821939df44de1705786c545cd1bf519d47250322dBen Murdoch GCEvents events = m_gcEvents; 8921939df44de1705786c545cd1bf519d47250322dBen Murdoch m_gcEvents.clear(); 9021939df44de1705786c545cd1bf519d47250322dBen Murdoch for (GCEvents::iterator i = events.begin(); i != events.end(); ++i) { 91e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(i->startTime); 92f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick record->setObject("data", TimelineRecordFactory::createGCEventData(i->collectedBytes)); 93e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke record->setNumber("endTime", i->endTime); 942bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::GCEvent); 95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::didGC(double startTime, double endTime, size_t collectedBytesCount) 99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_gcEvents.append(GCEvent(startTime, endTime, collectedBytesCount)); 101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockInspectorTimelineAgent::~InspectorTimelineAgent() 104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 10581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch clearFrontend(); 10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorTimelineAgent::setFrontend(InspectorFrontend* frontend) 10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_frontend = frontend->timeline(); 11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorTimelineAgent::clearFrontend() 11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ErrorString error; 11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch stop(&error); 11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_frontend = 0; 11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorTimelineAgent::restore() 12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_state->getBoolean(TimelineAgentState::timelineAgentEnabled)) { 12381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ErrorString error; 12481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch start(&error); 12581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 12681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 12781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 12881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorTimelineAgent::start(ErrorString*) 12981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!m_frontend) 13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return; 13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_instrumentingAgents->setInspectorTimelineAgent(this); 13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ScriptGCEvent::addEventListener(this); 1342bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend->started(); 13581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_state->setBoolean(TimelineAgentState::timelineAgentEnabled, true); 13681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 13781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 13881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorTimelineAgent::stop(ErrorString*) 13981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 14081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!started()) 14181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return; 14281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_instrumentingAgents->setInspectorTimelineAgent(0); 14381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (m_frontend) 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend->stopped(); 145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ScriptGCEvent::removeEventListener(this); 14681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 14781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch clearRecordStack(); 14881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_gcEvents.clear(); 14981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_state->setBoolean(TimelineAgentState::timelineAgentEnabled, false); 151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 15381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool InspectorTimelineAgent::started() const 15481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 15581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return m_state->getBoolean(TimelineAgentState::timelineAgentEnabled); 15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 15781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine) 159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall); 161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::didCallFunction() 164dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 1652bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::FunctionCall); 166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 168643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid InspectorTimelineAgent::willDispatchEvent(const Event& event) 169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 170e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event), 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block TimelineRecordType::EventDispatch); 172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 174643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid InspectorTimelineAgent::didDispatchEvent() 175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1762bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::EventDispatch); 177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid InspectorTimelineAgent::willLayout() 180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1812bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Layout); 182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid InspectorTimelineAgent::didLayout() 185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1862bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::Layout); 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid InspectorTimelineAgent::willRecalculateStyle() 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1912bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RecalculateStyles); 192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid InspectorTimelineAgent::didRecalculateStyle() 195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1962bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::RecalculateStyles); 197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 199643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid InspectorTimelineAgent::willPaint(const IntRect& rect) 200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 2012bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createPaintData(rect), TimelineRecordType::Paint); 202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid InspectorTimelineAgent::didPaint() 205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 2062bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::Paint); 207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 209d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid InspectorTimelineAgent::willWriteHTML(unsigned int length, unsigned int startLine) 210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 2112bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createParseHTMLData(length, startLine), TimelineRecordType::ParseHTML); 212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 214d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid InspectorTimelineAgent::didWriteHTML(unsigned int endLine) 215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 216d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!m_recordStack.isEmpty()) { 217d0825bca7fe65beaee391d30da42e937db621564Steve Block TimelineRecordEntry entry = m_recordStack.last(); 218e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke entry.data->setNumber("endLine", endLine); 2192bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::ParseHTML); 220d0825bca7fe65beaee391d30da42e937db621564Steve Block } 221cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 222dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 223cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool singleShot) 224cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 226e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 227f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick record->setObject("data", TimelineRecordFactory::createTimerInstallData(timerId, timeout, singleShot)); 2282bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::TimerInstall); 229cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 230cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 231cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::didRemoveTimer(int timerId) 232cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 233dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 234e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 235f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick record->setObject("data", TimelineRecordFactory::createGenericTimerData(timerId)); 2362bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::TimerRemove); 237cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 238cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 239cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::willFireTimer(int timerId) 240cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2412bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createGenericTimerData(timerId), TimelineRecordType::TimerFire); 242cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 243cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 244cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::didFireTimer() 245cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2462bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::TimerFire); 247cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 248cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 249cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::willChangeXHRReadyState(const String& url, int readyState) 250cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2512bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createXHRReadyStateChangeData(url, readyState), TimelineRecordType::XHRReadyStateChange); 252cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 253cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 254cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::didChangeXHRReadyState() 255cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2562bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::XHRReadyStateChange); 257cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 258cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 259cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::willLoadXHR(const String& url) 260cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2612bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createXHRLoadData(url), TimelineRecordType::XHRLoad); 262cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 263cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 264cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid InspectorTimelineAgent::didLoadXHR() 265cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2662bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::XHRLoad); 267cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 268cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 269643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber) 270cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2712bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript); 272cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 273cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 274643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid InspectorTimelineAgent::didEvaluateScript() 275cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2762bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::EvaluateScript); 277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 2796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid InspectorTimelineAgent::didScheduleResourceRequest(const String& url) 2806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 2816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen pushGCEventRecords(); 282e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 283f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick record->setObject("data", TimelineRecordFactory::createScheduleResourceRequestData(url)); 2842bde8e466a4451c7319e3a072d118917957d6554Steve Block record->setString("type", TimelineRecordType::ScheduleResourceRequest); 2852bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::ScheduleResourceRequest); 2866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 2876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 28865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorTimelineAgent::willSendResourceRequest(unsigned long identifier, const ResourceRequest& request) 289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 291e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch record->setObject("data", TimelineRecordFactory::createResourceSendRequestData(identifier, request)); 2932bde8e466a4451c7319e3a072d118917957d6554Steve Block record->setString("type", TimelineRecordType::ResourceSendRequest); 294e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setHeapSizeStatistic(record.get()); 2952bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend->eventRecorded(record.release()); 296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 297643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 298dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::willReceiveResourceData(unsigned long identifier) 299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 3002bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createReceiveResourceData(identifier), TimelineRecordType::ResourceReceivedData); 301dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 302dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::didReceiveResourceData() 304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 3052bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::ResourceReceivedData); 306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 307dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 308dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::willReceiveResourceResponse(unsigned long identifier, const ResourceResponse& response) 309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 3102bde8e466a4451c7319e3a072d118917957d6554Steve Block pushCurrentRecord(TimelineRecordFactory::createResourceReceiveResponseData(identifier, response), TimelineRecordType::ResourceReceiveResponse); 311dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 313dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::didReceiveResourceResponse() 314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 3152bde8e466a4451c7319e3a072d118917957d6554Steve Block didCompleteCurrentRecord(TimelineRecordType::ResourceReceiveResponse); 316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, bool didFail, double finishTime) 319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 320dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Sometimes network stack can provide for us exact finish loading time. In the other case we will use currentTime. 322f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 323f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch record->setObject("data", TimelineRecordFactory::createResourceFinishData(identifier, didFail, finishTime * 1000)); 3242bde8e466a4451c7319e3a072d118917957d6554Steve Block record->setString("type", TimelineRecordType::ResourceFinish); 325e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setHeapSizeStatistic(record.get()); 3262bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend->eventRecorded(record.release()); 327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 328643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 329643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid InspectorTimelineAgent::didMarkTimeline(const String& message) 330643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 332e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 333f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick record->setObject("data", TimelineRecordFactory::createMarkTimelineData(message)); 3342bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::MarkTimeline); 335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 336231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::didMarkDOMContentEvent() 338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 340e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 3412bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::MarkDOMContent); 342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid InspectorTimelineAgent::didMarkLoadEvent() 345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 347e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 3482bde8e466a4451c7319e3a072d118917957d6554Steve Block addRecordToTimeline(record.release(), TimelineRecordType::MarkLoad); 349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 3512fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid InspectorTimelineAgent::didCommitLoad() 352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 35381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch clearRecordStack(); 354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3562bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<InspectorObject> prpRecord, const String& type) 357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 358e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record(prpRecord); 3592bde8e466a4451c7319e3a072d118917957d6554Steve Block record->setString("type", type); 360e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setHeapSizeStatistic(record.get()); 361cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_recordStack.isEmpty()) 3622bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend->eventRecorded(record.release()); 363cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block else { 364cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block TimelineRecordEntry parent = m_recordStack.last(); 365f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick parent.children->pushObject(record.release()); 366cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 367cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 368231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 369e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid InspectorTimelineAgent::setHeapSizeStatistic(InspectorObject* record) 370dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 371dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block size_t usedHeapSize = 0; 372dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block size_t totalHeapSize = 0; 3732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block size_t heapSizeLimit = 0; 3742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ScriptGCEvent::getHeapSize(usedHeapSize, totalHeapSize, heapSizeLimit); 375e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke record->setNumber("usedHeapSize", usedHeapSize); 376e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke record->setNumber("totalHeapSize", totalHeapSize); 377dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 378dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 3792bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorTimelineAgent::didCompleteCurrentRecord(const String& type) 380cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 381643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // An empty stack could merely mean that the timeline agent was turned on in the middle of 382643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // an event. Don't treat as an error. 383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!m_recordStack.isEmpty()) { 384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block TimelineRecordEntry entry = m_recordStack.last(); 386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_recordStack.removeLast(); 387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(entry.type == type); 388f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick entry.record->setObject("data", entry.data); 389f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick entry.record->setArray("children", entry.children); 390e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke entry.record->setNumber("endTime", WTF::currentTimeMS()); 391643ca7872b450ea4efacab6188849e5aac2ba161Steve Block addRecordToTimeline(entry.record, type); 392643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 393231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 394231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 39581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochInspectorTimelineAgent::InspectorTimelineAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state) 39681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_instrumentingAgents(instrumentingAgents) 39781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_state(state) 39881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_frontend(0) 39981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_id(1) 4002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 4012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 4022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4032bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<InspectorObject> data, const String& type) 404231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 405dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block pushGCEventRecords(); 406e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); 407e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_recordStack.append(TimelineRecordEntry(record.release(), data, InspectorArray::create(), type)); 408231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 40981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 41081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorTimelineAgent::clearRecordStack() 41181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 41281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_recordStack.clear(); 41381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_id++; 41481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 41581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 416231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore 417231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 418231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif // ENABLE(INSPECTOR) 419