Web Inspector: display time intervals measured with console.time() and console.timeEn...
authorcaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Jul 2012 13:47:40 +0000 (13:47 +0000)
committercaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Jul 2012 13:47:40 +0000 (13:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=90442

Reviewed by Pavel Feldman.

Source/WebCore:

- added Time and TimeEnd record types produced by console.time() and console.timeEnd()
- connect Time to TimeEnd in "glue" mode to better visualize the interval;
- always make Time a top-level record;

* English.lproj/localizedStrings.js:
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::startConsoleTimingImpl):
(WebCore::InspectorInstrumentation::stopConsoleTimingImpl):
* inspector/InspectorTimelineAgent.cpp:
(TimelineRecordType):
(WebCore::InspectorTimelineAgent::didStartTiming):
(WebCore):
(WebCore::InspectorTimelineAgent::didStopTiming):
* inspector/InspectorTimelineAgent.h:
(InspectorTimelineAgent):
* inspector/front-end/TimelineModel.js:
* inspector/front-end/TimelinePresentationModel.js:
(WebInspector.TimelinePresentationModel.recordStyle):
(WebInspector.TimelinePresentationModel.categoryForRecord):
(WebInspector.TimelinePresentationModel.prototype.reset):
(WebInspector.TimelinePresentationModel.prototype.addRecord):
(WebInspector.TimelinePresentationModel.prototype._findParentRecord):
(WebInspector.TimelinePresentationModel.Record):
(WebInspector.TimelinePresentationModel.Record.prototype.generatePopupContent):

LayoutTests:

- added Time & TimeEnd;

* inspector/timeline/timeline-enum-stability-expected.txt:

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

LayoutTests/ChangeLog
LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/English.lproj/localizedStrings.js
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorTimelineAgent.cpp
Source/WebCore/inspector/InspectorTimelineAgent.h
Source/WebCore/inspector/front-end/TimelineModel.js
Source/WebCore/inspector/front-end/TimelinePresentationModel.js

index 8a43f99..f23cdda 100644 (file)
@@ -1,3 +1,14 @@
+2012-07-03  Andrey Kosyakov  <caseq@chromium.org>
+
+        Web Inspector: display time intervals measured with console.time() and console.timeEnd() in Timeline
+        https://bugs.webkit.org/show_bug.cgi?id=90442
+
+        Reviewed by Pavel Feldman.
+
+        - added Time & TimeEnd;
+
+        * inspector/timeline/timeline-enum-stability-expected.txt:
+
 2012-07-03  Thiago Marcos P. Santos  <thiago.santos@intel.com>
 
         [EFL] Add new baselines after r121697, r121722 and r121728
index d931f14..f15e89a 100644 (file)
@@ -17,9 +17,11 @@ Applications outside of WebKit depend on the stability of the mapping of these t
     XHRReadyStateChange : "XHRReadyStateChange"
     XHRLoad : "XHRLoad"
     EvaluateScript : "EvaluateScript"
-    TimeStamp : "TimeStamp"
     MarkLoad : "MarkLoad"
     MarkDOMContent : "MarkDOMContent"
+    TimeStamp : "TimeStamp"
+    Time : "Time"
+    TimeEnd : "TimeEnd"
     ScheduleResourceRequest : "ScheduleResourceRequest"
     ResourceSendRequest : "ResourceSendRequest"
     ResourceReceiveResponse : "ResourceReceiveResponse"
index e0bb9aa..ea9b4bb 100644 (file)
@@ -1,3 +1,35 @@
+2012-07-03  Andrey Kosyakov  <caseq@chromium.org>
+
+        Web Inspector: display time intervals measured with console.time() and console.timeEnd() in Timeline
+        https://bugs.webkit.org/show_bug.cgi?id=90442
+
+        Reviewed by Pavel Feldman.
+
+        - added Time and TimeEnd record types produced by console.time() and console.timeEnd()
+        - connect Time to TimeEnd in "glue" mode to better visualize the interval;
+        - always make Time a top-level record;
+
+        * English.lproj/localizedStrings.js:
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::startConsoleTimingImpl):
+        (WebCore::InspectorInstrumentation::stopConsoleTimingImpl):
+        * inspector/InspectorTimelineAgent.cpp:
+        (TimelineRecordType):
+        (WebCore::InspectorTimelineAgent::didStartTiming):
+        (WebCore):
+        (WebCore::InspectorTimelineAgent::didStopTiming):
+        * inspector/InspectorTimelineAgent.h:
+        (InspectorTimelineAgent):
+        * inspector/front-end/TimelineModel.js:
+        * inspector/front-end/TimelinePresentationModel.js:
+        (WebInspector.TimelinePresentationModel.recordStyle):
+        (WebInspector.TimelinePresentationModel.categoryForRecord):
+        (WebInspector.TimelinePresentationModel.prototype.reset):
+        (WebInspector.TimelinePresentationModel.prototype.addRecord):
+        (WebInspector.TimelinePresentationModel.prototype._findParentRecord):
+        (WebInspector.TimelinePresentationModel.Record):
+        (WebInspector.TimelinePresentationModel.Record.prototype.generatePopupContent):
+
 2012-07-03  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>  Joel Dillon <joel.dillon@codethink.co.uk>
 
         [Qt][Win] Fix broken QtWebKit5.lib linking
