Title: [173992] trunk
Revision
173992
Author
[email protected]
Date
2014-09-25 19:29:50 -0700 (Thu, 25 Sep 2014)

Log Message

Web Inspector: FunctionCall timeline records omit profile data if the debugger has paused
https://bugs.webkit.org/show_bug.cgi?id=136805

Reviewed by Timothy Hatcher.

Source/WebCore:

TimelineAgent was mismanaging its call stack depth counter, which caused nested FunctionCall
records to steal the parent FunctionCall's captured profile in the child's didCallFunction().
Thus, the top FunctionCall node had no profile data and nested FunctionCall nodes each had
their own profiles. The frontend expected just one profile, so it didn't show anything when
it couldn't be found.

Test: inspector/timeline/debugger-paused-while-recording.html

* inspector/InspectorTimelineAgent.cpp: Rename m_recordingProfileDepth to m_callStackDepth.
(WebCore::InspectorTimelineAgent::willCallFunction): Fix the call stack depth management.
(WebCore::InspectorTimelineAgent::didCallFunction):
(WebCore::InspectorTimelineAgent::willEvaluateScript):
(WebCore::InspectorTimelineAgent::didEvaluateScript):
(WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
* inspector/InspectorTimelineAgent.h:

Source/WebInspectorUI:

* UserInterface/Test.html: Add missing include for ScopeChainNode.js.

LayoutTests:

Add a test to see that script timeline records contain profiles even when
the debugger pauses during timeline capturing.

* inspector/timeline/debugger-paused-while-recording-expected.txt: Added.
* inspector/timeline/debugger-paused-while-recording.html: Added.
* inspector/timeline/resources/timeline-helper.js: Added.
(callFunction):
(hook):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (173991 => 173992)


--- trunk/LayoutTests/ChangeLog	2014-09-26 02:20:05 UTC (rev 173991)
+++ trunk/LayoutTests/ChangeLog	2014-09-26 02:29:50 UTC (rev 173992)
@@ -1,5 +1,21 @@
 2014-09-25  Brian J. Burg  <[email protected]>
 
+        Web Inspector: FunctionCall timeline records omit profile data if the debugger has paused
+        https://bugs.webkit.org/show_bug.cgi?id=136805
+
+        Reviewed by Timothy Hatcher.
+
+        Add a test to see that script timeline records contain profiles even when
+        the debugger pauses during timeline capturing.
+
+        * inspector/timeline/debugger-paused-while-recording-expected.txt: Added.
+        * inspector/timeline/debugger-paused-while-recording.html: Added.
+        * inspector/timeline/resources/timeline-helper.js: Added.
+        (callFunction):
+        (hook):
+
+2014-09-25  Brian J. Burg  <[email protected]>
+
         StorageTracker::deleteOrigin being called off the main thread (ASSERTs in inspector/test-harness-trivially-works.html test)
         https://bugs.webkit.org/show_bug.cgi?id=129642
 

Added: trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording-expected.txt (0 => 173992)


--- trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording-expected.txt	2014-09-26 02:29:50 UTC (rev 173992)
@@ -0,0 +1,8 @@
+Testing that profiling data is correctly generated and attached to Timeline records when the debugger pauses and resumes while capturing timelines.
+
+Added a breakpoint inside hook().
+Debugger paused; resuming...
+Debugger resumed; stopping timeline capture.
+Timeline capturing stopped. Inspecting the active recording....
+TimerFired timeline record has profile attached: TRUE
+

Added: trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html (0 => 173992)


--- trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html	2014-09-26 02:29:50 UTC (rev 173992)
@@ -0,0 +1,82 @@
+<!doctype html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
+<script type="text/_javascript_" src=""
+<script type="text/_javascript_" src=""
+<script>
+function installTimer()
+{
+    setTimeout(function() {
+        callFunction(mul, add(1, 3), 3);
+        hook();
+    });
+}
+
+function add(a, b)
+{
+    InspectorTestProxy.addResult("Calling add(): " + a + " + " + b);
+    return a + b;
+}
+
+function mul(a, b)
+{
+    InspectorTestProxy.addResult("Calling mul(): " + a + " * " + b);
+    return a * b;
+}
+
+function test()
+{
+    // First, set up the breakpoint, start timeline capturing, and trigger execution of installTimer().
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, function(event) {
+        var scriptObject = event.data.script;
+
+        if (!/timeline-helper\.js$/.test(scriptObject.url))
+            return;
+
+        var location = scriptObject.createSourceCodeLocation(17, 0);  // Inside timeline-helper.js:hook()
+        var breakpoint = new WebInspector.Breakpoint(location);
+        WebInspector.debuggerManager.addBreakpoint(breakpoint);
+        InspectorTest.addResult("Added a breakpoint inside hook().")
+
+        WebInspector.timelineManager.startCapturing();
+        InspectorTest.evaluateInPage("installTimer()");
+    });
+
+    // Second, the debugger will pause during timeline capturing. Resume, then stop timeline capturing.
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Paused, function(event) {
+            InspectorTest.addResult("Debugger paused; resuming...");
+
+            WebInspector.debuggerManager.resume().then(function() {
+                InspectorTest.addResult("Debugger resumed; stopping timeline capture.");
+                WebInspector.timelineManager.stopCapturing();
+            })
+    });
+
+    // When timeline capturing stops, inspect the resulting timeline records for a profile.
+    WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStopped, function(event) {
+        var recording = WebInspector.timelineManager.activeRecording;
+        var scriptTimeline = recording.timelines.get(WebInspector.TimelineRecord.Type.Script);
+        console.assert(scriptTimeline);
+
+        InspectorTest.addResult("Timeline capturing stopped. Inspecting the active recording....");
+
+        for (var record of scriptTimeline.records) {
+            if (record.eventType !== WebInspector.ScriptTimelineRecord.EventType.TimerFired)
+                continue;
+
+            var result = record.profile ? "TRUE" : "FALSE";
+            InspectorTest.addResult("TimerFired timeline record has profile attached: " + result);
+        }
+
+        InspectorTest.completeTest();
+    });
+
+    InspectorTest.reloadPage();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Testing that profiling data is correctly generated and attached to Timeline records when the debugger pauses and resumes while capturing timelines.</p>
+</body>
+</html>

