2010-09-27 Ilya Tikhonovsky <loislo@chromium.org>
authorloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Sep 2010 13:59:45 +0000 (13:59 +0000)
committerloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Sep 2010 13:59:45 +0000 (13:59 +0000)
        Reviewed by Pavel Feldman.

        Web Inspector: divide InspectorTimelineAgent into two parts.

        We have an idea to split InspectorTimelineAgent into two parts.
        The first part is an instrumentation API which can be used for DOM breakpoints too.
        The other is the real Timeline agent which do a transformation of raw data into timeline data.

        https://bugs.webkit.org/show_bug.cgi?id=46611

        * inspector/InspectorTimelineAgent.cpp:
        (WebCore::InspectorTimelineAgent2::TimelineRecordEntry::TimelineRecordEntry):
        (WebCore::InspectorTimelineAgent2::GCEvent::GCEvent):
        (WebCore::InspectorTimelineAgent2::InspectorTimelineAgent2):
        (WebCore::InspectorTimelineAgent2::~InspectorTimelineAgent2):
        (WebCore::InspectorTimelineAgent2::didGC):
        (WebCore::InspectorTimelineAgent2::addRecordToTimeline):
        (WebCore::InspectorTimelineAgent2::setHeapSizeStatistic):
        (WebCore::InspectorTimelineAgent2::startNewRecord):
        (WebCore::InspectorTimelineAgent2::completeCurrentRecord):
        (WebCore::InspectorTimelineAgent2::asyncRecord):
        (WebCore::InspectorTimelineAgent2::atomicRecord):
        (WebCore::InspectorTimelineAgent2::getTopRecordData):
        (WebCore::InspectorTimelineAgent2::reset):
        (WebCore::InspectorTimelineAgent2::resetFrontendProxyObject):
        (WebCore::InspectorTimelineAgent2::pushGCEventRecords):
        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
        (WebCore::InspectorTimelineAgent::~InspectorTimelineAgent):
        (WebCore::InspectorTimelineAgent::reset):
        (WebCore::InspectorTimelineAgent::willCallFunction):
        (WebCore::InspectorTimelineAgent::didCallFunction):
        (WebCore::InspectorTimelineAgent::willDispatchEvent):
        (WebCore::InspectorTimelineAgent::didDispatchEvent):
        (WebCore::InspectorTimelineAgent::willLayout):
        (WebCore::InspectorTimelineAgent::didLayout):
        (WebCore::InspectorTimelineAgent::willRecalculateStyle):
        (WebCore::InspectorTimelineAgent::didRecalculateStyle):
        (WebCore::InspectorTimelineAgent::willPaint):
        (WebCore::InspectorTimelineAgent::didPaint):
        (WebCore::InspectorTimelineAgent::willWriteHTML):
        (WebCore::InspectorTimelineAgent::didWriteHTML):
        (WebCore::InspectorTimelineAgent::didInstallTimer):
        (WebCore::InspectorTimelineAgent::didRemoveTimer):
        (WebCore::InspectorTimelineAgent::willFireTimer):
        (WebCore::InspectorTimelineAgent::didFireTimer):
        (WebCore::InspectorTimelineAgent::willChangeXHRReadyState):
        (WebCore::InspectorTimelineAgent::didChangeXHRReadyState):
        (WebCore::InspectorTimelineAgent::willLoadXHR):
        (WebCore::InspectorTimelineAgent::didLoadXHR):
        (WebCore::InspectorTimelineAgent::willEvaluateScript):
        (WebCore::InspectorTimelineAgent::didEvaluateScript):
        (WebCore::InspectorTimelineAgent::didScheduleResourceRequest):
        (WebCore::InspectorTimelineAgent::willSendResourceRequest):
        (WebCore::InspectorTimelineAgent::willReceiveResourceData):
        (WebCore::InspectorTimelineAgent::didReceiveResourceData):
        (WebCore::InspectorTimelineAgent::willReceiveResourceResponse):
        (WebCore::InspectorTimelineAgent::didReceiveResourceResponse):
        (WebCore::InspectorTimelineAgent::didFinishLoadingResource):
        (WebCore::InspectorTimelineAgent::didMarkTimeline):
        (WebCore::InspectorTimelineAgent::didMarkDOMContentEvent):
        (WebCore::InspectorTimelineAgent::didMarkLoadEvent):
        (WebCore::InspectorTimelineAgent::resetFrontendProxyObject):
        * inspector/InspectorTimelineAgent.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@68389 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/inspector/InspectorTimelineAgent.cpp