index d2889d6..27aea7b 100644 (file)
@@ -711,3 +711,4 @@ localizedStrings["revert"] = "revert";
 localizedStrings["CPU Time"] = "CPU Time";
 localizedStrings["Encoded Data Length"] = "Encoded Data Length";
 localizedStrings["%d Bytes"] = "%d Bytes";
+localizedStrings["Time End"] = "Time End";
index a7accfb..78b0847 100644 (file)
@@ -879,6 +879,8 @@ void InspectorInstrumentation::consoleCountImpl(InstrumentingAgents* instrumenti
 
 void InspectorInstrumentation::startConsoleTimingImpl(InstrumentingAgents* instrumentingAgents, const String& title)
 {
+    if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent())
+        timelineAgent->time(title);
     if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent())
         consoleAgent->startTiming(title);
 }
@@ -887,6 +889,8 @@ void InspectorInstrumentation::stopConsoleTimingImpl(InstrumentingAgents* instru
 {
     if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent())
         consoleAgent->stopTiming(title, stack);
+    if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent())
+        timelineAgent->timeEnd(title);
 }
 
 void InspectorInstrumentation::consoleTimeStampImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ScriptArguments> arguments)
index c568037..30ed7cd 100644 (file)
@@ -79,6 +79,8 @@ static const char MarkLoad[] = "MarkLoad";
 static const char MarkDOMContent[] = "MarkDOMContent";
 
 static const char TimeStamp[] = "TimeStamp";
+static const char Time[] = "Time";
+static const char TimeEnd[] = "TimeEnd";
 
 static const char ScheduleResourceRequest[] = "ScheduleResourceRequest";
 static const char ResourceSendRequest[] = "ResourceSendRequest";
@@ -378,6 +380,16 @@ void InspectorTimelineAgent::didTimeStamp(const String& message)
     appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeStamp, true, 0);
 }
 
+void InspectorTimelineAgent::time(const String& message)
+{
+    appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::Time, true, 0);
+}
+
+void InspectorTimelineAgent::timeEnd(const String& message)
+{
+    appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, 0);
+}
+
 void InspectorTimelineAgent::didMarkDOMContentEvent(Frame* frame)
 {
     appendRecord(InspectorObject::create(), TimelineRecordType::MarkDOMContent, false, frame);
index 1898f6f..e447b79 100644 (file)
@@ -125,6 +125,9 @@ public:
     void didMarkDOMContentEvent(Frame*);
     void didMarkLoadEvent(Frame*);
 
+    void time(const String&);
+    void timeEnd(const String&);
+
     void didScheduleResourceRequest(const String& url, Frame*);
     void willSendResourceRequest(unsigned long, const ResourceRequest&, Frame*);
     void willReceiveResourceResponse(unsigned long, const ResourceResponse&, Frame*);
index 03ff0e7..a5fab15 100644 (file)
@@ -62,11 +62,13 @@ WebInspector.TimelineModel.RecordType = {
     XHRLoad: "XHRLoad",
     EvaluateScript: "EvaluateScript",
 
-    TimeStamp: "TimeStamp",
-
     MarkLoad: "MarkLoad",
     MarkDOMContent: "MarkDOMContent",
 
+    TimeStamp: "TimeStamp",
+    Time: "Time",
+    TimeEnd: "TimeEnd",
+
     ScheduleResourceRequest: "ScheduleResourceRequest",
     ResourceSendRequest: "ResourceSendRequest",
     ResourceReceiveResponse: "ResourceReceiveResponse",
index cc37675..2a2e6a2 100644 (file)
@@ -81,7 +81,6 @@ WebInspector.TimelinePresentationModel.recordStyle = function(record)
     recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: categories["scripting"] };
     recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: categories["scripting"] };
     recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: categories["scripting"] };