Added: trunk/LayoutTests/inspector/timeline/resources/timeline-helper.js (0 => 173992)


--- trunk/LayoutTests/inspector/timeline/resources/timeline-helper.js	                        (rev 0)
+++ trunk/LayoutTests/inspector/timeline/resources/timeline-helper.js	2014-09-26 02:29:50 UTC (rev 173992)
@@ -0,0 +1,19 @@
+// WARNING: some tests blindly set breakpoints in this file by line number.
+// So, if you modify the code, make sure to adjust any createSourceCodeLocation
+// calls from tests in the ../ directory. Callsites should include a description
+// of the function/statement to set a breakpoint at, so that it's easy to fix them.
+
+function callFunction(fn)
+{
+    if (!(fn instanceof Function))
+        return;
+
+    var argsArray = Array.prototype.slice.call(arguments);
+    Array.prototype.splice.call(argsArray, 0, 1);
+    fn.call(this, argsArray);
+}
+
+function hook()
+{
+    return 42;
+}

Modified: trunk/Source/WebCore/ChangeLog (173991 => 173992)


--- trunk/Source/WebCore/ChangeLog	2014-09-26 02:20:05 UTC (rev 173991)
+++ trunk/Source/WebCore/ChangeLog	2014-09-26 02:29:50 UTC (rev 173992)
@@ -1,5 +1,28 @@
 2014-09-25  Brian J. Burg  <[email protected]>
 
+        Web Inspector: FunctionCall timeline records omit profile data if the debugger has paused
+        https://bugs.webkit.org/show_bug.cgi?id=136805
+
+        Reviewed by Timothy Hatcher.
+
+        TimelineAgent was mismanaging its call stack depth counter, which caused nested FunctionCall
+        records to steal the parent FunctionCall's captured profile in the child's didCallFunction().
+        Thus, the top FunctionCall node had no profile data and nested FunctionCall nodes each had
+        their own profiles. The frontend expected just one profile, so it didn't show anything when
+        it couldn't be found.
+
+        Test: inspector/timeline/debugger-paused-while-recording.html
+
+        * inspector/InspectorTimelineAgent.cpp: Rename m_recordingProfileDepth to m_callStackDepth.
+        (WebCore::InspectorTimelineAgent::willCallFunction): Fix the call stack depth management.
+        (WebCore::InspectorTimelineAgent::didCallFunction):
+        (WebCore::InspectorTimelineAgent::willEvaluateScript):
+        (WebCore::InspectorTimelineAgent::didEvaluateScript):
+        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+        * inspector/InspectorTimelineAgent.h:
+
+2014-09-25  Brian J. Burg  <[email protected]>
+
         StorageTracker::deleteOrigin being called off the main thread (ASSERTs in inspector/test-harness-trivially-works.html test)
         https://bugs.webkit.org/show_bug.cgi?id=129642
 

Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (173991 => 173992)