WebCore/inspector/InspectorTimelineAgent.h

index 75810c07c4296d4fe0579363b7a9f11393455884..adf20a966cc37f8b3cf82cfc294a3e977854862a 100644 (file)
@@ -1,3 +1,69 @@
+2010-09-27  Ilya Tikhonovsky  <loislo@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Web Inspector: divide InspectorTimelineAgent into two parts.
+
+        We have an idea to split InspectorTimelineAgent into two parts.
+        The first part is an instrumentation API which can be used for DOM breakpoints too.
+        The other is the real Timeline agent which do a transformation of raw data into timeline data.
+
+        https://bugs.webkit.org/show_bug.cgi?id=46611
+
+        * inspector/InspectorTimelineAgent.cpp:
+        (WebCore::InspectorTimelineAgent2::TimelineRecordEntry::TimelineRecordEntry):
+        (WebCore::InspectorTimelineAgent2::GCEvent::GCEvent):
+        (WebCore::InspectorTimelineAgent2::InspectorTimelineAgent2):
+        (WebCore::InspectorTimelineAgent2::~InspectorTimelineAgent2):
+        (WebCore::InspectorTimelineAgent2::didGC):
+        (WebCore::InspectorTimelineAgent2::addRecordToTimeline):
+        (WebCore::InspectorTimelineAgent2::setHeapSizeStatistic):
+        (WebCore::InspectorTimelineAgent2::startNewRecord):
+        (WebCore::InspectorTimelineAgent2::completeCurrentRecord):
+        (WebCore::InspectorTimelineAgent2::asyncRecord):
+        (WebCore::InspectorTimelineAgent2::atomicRecord):
+        (WebCore::InspectorTimelineAgent2::getTopRecordData):
+        (WebCore::InspectorTimelineAgent2::reset):
+        (WebCore::InspectorTimelineAgent2::resetFrontendProxyObject):
+        (WebCore::InspectorTimelineAgent2::pushGCEventRecords):
+        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+        (WebCore::InspectorTimelineAgent::~InspectorTimelineAgent):
+        (WebCore::InspectorTimelineAgent::reset):
+        (WebCore::InspectorTimelineAgent::willCallFunction):
+        (WebCore::InspectorTimelineAgent::didCallFunction):
+        (WebCore::InspectorTimelineAgent::willDispatchEvent):
+        (WebCore::InspectorTimelineAgent::didDispatchEvent):
+        (WebCore::InspectorTimelineAgent::willLayout):
+        (WebCore::InspectorTimelineAgent::didLayout):
+        (WebCore::InspectorTimelineAgent::willRecalculateStyle):
+        (WebCore::InspectorTimelineAgent::didRecalculateStyle):
+        (WebCore::InspectorTimelineAgent::willPaint):
+        (WebCore::InspectorTimelineAgent::didPaint):
+        (WebCore::InspectorTimelineAgent::willWriteHTML):
+        (WebCore::InspectorTimelineAgent::didWriteHTML):
+        (WebCore::InspectorTimelineAgent::didInstallTimer):
+        (WebCore::InspectorTimelineAgent::didRemoveTimer):
+        (WebCore::InspectorTimelineAgent::willFireTimer):
+        (WebCore::InspectorTimelineAgent::didFireTimer):
+        (WebCore::InspectorTimelineAgent::willChangeXHRReadyState):
+        (WebCore::InspectorTimelineAgent::didChangeXHRReadyState):
+        (WebCore::InspectorTimelineAgent::willLoadXHR):
+        (WebCore::InspectorTimelineAgent::didLoadXHR):
+        (WebCore::InspectorTimelineAgent::willEvaluateScript):
+        (WebCore::InspectorTimelineAgent::didEvaluateScript):
+        (WebCore::InspectorTimelineAgent::didScheduleResourceRequest):
+        (WebCore::InspectorTimelineAgent::willSendResourceRequest):
+        (WebCore::InspectorTimelineAgent::willReceiveResourceData):
+        (WebCore::InspectorTimelineAgent::didReceiveResourceData):
+        (WebCore::InspectorTimelineAgent::willReceiveResourceResponse):
+        (WebCore::InspectorTimelineAgent::didReceiveResourceResponse):
+        (WebCore::InspectorTimelineAgent::didFinishLoadingResource):
+        (WebCore::InspectorTimelineAgent::didMarkTimeline):
+        (WebCore::InspectorTimelineAgent::didMarkDOMContentEvent):
+        (WebCore::InspectorTimelineAgent::didMarkLoadEvent):
+        (WebCore::InspectorTimelineAgent::resetFrontendProxyObject):
+        * inspector/InspectorTimelineAgent.h:
+
 2010-09-27  Alexander Pavlov  <apavlov@chromium.org>
 
         Reviewed by Sam Weinig.
