Bug 152727 - Web Inspector: Migrate Page Timeline recording to ScriptProfiler
Summary: Web Inspector: Migrate Page Timeline recording to ScriptProfiler
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (show other bugs)
Version: WebKit Nightly Build
Hardware: All All
: P2 Normal
Assignee: Joseph Pecoraro
URL:
Keywords: InRadar
: 151434 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-01-04 21:19 PST by Joseph Pecoraro
Modified: 2016-02-08 11:15 PST (History)
9 users (show)

See Also:


Attachments
[PATCH] Work In Progress (31.23 KB, patch)
2016-01-04 21:20 PST, Joseph Pecoraro
no flags Details | Formatted Diff | Diff
[PATCH] Proposed Fix (52.34 KB, patch)
2016-01-06 14:43 PST, Joseph Pecoraro
no flags Details | Formatted Diff | Diff
[IMAGE] After (268.59 KB, image/png)
2016-01-06 14:45 PST, Joseph Pecoraro
no flags Details
[PATCH] Proposed Fix (52.74 KB, patch)
2016-01-06 14:58 PST, Joseph Pecoraro
bburg: review+
bburg: commit-queue-
Details | Formatted Diff | Diff
[PATCH] Proposed Fix (54.71 KB, patch)
2016-01-08 11:03 PST, Joseph Pecoraro
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph Pecoraro 2016-01-04 21:19:09 PST
* SUMMARY
Migrate Page Timeline recording to ScriptProfiler.

* NOTES
- Use the ScriptProfiler domain in Page Timeline recordings.
Comment 1 Radar WebKit Bug Importer 2016-01-04 21:19:21 PST
<rdar://problem/24052220>
Comment 2 Joseph Pecoraro 2016-01-04 21:20:38 PST
Created attachment 268261 [details]
[PATCH] Work In Progress

This was a very rough work in progress that got things working with some debugging still left in to play with. The actual patch will likely be much smaller, but I wanted to get this up tonight so I didn't forget.
Comment 3 Joseph Pecoraro 2016-01-06 14:43:18 PST
Created attachment 268412 [details]
[PATCH] Proposed Fix
Comment 4 Joseph Pecoraro 2016-01-06 14:45:35 PST
Created attachment 268413 [details]
[IMAGE] After

This shows a Script & Events TimelineView after moving it to ScriptProfiler.

Note that Safari evaluates some scripts in the page via API, and those now show up with the "API Script Evaluation" look.

After this change the frontend continues to update the Graph / Overview views during recording, but does not update the TimelineView / DataGrid until recording stops. I'm putting off re-working that UI until a larger Timelines UI modification.
Comment 5 Joseph Pecoraro 2016-01-06 14:58:44 PST
Created attachment 268418 [details]
[PATCH] Proposed Fix

Adds a test for EventDispatch.
Comment 6 Saam Barati 2016-01-06 18:59:56 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:354
> +            var record;

maybe "let"?

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:400
> +            var record;

maybe "let"?
Comment 7 Joseph Pecoraro 2016-01-06 20:12:11 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:354
>> +            var record;
> 
> maybe "let"?

Unfortunately, this is (already) inside of a switch case. So it gets tricky, and just using var was stylistically simpler. I could go all the way to the top and do a `let record` once though. Anyone have style opinions?
Comment 8 BJ Burg 2016-01-06 23:37:17 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

Looks pretty close to being ready. I will take a look at the record merging code when I have some more coffee in my brain.