--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp	2014-09-26 02:20:05 UTC (rev 173991)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp	2014-09-26 02:29:50 UTC (rev 173992)
@@ -231,19 +231,19 @@
 {
     pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frame);
 
-    if (frame && !m_recordingProfileDepth) {
-        ++m_recordingProfileDepth;
+    if (frame && !m_callStackDepth)
         startProfiling(frame, ASCIILiteral("Timeline FunctionCall"));
-    }
+
+    ++m_callStackDepth;
 }
 
 void InspectorTimelineAgent::didCallFunction(Frame* frame)
 {
-    if (frame && m_recordingProfileDepth) {
-        --m_recordingProfileDepth;
-        ASSERT(m_recordingProfileDepth >= 0);
+    if (frame && m_callStackDepth) {
+        --m_callStackDepth;
+        ASSERT(m_callStackDepth >= 0);
 
-        if (!m_recordingProfileDepth) {
+        if (!m_callStackDepth) {
             if (m_recordStack.isEmpty())
                 return;
 
@@ -405,19 +405,19 @@
 {
     pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, frame);
 
-    if (frame && !m_recordingProfileDepth) {
-        ++m_recordingProfileDepth;
+    if (frame && !m_callStackDepth) {
+        ++m_callStackDepth;
         startProfiling(frame, ASCIILiteral("Timeline EvaluateScript"));
     }
 }
 
 void InspectorTimelineAgent::didEvaluateScript(Frame* frame)
 {
-    if (frame && m_recordingProfileDepth) {
-        --m_recordingProfileDepth;
-        ASSERT(m_recordingProfileDepth >= 0);
+    if (frame && m_callStackDepth) {
+        --m_callStackDepth;
+        ASSERT(m_callStackDepth >= 0);
         
-        if (!m_recordingProfileDepth) {
+        if (!m_callStackDepth) {
             if (m_recordStack.isEmpty())
                 return;
 
@@ -691,10 +691,10 @@
     , m_pageAgent(pageAgent)
     , m_scriptDebugServer(nullptr)
     , m_id(1)
+    , m_callStackDepth(0)
     , m_maxCallStackDepth(5)
     , m_inspectorType(type)
     , m_client(client)
-    , m_recordingProfileDepth(0)
     , m_enabled(false)
     , m_enabledFromFrontend(false)
 {

Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (173991 => 173992)


--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.h	2014-09-26 02:20:05 UTC (rev 173991)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.h	2014-09-26 02:29:50 UTC (rev 173992)
@@ -279,13 +279,13 @@
     Vector<TimelineRecordEntry> m_recordStack;
 
     int m_id;
+    int m_callStackDepth;
     int m_maxCallStackDepth;
     InspectorType m_inspectorType;
     InspectorClient* m_client;
 
     Vector<TimelineRecordEntry> m_pendingConsoleProfileRecords;
 
-    int m_recordingProfileDepth;
     bool m_enabled;
     bool m_enabledFromFrontend;
 };

Modified: trunk/Source/WebInspectorUI/ChangeLog (173991 => 173992)


--- trunk/Source/WebInspectorUI/ChangeLog	2014-09-26 02:20:05 UTC (rev 173991)
+++ trunk/Source/WebInspectorUI/ChangeLog	2014-09-26 02:29:50 UTC (rev 173992)
@@ -1,5 +1,14 @@
 2014-09-25  Brian J. Burg  <[email protected]>
 
+        Web Inspector: FunctionCall timeline records omit profile data if the debugger has paused
+        https://bugs.webkit.org/show_bug.cgi?id=136805
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Test.html: Add missing include for ScopeChainNode.js.
+
+2014-09-25  Brian J. Burg  <[email protected]>
+
         Web Inspector: sort probe details sidebar sections by source code location string
         https://bugs.webkit.org/show_bug.cgi?id=137080
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (173991 => 173992)


--- trunk/Source/WebInspectorUI/UserInterface/Test.html	2014-09-26 02:20:05 UTC (rev 173991)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html	2014-09-26 02:29:50 UTC (rev 173992)
@@ -103,6 +103,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
     <script src=""
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to