index fbb17c46fb7928e13105e435561cc7bfe5976286..6e85f86ddb98f8c7de356727a5f680bd994bd174 100644 (file)
@@ -46,15 +46,151 @@ namespace WebCore {
 
 int InspectorTimelineAgent::s_instanceCount = 0;
 
-InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
-    : m_frontend(frontend)
+class InspectorTimelineAgent2 : ScriptGCEventListener, public Noncopyable {
+public:
+    InspectorTimelineAgent2(InspectorFrontend* frontend);
+    virtual ~InspectorTimelineAgent2();
+
+    void startNewRecord(PassRefPtr<InspectorObject>, TimelineRecordType);
+    void completeCurrentRecord(TimelineRecordType);
+    void addAtomicRecord(PassRefPtr<InspectorObject>, TimelineRecordType);
+    void pushOutOfOrderRecord(PassRefPtr<InspectorObject>, TimelineRecordType);
+    InspectorObject* getTopRecordData();
+    virtual void didGC(double, double, size_t);
+
+    void resetFrontendProxyObject(InspectorFrontend* frontend);
+    void reset();
+
+private:
+    struct TimelineRecordEntry {
+        TimelineRecordEntry(PassRefPtr<InspectorObject> record, PassRefPtr<InspectorObject> data, PassRefPtr<InspectorArray> children, TimelineRecordType type)
+            : record(record), data(data), children(children), type(type)
+        {
+        }
+        RefPtr<InspectorObject> record;
+        RefPtr<InspectorObject> data;
+        RefPtr<InspectorArray> children;
+        TimelineRecordType type;
+    };
+    Vector<TimelineRecordEntry> m_recordStack;
+
+    struct GCEvent {
+        GCEvent(double startTime, double endTime, size_t collectedBytes)
+            : startTime(startTime), endTime(endTime), collectedBytes(collectedBytes)
+        {
+        }
+        double startTime;
+        double endTime;
+        size_t collectedBytes;
+    };
+    typedef Vector<GCEvent> GCEvents;
+    GCEvents m_gcEvents;
+    InspectorFrontend* m_frontend;
+
+    void pushGCEventRecords();
+    void setHeapSizeStatistic(InspectorObject* record);
+    void addRecordToTimeline(PassRefPtr<InspectorObject> prpRecord, TimelineRecordType type);
+};
+
+InspectorTimelineAgent2::InspectorTimelineAgent2(InspectorFrontend* frontend)
 {
-    ++s_instanceCount;
+    m_frontend = frontend;
     ScriptGCEvent::addEventListener(this);
-    ASSERT(m_frontend);
 }
 
-void InspectorTimelineAgent::pushGCEventRecords()
+InspectorTimelineAgent2::~InspectorTimelineAgent2()
+{
+    ScriptGCEvent::removeEventListener(this);
+}
+
+void InspectorTimelineAgent2::didGC(double startTime, double endTime, size_t collectedBytesCount)
+{
+    m_gcEvents.append(GCEvent(startTime, endTime, collectedBytesCount));
+}
+
+void InspectorTimelineAgent2::addRecordToTimeline(PassRefPtr<InspectorObject> prpRecord, TimelineRecordType type)
+{
+    RefPtr<InspectorObject> record(prpRecord);
+    record->setNumber("type", type);
+    setHeapSizeStatistic(record.get());
+    if (m_recordStack.isEmpty())
+        m_frontend->addRecordToTimeline(record.release());
+    else {
+        TimelineRecordEntry parent = m_recordStack.last();
+        parent.children->pushObject(record.release());
+    }
+}
+
+void InspectorTimelineAgent2::setHeapSizeStatistic(InspectorObject* record)
+{
+    size_t usedHeapSize = 0;
+    size_t totalHeapSize = 0;
+    ScriptGCEvent::getHeapSize(usedHeapSize, totalHeapSize);
+    record->setNumber("usedHeapSize", usedHeapSize);
+    record->setNumber("totalHeapSize", totalHeapSize);
+}
+
+void InspectorTimelineAgent2::startNewRecord(PassRefPtr<InspectorObject> data, TimelineRecordType type)
+{
+    pushGCEventRecords();
+    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
+    m_recordStack.append(TimelineRecordEntry(record.release(), data, InspectorArray::create(), type));
+}
+
+void InspectorTimelineAgent2::completeCurrentRecord(TimelineRecordType type)
+{
+    // An empty stack could merely mean that the timeline agent was turned on in the middle of
+    // an event.  Don't treat as an error.
+    if (!m_recordStack.isEmpty()) {
+        pushGCEventRecords();
+        TimelineRecordEntry entry = m_recordStack.last();
+        m_recordStack.removeLast();
+        ASSERT(entry.type == type);
+        entry.record->setObject("data", entry.data);
+        entry.record->setArray("children", entry.children);
+        entry.record->setNumber("endTime", WTF::currentTimeMS());
+        addRecordToTimeline(entry.record, type);
+    }
+}
+
+void InspectorTimelineAgent2::pushOutOfOrderRecord(PassRefPtr<InspectorObject> data, TimelineRecordType recordType)
+{
+    pushGCEventRecords();
+    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
+    record->setObject("data", data);
+    record->setNumber("type", recordType);
+    setHeapSizeStatistic(record.get());
+    m_frontend->addRecordToTimeline(record.release());
+}
+
+void InspectorTimelineAgent2::addAtomicRecord(PassRefPtr<InspectorObject> data, TimelineRecordType recordType)
+{
+    pushGCEventRecords();
+    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
+    record->setObject("data", data);
+    addRecordToTimeline(record.release(), recordType);
+}
+
+InspectorObject* InspectorTimelineAgent2::getTopRecordData()
+{
+    if (m_recordStack.isEmpty())
+        return 0;
+    return m_recordStack.last().data.get();
+}
+
+void InspectorTimelineAgent2::reset()
+{
+    m_recordStack.clear();
+}
+
+void InspectorTimelineAgent2::resetFrontendProxyObject(InspectorFrontend* frontend)
+{
+    ASSERT(frontend);
+    reset();
+    m_frontend = frontend;
+}
+
+void InspectorTimelineAgent2::pushGCEventRecords()
 {
     if (!m_gcEvents.size())
         return;
@@ -69,267 +205,227 @@ void InspectorTimelineAgent::pushGCEventRecords()
     }
 }
 