-    recordStyles[recordTypes.TimeStamp] = { title: WebInspector.UIString("Stamp"), category: categories["scripting"] };
     recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: categories["loading"] };
     recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: categories["loading"] };
     recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: categories["loading"] };
@@ -90,6 +89,9 @@ WebInspector.TimelinePresentationModel.recordStyle = function(record)
     recordStyles[recordTypes.GCEvent] = { title: WebInspector.UIString("GC Event"), category: categories["scripting"] };
     recordStyles[recordTypes.MarkDOMContent] = { title: WebInspector.UIString("DOMContent event"), category: categories["scripting"] };
     recordStyles[recordTypes.MarkLoad] = { title: WebInspector.UIString("Load event"), category: categories["scripting"] };
+    recordStyles[recordTypes.TimeStamp] = { title: WebInspector.UIString("Stamp"), category: categories["scripting"] };
+    recordStyles[recordTypes.Time] = { title: WebInspector.UIString("Time"), category: categories["scripting"] };
+    recordStyles[recordTypes.TimeEnd] = { title: WebInspector.UIString("Time End"), category: categories["scripting"] };
     recordStyles[recordTypes.ScheduleResourceRequest] = { title: WebInspector.UIString("Schedule Request"), category: categories["loading"] };
     recordStyles[recordTypes.RequestAnimationFrame] = { title: WebInspector.UIString("Request Animation Frame"), category: categories["scripting"] };
     recordStyles[recordTypes.CancelAnimationFrame] = { title: WebInspector.UIString("Cancel Animation Frame"), category: categories["scripting"] };
@@ -101,7 +103,7 @@ WebInspector.TimelinePresentationModel.recordStyle = function(record)
 
 WebInspector.TimelinePresentationModel.categoryForRecord = function(record)
 {
-        return WebInspector.TimelinePresentationModel.recordStyle(record).category;
+    return WebInspector.TimelinePresentationModel.recordStyle(record).category;
 }
 
 WebInspector.TimelinePresentationModel.isEventDivider = function(record)
@@ -191,6 +193,7 @@ WebInspector.TimelinePresentationModel.prototype = {
         this._scheduledResourceRequests = {};
         this._timerRecords = {};
         this._requestAnimationFrameRecords = {};
+        this._timeRecords = {};
         this._frames = [];
         this._minimumRecordTime = -1;
     },
