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