-void InspectorTimelineAgent::didGC(double startTime, double endTime, size_t collectedBytesCount)
+InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
 {
-    m_gcEvents.append(GCEvent(startTime, endTime, collectedBytesCount));
+    ++s_instanceCount;
+    m_timelineAgent = new InspectorTimelineAgent2(frontend);
 }
 
 InspectorTimelineAgent::~InspectorTimelineAgent()
 {
     ASSERT(s_instanceCount);
     --s_instanceCount;
-    ScriptGCEvent::removeEventListener(this);
+}
+
+void InspectorTimelineAgent::reset()
+{
+    if (m_timelineAgent)
+        m_timelineAgent->reset();
 }
 
 void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine)
 {
-    pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), FunctionCallTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), FunctionCallTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didCallFunction()
 {
-    didCompleteCurrentRecord(FunctionCallTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(FunctionCallTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willDispatchEvent(const Event& event)
 {
-    pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event),
-        EventDispatchTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createEventDispatchData(event), EventDispatchTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didDispatchEvent()
 {
-    didCompleteCurrentRecord(EventDispatchTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(EventDispatchTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willLayout()
 {
-    pushCurrentRecord(InspectorObject::create(), LayoutTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(InspectorObject::create(), LayoutTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didLayout()
 {
-    didCompleteCurrentRecord(LayoutTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(LayoutTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willRecalculateStyle()
 {
-    pushCurrentRecord(InspectorObject::create(), RecalculateStylesTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(InspectorObject::create(), RecalculateStylesTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didRecalculateStyle()
 {
-    didCompleteCurrentRecord(RecalculateStylesTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(RecalculateStylesTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willPaint(const IntRect& rect)
 {
-    pushCurrentRecord(TimelineRecordFactory::createPaintData(rect), PaintTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createPaintData(rect), PaintTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didPaint()
 {
-    didCompleteCurrentRecord(PaintTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(PaintTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willWriteHTML(unsigned int length, unsigned int startLine)
 {
-    pushCurrentRecord(TimelineRecordFactory::createParseHTMLData(length, startLine), ParseHTMLTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createParseHTMLData(length, startLine), ParseHTMLTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didWriteHTML(unsigned int endLine)
 {
-    if (!m_recordStack.isEmpty()) {
-        TimelineRecordEntry entry = m_recordStack.last();
-        entry.data->setNumber("endLine", endLine);
-        didCompleteCurrentRecord(ParseHTMLTimelineRecordType);
+    if (m_timelineAgent) {
+        InspectorObject* data = m_timelineAgent->getTopRecordData();
+        if (data) {
+            data->setNumber("endLine", endLine);
+            m_timelineAgent->completeCurrentRecord(ParseHTMLTimelineRecordType);
+        }
     }
 }
 
 void InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool singleShot)
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    record->setObject("data", TimelineRecordFactory::createTimerInstallData(timerId, timeout, singleShot));
-    addRecordToTimeline(record.release(), TimerInstallTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->addAtomicRecord(TimelineRecordFactory::createTimerInstallData(timerId, timeout, singleShot), TimerInstallTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didRemoveTimer(int timerId)
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    record->setObject("data", TimelineRecordFactory::createGenericTimerData(timerId));
-    addRecordToTimeline(record.release(), TimerRemoveTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->addAtomicRecord(TimelineRecordFactory::createGenericTimerData(timerId), TimerRemoveTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willFireTimer(int timerId)
 {
-    pushCurrentRecord(TimelineRecordFactory::createGenericTimerData(timerId), TimerFireTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createGenericTimerData(timerId), TimerFireTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didFireTimer()
 {
-    didCompleteCurrentRecord(TimerFireTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(TimerFireTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willChangeXHRReadyState(const String& url, int readyState)
 {
-    pushCurrentRecord(TimelineRecordFactory::createXHRReadyStateChangeData(url, readyState), XHRReadyStateChangeRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createXHRReadyStateChangeData(url, readyState), XHRReadyStateChangeRecordType);
 }
 
 void InspectorTimelineAgent::didChangeXHRReadyState()
 {
-    didCompleteCurrentRecord(XHRReadyStateChangeRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(XHRReadyStateChangeRecordType);
 }
 
 void InspectorTimelineAgent::willLoadXHR(const String& url) 
 {
-    pushCurrentRecord(TimelineRecordFactory::createXHRLoadData(url), XHRLoadRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createXHRLoadData(url), XHRLoadRecordType);
 }
 
 void InspectorTimelineAgent::didLoadXHR()
 {
-    didCompleteCurrentRecord(XHRLoadRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(XHRLoadRecordType);
 }
 
 void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber)
 {
-    pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), EvaluateScriptTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), EvaluateScriptTimelineRecordType);
 }
     
 void InspectorTimelineAgent::didEvaluateScript()
 {
-    didCompleteCurrentRecord(EvaluateScriptTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(EvaluateScriptTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didScheduleResourceRequest(const String& url)
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    record->setObject("data", TimelineRecordFactory::createScheduleResourceRequestData(url));
-    record->setNumber("type", ScheduleResourceRequestTimelineRecordType);
-    addRecordToTimeline(record.release(), ScheduleResourceRequestTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->addAtomicRecord(TimelineRecordFactory::createScheduleResourceRequestData(url), ScheduleResourceRequestTimelineRecordType);
 }
 
-void InspectorTimelineAgent::willSendResourceRequest(unsigned long identifier, bool isMainResource,
-    const ResourceRequest& request)
+void InspectorTimelineAgent::willSendResourceRequest(unsigned long identifier, bool isMainResource, const ResourceRequest& request)
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    record->setObject("data", TimelineRecordFactory::createResourceSendRequestData(identifier, isMainResource, request));
-    record->setNumber("type", ResourceSendRequestTimelineRecordType);
-    setHeapSizeStatistic(record.get());
-    m_frontend->addRecordToTimeline(record.release());
+    if (m_timelineAgent)
+        m_timelineAgent->pushOutOfOrderRecord(TimelineRecordFactory::createResourceSendRequestData(identifier, isMainResource, request), ResourceSendRequestTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willReceiveResourceData(unsigned long identifier)
 {
-    pushCurrentRecord(TimelineRecordFactory::createReceiveResourceData(identifier), ReceiveResourceDataTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createReceiveResourceData(identifier), ReceiveResourceDataTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didReceiveResourceData()
 {
-    didCompleteCurrentRecord(ReceiveResourceDataTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(ReceiveResourceDataTimelineRecordType);
 }
     
 void InspectorTimelineAgent::willReceiveResourceResponse(unsigned long identifier, const ResourceResponse& response)
 {
-    pushCurrentRecord(TimelineRecordFactory::createResourceReceiveResponseData(identifier, response), ResourceReceiveResponseTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->startNewRecord(TimelineRecordFactory::createResourceReceiveResponseData(identifier, response), ResourceReceiveResponseTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didReceiveResourceResponse()
 {
-    didCompleteCurrentRecord(ResourceReceiveResponseTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->completeCurrentRecord(ResourceReceiveResponseTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, bool didFail)
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    record->setObject("data", TimelineRecordFactory::createResourceFinishData(identifier, didFail));
-    record->setNumber("type", ResourceFinishTimelineRecordType);
-    setHeapSizeStatistic(record.get());
-    m_frontend->addRecordToTimeline(record.release());
+    if (m_timelineAgent)
+        m_timelineAgent->pushOutOfOrderRecord(TimelineRecordFactory::createResourceFinishData(identifier, didFail), ResourceFinishTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didMarkTimeline(const String& message)
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    record->setObject("data", TimelineRecordFactory::createMarkTimelineData(message));
-    addRecordToTimeline(record.release(), MarkTimelineRecordType);
+    if (m_timelineAgent)
+        m_timelineAgent->addAtomicRecord(TimelineRecordFactory::createMarkTimelineData(message), MarkTimelineRecordType);
 }
 
 void InspectorTimelineAgent::didMarkDOMContentEvent()
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    addRecordToTimeline(record.release(), MarkDOMContentEventType);
+    if (m_timelineAgent)
+        m_timelineAgent->addAtomicRecord(InspectorObject::create(), MarkDOMContentEventType);
 }
 
 void InspectorTimelineAgent::didMarkLoadEvent()
 {
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    addRecordToTimeline(record.release(), MarkLoadEventType);
-}
-
-void InspectorTimelineAgent::reset()
-{
-    m_recordStack.clear();
+    if (m_timelineAgent)
+        m_timelineAgent->addAtomicRecord(InspectorObject::create(), MarkLoadEventType);
 }
 
 void InspectorTimelineAgent::resetFrontendProxyObject(InspectorFrontend* frontend)
 {
-    ASSERT(frontend);
-    reset();
-    m_frontend = frontend;
-}
-
-void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<InspectorObject> prpRecord, TimelineRecordType type)
-{
-    RefPtr<InspectorObject> record(prpRecord);
-    record->setNumber("type", type);
-    setHeapSizeStatistic(record.get());
-    if (m_recordStack.isEmpty())
-        m_frontend->addRecordToTimeline(record.release());
-    else {
-        TimelineRecordEntry parent = m_recordStack.last();
-        parent.children->pushObject(record.release());
-    }
-}
-
-void InspectorTimelineAgent::setHeapSizeStatistic(InspectorObject* record)
-{
-    size_t usedHeapSize = 0;
-    size_t totalHeapSize = 0;
-    ScriptGCEvent::getHeapSize(usedHeapSize, totalHeapSize);
-    record->setNumber("usedHeapSize", usedHeapSize);
-    record->setNumber("totalHeapSize", totalHeapSize);
+    if (m_timelineAgent)
+        m_timelineAgent->resetFrontendProxyObject(frontend);
 }
 
-void InspectorTimelineAgent::didCompleteCurrentRecord(TimelineRecordType type)
-{
-    // An empty stack could merely mean that the timeline agent was turned on in the middle of
-    // an event.  Don't treat as an error.
-    if (!m_recordStack.isEmpty()) {
-        pushGCEventRecords();
-        TimelineRecordEntry entry = m_recordStack.last();
-        m_recordStack.removeLast();
-        ASSERT(entry.type == type);
-        entry.record->setObject("data", entry.data);
-        entry.record->setArray("children", entry.children);
-        entry.record->setNumber("endTime", WTF::currentTimeMS());
-        addRecordToTimeline(entry.record, type);
-    }
-}
-
-void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<InspectorObject> data, TimelineRecordType type)
-{
-    pushGCEventRecords();
-    RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS());
-    m_recordStack.append(TimelineRecordEntry(record.release(), data, InspectorArray::create(), type));
-}
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)
index 410e18906df8a1e8b017933115a49b300a61ee37..9de3c4e637a0466d89e78d0602542fcc926c8fc5 100644 (file)
@@ -46,6 +46,7 @@ class InspectorFrontend;
 class IntRect;
 class ResourceRequest;
 class ResourceResponse;
+class InspectorTimelineAgent2;
 
 // Must be kept in sync with TimelineAgent.js
 enum TimelineRecordType {
@@ -73,7 +74,7 @@ enum TimelineRecordType {
     XHRSendRecordType = 21
 };
 
-class InspectorTimelineAgent : ScriptGCEventListener, public Noncopyable {
+class InspectorTimelineAgent : public Noncopyable {
 public:
     InspectorTimelineAgent(InspectorFrontend* frontend);
     ~InspectorTimelineAgent();
@@ -126,48 +127,15 @@ public:
     void didFinishLoadingResource(unsigned long, bool didFail);
     void willReceiveResourceData(unsigned long identifier);
     void didReceiveResourceData();
-        
-    virtual void didGC(double, double, size_t);
 
     static int instanceCount() { return s_instanceCount; }
     static InspectorTimelineAgent* retrieve(ScriptExecutionContext*);
 
 private:
-    struct TimelineRecordEntry {
-        TimelineRecordEntry(PassRefPtr<InspectorObject> record, PassRefPtr<InspectorObject> data, PassRefPtr<InspectorArray> children, TimelineRecordType type)
-            : record(record), data(data), children(children), type(type)
-        {
-        }
-        RefPtr<InspectorObject> record;
-        RefPtr<InspectorObject> data;
-        RefPtr<InspectorArray> children;
-        TimelineRecordType type;
-    };
-        
-    void pushCurrentRecord(PassRefPtr<InspectorObject>, TimelineRecordType);
-    void setHeapSizeStatistic(InspectorObject* record);
-        
-    void didCompleteCurrentRecord(TimelineRecordType);
-
-    void addRecordToTimeline(PassRefPtr<InspectorObject>, TimelineRecordType);
-
-    void pushGCEventRecords();
-
-    InspectorFrontend* m_frontend;
-
-    Vector<TimelineRecordEntry> m_recordStack;
+
     static int s_instanceCount;
-    struct GCEvent {
-        GCEvent(double startTime, double endTime, size_t collectedBytes)
-            : startTime(startTime), endTime(endTime), collectedBytes(collectedBytes)
-        {
-        }
-        double startTime;
-        double endTime;
-        size_t collectedBytes;
-    };
-    typedef Vector<GCEvent> GCEvents;
-    GCEvents m_gcEvents;
+
+    OwnPtr<InspectorTimelineAgent2> m_timelineAgent;
 };
 
 inline InspectorTimelineAgent* InspectorTimelineAgent::retrieve(ScriptExecutionContext* context)