@@ -208,9 +211,16 @@ WebInspector.TimelinePresentationModel.prototype = {
         if (this._minimumRecordTime === -1 || record.startTime < this._minimumRecordTime)
             this._minimumRecordTime = WebInspector.TimelineModel.startTimeInSeconds(record);
 
-        if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
-            parentRecord = null; // No bar entry for load events.
-        else {
+        switch (record.type) {
+        // No bar entry for load events.
+        case recordTypes.MarkDOMContent:
+        case recordTypes.MarkLoad:
+            parentRecord = null;
+            break;
+        case recordTypes.Time:
+            parentRecord = this._rootRecord;
+            break;
+        default:
             var newParentRecord = this._findParentRecord(record);
             if (newParentRecord) {
                 parentRecord = newParentRecord;
@@ -274,18 +284,25 @@ WebInspector.TimelinePresentationModel.prototype = {
         if (!this._glueRecords)
             return null;
         var recordTypes = WebInspector.TimelineModel.RecordType;
-        var parentRecord;
-        if (record.type === recordTypes.ResourceReceiveResponse ||
-            record.type === recordTypes.ResourceFinish ||
-            record.type === recordTypes.ResourceReceivedData)
-            parentRecord = this._sendRequestRecords[record.data["requestId"]];
-        else if (record.type === recordTypes.TimerFire)
-            parentRecord = this._timerRecords[record.data["timerId"]];
-        else if (record.type === recordTypes.ResourceSendRequest)
-            parentRecord = this._scheduledResourceRequests[record.data["url"]];
-        else if (record.type === recordTypes.FireAnimationFrame)
-            parentRecord = this._requestAnimationFrameRecords[record.data["id"]];
-        return parentRecord;
+
+        switch (record.type) {
+        case recordTypes.ResourceReceiveResponse:
+        case recordTypes.ResourceFinish:
+        case recordTypes.ResourceReceivedData:
+            return this._sendRequestRecords[record.data["requestId"]];
+
+        case recordTypes.TimerFire:
+            return this._timerRecords[record.data["timerId"]];
+
+        case recordTypes.ResourceSendRequest:
+            return this._scheduledResourceRequests[record.data["url"]];
+
+        case recordTypes.FireAnimationFrame:
+            return this._requestAnimationFrameRecords[record.data["id"]];
+
+        case recordTypes.TimeEnd:
+            return this._timeRecords[record.data["message"]];
+        }
     },
 
     setGlueRecords: function(glue)
@@ -376,12 +393,18 @@ WebInspector.TimelinePresentationModel.Record = function(presentationModel, reco
         this.scriptName = scriptDetails.scriptName;
         this.scriptLine = scriptDetails.scriptLine;
     }
-    // Make resource receive record last since request was sent; make finish record last since response received.
-    if (record.type === recordTypes.ResourceSendRequest) {
+
+    switch (record.type) {
+    case recordTypes.ResourceSendRequest:
+        // Make resource receive record last since request was sent; make finish record last since response received.
         presentationModel._sendRequestRecords[record.data["requestId"]] = this;
-    } else if (record.type === recordTypes.ScheduleResourceRequest) {
+        break;
+
+    case recordTypes.ScheduleResourceRequest:
         presentationModel._scheduledResourceRequests[record.data["url"]] = this;
-    } else if (record.type === recordTypes.ResourceReceiveResponse) {
+        break;
+
+    case recordTypes.ResourceReceiveResponse:
         var sendRequestRecord = presentationModel._sendRequestRecords[record.data["requestId"]];
         if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
             this.url = sendRequestRecord.url;
@@ -390,27 +413,52 @@ WebInspector.TimelinePresentationModel.Record = function(presentationModel, reco
             if (sendRequestRecord.parent !== presentationModel._rootRecord && sendRequestRecord.parent.type === recordTypes.ScheduleResourceRequest)
                 sendRequestRecord.parent._refreshDetails();
         }
-    } else if (record.type === recordTypes.ResourceReceivedData || record.type === recordTypes.ResourceFinish) {
+        break;
+
+    case recordTypes.ResourceReceivedData:
+    case recordTypes.ResourceFinish:
         var sendRequestRecord = presentationModel._sendRequestRecords[record.data["requestId"]];
         if (sendRequestRecord) // False for main resource.
             this.url = sendRequestRecord.url;
-    } else if (record.type === recordTypes.TimerInstall) {
+        break;
+
+    case recordTypes.TimerInstall:
         this.timeout = record.data["timeout"];
         this.singleShot = record.data["singleShot"];
         presentationModel._timerRecords[record.data["timerId"]] = this;
-    } else if (record.type === recordTypes.TimerFire) {
+        break;
+
+    case recordTypes.TimerFire:
         var timerInstalledRecord = presentationModel._timerRecords[record.data["timerId"]];
         if (timerInstalledRecord) {
             this.callSiteStackTrace = timerInstalledRecord.stackTrace;
             this.timeout = timerInstalledRecord.timeout;
             this.singleShot = timerInstalledRecord.singleShot;
         }
-    } else if (record.type === recordTypes.RequestAnimationFrame) {
+        break;
+
+    case recordTypes.RequestAnimationFrame:
         presentationModel._requestAnimationFrameRecords[record.data["id"]] = this;
-    } else if (record.type === recordTypes.FireAnimationFrame) {
+        break;
+
+    case recordTypes.FireAnimationFrame:
         var requestAnimationRecord = presentationModel._requestAnimationFrameRecords[record.data["id"]];
         if (requestAnimationRecord)
             this.callSiteStackTrace = requestAnimationRecord.stackTrace;
+        break;
+
+    case recordTypes.Time:
+        presentationModel._timeRecords[record.data["message"]] = this;
+        break;
+
+    case recordTypes.TimeEnd:
+        var timeRecord = presentationModel._timeRecords[record.data["message"]];
+        if (timeRecord) {
+            var intervalDuration = this.startTime - timeRecord.startTime;
+            this.intervalDuration = intervalDuration;
+            timeRecord.intervalDuration = intervalDuration;
+        }
+        break;
     }
     this._refreshDetails();
 }
@@ -525,8 +573,14 @@ WebInspector.TimelinePresentationModel.Record.prototype = {
             case recordTypes.Paint:
                 contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", this.data["x"], this.data["y"]));
                 contentHelper._appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", this.data["width"], this.data["height"]));
+                break;
             case recordTypes.RecalculateStyles: // We don't want to see default details.
                 break;
+            case recordTypes.Time:
+            case recordTypes.TimeEnd:
+                if (typeof this.intervalDuration === "number")
+                    contentHelper._appendTextRow(WebInspector.UIString("Interval Duration"), Number.secondsToString(this.intervalDuration, true));
+                break;
             default:
                 if (this.details)
                     contentHelper._appendTextRow(WebInspector.UIString("Details"), this.details);