> LayoutTests/inspector/script-profiler/event-type-Other.html:6
> +function triggerScriptEvalution() {

Nit: 'evaluation'

> Source/WebCore/ChangeLog:7
> +

Please add the "why do we want to do this?" rationale here, for people besides you and me.

> Source/WebCore/ChangeLog:29
> +        These were nearly all already classified for the Timeline, we added

Nit: grammar (Timeline, we added)

> Source/WebCore/ChangeLog:40
> +        TimelineAgent no longer needs to start/stop the Legacy Profiler

Wohoo!

> Source/WebCore/bindings/js/JSMutationCallback.cpp:93
>      InspectorInstrumentation::didCallFunction(cookie, context);

Now that this instrumentation doesn't have anything to do with profiling, maybe we could come up with a better name. didExecuteCallback? It seems to always be some sort of callback from native DOM code.

> Source/WebInspectorUI/ChangeLog:10
> +        New [S] image for API initiated script evaluates.

Nit: 'evaluations'

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:45
> +        this._hasWrappedScriptProfileRecords = WebInspector.debuggableType !== WebInspector.DebuggableType.JavaScript;

Seems awkward as an property, can't it just be a getter? Actually, it's only used in one place, so just inline it.

>>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:354
>>> +            var record;
>> 
>> maybe "let"?
> 
> Unfortunately, this is (already) inside of a switch case. So it gets tricky, and just using var was stylistically simpler. I could go all the way to the top and do a `let record` once though. Anyone have style opinions?

Meh, let's not get carried away.

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:650
> +    _scriptProfilerTypeToScriptTimelineRecordType(type)

This could be a static method.

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:657
> +        case ScriptProfilerAgent.EventType.Other:

So, the frontend doesn't distinguish script evaluations from function callbacks? I thought it did.. or is it disambiguated based on context/parent record?

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:677
> +        if (type !== ScriptProfilerAgent.EventType.Other)

I would add a comment here to clarify what we do with EventType.Other, in case it isn't obvious locally.

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:683
> +        console.assert(!this._webScriptProfileRecordWrappers || this._scriptProfileRecords.length >= this._webScriptProfileRecordWrappers.length);

I don't like Wrappers in the name because they are actual profile records, not some other type of wrapper object. Maybe this._placeholderScriptProfileRecords? this._unmergedScriptProfileRecords? this._scriptProfileRecordsWithPendingPayloads?

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:710
> +        let recordContainsRecord = function(record1, record2) {

recordEnclosesRecord?

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:719
> +            // FIXME: Backend should just not send nested profilable things?

...what's the test case for this?

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:734
> +                // FIXME: Backend should better wrap each script execution.

...oh, I see. Yuck!

> Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js:811
> +WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol = Symbol("supress-filtering");

typo: 'suppress'
Comment 9 BJ Burg 2016-01-07 10:58:09 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

r=me, but please post another version of the patch.

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:709
> +        let nextScriptProfilerRecord = nextRecord.bind(null, this._scriptProfileRecords);

My intuition would be to call these 'nextWebTimelineRecord' and 'nextSamplePayloadRecord', but it's also fine as-is once the names are memorized.

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:710
>> +        let recordContainsRecord = function(record1, record2) {
> 
> recordEnclosesRecord?

recordsHaveParentChildRelationship?

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:734
>> +                // FIXME: Backend should better wrap each script execution.
> 
> ...oh, I see. Yuck!

Please file a bug for this FIXME.

> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:757
> +        // NOTE: Skipping the remaining ScriptProfiler events to match the current UI for handling Timeline records.

What would these unassociated events correspond to? API records that happened to occur after the last Web Timeline Record? Please add a FIXME if its something we plan to fix.
Comment 10 Joseph Pecoraro 2016-01-07 11:37:24 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:650
>> +    _scriptProfilerTypeToScriptTimelineRecordType(type)
> 
> This could be a static method.

I never know when to make it static and when not to. Is there a good reason to go one way or the other? We do this in a lot of agents and its been kind of different each time.

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:657
>> +        case ScriptProfilerAgent.EventType.Other:
> 
> So, the frontend doesn't distinguish script evaluations from function callbacks? I thought it did.. or is it disambiguated based on context/parent record?

In Page inspection it happens based on the parent record. But only for "Other" evaluations.

The API / Microtask evaluations will always stand on their own.

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:719
>> +            // FIXME: Backend should just not send nested profilable things?
> 
> ...what's the test case for this?

<script>document.write("<script src="..."><\/script>");</script>

>>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:734
>>> +                // FIXME: Backend should better wrap each script execution.
>> 
>> ...oh, I see. Yuck!
> 
> Please file a bug for this FIXME.

This case, I believe, is a Mutation Observer microtask firing at the end of script evaluation checkpoint, which happens before the Timeline completes the ScriptEvaluated record.

<script>
var observer = new MutationObserver(function(mutations) {
    sleepAndLog("MutationObserver callback");
}); 
var config = { attributes: true, childList: true, characterData: true };
observer.observe(document.body, config);
document.body.appendChild(document.createElement("span"));
</script>

>> Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js:757
>> +        // NOTE: Skipping the remaining ScriptProfiler events to match the current UI for handling Timeline records.
> 
> What would these unassociated events correspond to? API records that happened to occur after the last Web Timeline Record? Please add a FIXME if its something we plan to fix.

They would correspond to Web Timeline Records, but (currently) we drop the Web Timeline Records on the floor when the frontend can't keep up with ingesting them.

This is what happens when you record cnn.com, and the graphs get way behind the recording, and you manually stop the recording. The frontend receives all the records for the time between the lagging graphs and current time, but it drops them on the floor. Here we are matching that UI and dropping the ScriptProfiler events that would correspond to those Web Timeline Records and drops them on the floor. My goal is to eliminate this issue.

>> Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js:811
>> +WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol = Symbol("supress-filtering");
> 
> typo: 'suppress'

lol, how did I miss that, its on the left!
Comment 11 BJ Burg 2016-01-07 12:53:14 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

> LayoutTests/inspector/script-profiler/event-type-Other-expected.txt:13
> +PASS: Event type should be Other.

Test, please ignore this comment.
Comment 12 BJ Burg 2016-01-07 12:54:10 PST
Comment on attachment 268418 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=268418&action=review

> LayoutTests/inspector/script-profiler/event-type-Other-expected.txt:14
> +ScriptProfiler.trackingUpdate

Another test, please ignore.
Comment 13 Joseph Pecoraro 2016-01-08 11:03:27 PST
Created attachment 268553 [details]
[PATCH] Proposed Fix
Comment 14 BJ Burg 2016-01-11 14:45:19 PST
Comment on attachment 268553 [details]
[PATCH] Proposed Fix

r=me, delicious!
Comment 15 WebKit Commit Bot 2016-01-11 15:34:59 PST
Comment on attachment 268553 [details]
[PATCH] Proposed Fix

Clearing flags on attachment: 268553

Committed r194871: <http://trac.webkit.org/changeset/194871>
Comment 16 WebKit Commit Bot 2016-01-11 15:35:03 PST
All reviewed patches have been landed.  Closing bug.
Comment 17 Joseph Pecoraro 2016-02-08 11:15:41 PST
*** Bug 151434 has been marked as a duplicate of this bug. ***