Closed Bug 1363054 Opened 7 years ago Closed 7 years ago

Make type monitor stubs work with unknown objects/values

Categories

(Core :: JavaScript Engine: JIT, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla55
Performance Impact high
Tracking Status
firefox55 --- fixed

People

(Reporter: jandem, Assigned: jandem)

References

(Blocks 1 open bug)

Details

Attachments

(5 files)

Attached file Micro benchmark
Currently we attach up to 8 monitor stubs and give up, but this hurts us on polymorphic code because we end up with (relatively slow) DoTypeMonitorFallback calls. If the TypeSet is unknown() or unknownObject() we should just attach a single stub to handle these cases.

I have some patches to fix this. It improves the silly micro-benchmark I'm attaching from 55 ms to 15 ms with --no-ion, and when I load Gmail it reduces the number of DoTypeMonitorFallback calls from > 230,000 to less than 40,000, so it seems pretty effective.

After this we should do something similar for the type update stubs.
The call and spread-call ICs were calling addMonitorStubForValue twice, so let's remove one of these calls.
Attachment #8865474 - Flags: review?(tcampbell)
At some point we used Baseline's GetProp IC in Ion (the shared stubs mechanism), but we no longer do that and we don't have any shared stubs that use type monitoring. So now that the type monitoring code is Baseline-specific again, we can simplify/optimize it a bit.
Attachment #8865483 - Flags: review?(tcampbell)
Comment on attachment 8865474 [details] [diff] [review]
Part 1 - Remove unnecessary addMonitorStubForValue calls

Review of attachment 8865474 [details] [diff] [review]:
-----------------------------------------------------------------

Ah, looking at the history, this looks like an accidental merge issue. The patch on bug 836064 didn't quite apply correctly.

Good find.
Attachment #8865474 - Flags: review?(tcampbell) → review+
The next patch wants to have access to the StackTypeSet in addMonitorStubForValue - in order to check whether it's unknown() or unknownObject() - so here's some plumbing to do that.

I also added a more-optimized version of TypeScript::Monitor that takes the StackTypeSet* so we don't have to call TypeScript::BytecodeTypes twice.
Attachment #8865493 - Flags: review?(tcampbell)
If the TypeSet is unknown() we can now attach a TypeMonitor_AnyValue stub.

If the TypeSet is unknownObject(), we can attach a TypeMonitor_PrimitiveSet stub that works with objects.
Attachment #8865499 - Flags: review?(tcampbell)
Comment on attachment 8865483 [details] [diff] [review]
Part 2 - Remove shared stubs code

Review of attachment 8865483 [details] [diff] [review]:
-----------------------------------------------------------------

LGTM
Attachment #8865483 - Flags: review?(tcampbell) → review+
Comment on attachment 8865493 [details] [diff] [review]
Part 3 - Pass StackTypeSet* to addMonitorStubForValue

Review of attachment 8865493 [details] [diff] [review]:
-----------------------------------------------------------------

Sure. Makes sense as plumbing.
Attachment #8865493 - Flags: review?(tcampbell) → review+
Comment on attachment 8865499 [details] [diff] [review]
Part 4 - Attach generalized stubs if unknown/unknownObject

Review of attachment 8865499 [details] [diff] [review]:
-----------------------------------------------------------------

Makes sense to me.

::: js/src/jit/SharedIC.cpp
@@ +2195,5 @@
> +    if (types->unknown()) {
> +        // The TypeSet got marked as unknown so attach a stub that always
> +        // succeeds.
> +
> +        // Check for existing TypeMonitor_AnyValue stubs.

Can this be an assertion, or do things likes DoCallFallback cause us to run addMonitorStubForValue even with AnyValue stub already in place.
Attachment #8865499 - Flags: review?(tcampbell) → review+
Whiteboard: [qf]
Thanks for the quick reviews.

(In reply to Ted Campbell [:tcampbell] from comment #8)
> Can this be an assertion, or do things likes DoCallFallback cause us to run
> addMonitorStubForValue even with AnyValue stub already in place.

Yes, exactly.
Pushed by jandemooij@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/10acb957ba60
part 1 - Remove redundant addMonitorStubForValue calls. r=tcampbell
https://hg.mozilla.org/integration/mozilla-inbound/rev/a2281e684a80
part 2 - Remove some shared stubs code that's no longer needed. r=tcampbell
https://hg.mozilla.org/integration/mozilla-inbound/rev/4d383642cf05
part 3 - Pass StackTypeSet* to addMonitorStubForValue. r=tcampbell
https://hg.mozilla.org/integration/mozilla-inbound/rev/eade14aad3f7
part 4 - Attach generalized type monitor stubs for unknown/unknownObject type sets. r=tcampbell
Taking a look at it, I see that if I run the build artifact before and after that the after is certainly broken. Without running the test or even using -marionette flag, I get problems. This also persists when the JITs are turned off (thus negating this patch). I see spinner on startup and sometimes a hidden window in taskbar that is white with native close buttons.

This failure looks like a compiler problem or existing bug affected by memory/symbol layout.
Took another look at it. I'm suspicious this is just an intermittent that got unlucky with compiler or timing. Builds after a few commits and before bailout don't have the glitchy behavior I saw.

A few experiments in progress:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=96f97a36071993185ba4d9f7a3f2116d6207641a  // Rebuild the same tree
https://treeherder.mozilla.org/#/jobs?repo=try&revision=82a5795ade97fc5cea3dcc7c81db9fe101dcc3b0  // Rebuild with different unified source bundling
https://treeherder.mozilla.org/#/jobs?repo=try&revision=97e37ef615e619f2eac1f03b4de1b52548319d1b  // Run Mn-e10s on a later commit but before the backout
Ted, thanks a lot for looking at this!

I agree the failure is pretty weird. I'm going to bisect the patches on Try so we can land the ones that are okay and narrow it down more.
If you are good at windows debugging, take a look at that win64 build on a local machine. It is consistently unable to start without glitches (no flags or tests. Just open with a blank profile). Even with the JITs pref'd off. The first tab fails to render at all.
So, getting back to this, it looks like the badness starts with part 3. I'll push parts 1 and 2 since they're strict improvements and will investigate more next week.
Pushed by jandemooij@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/d2730adba4bc
part 1 - Remove redundant addMonitorStubForValue calls. r=tcampbell
https://hg.mozilla.org/integration/mozilla-inbound/rev/131c75bd410c
part 2 - Remove some shared stubs code that's no longer needed. r=tcampbell
Flags: needinfo?(jdemooij)
Keywords: leave-open
Flags: needinfo?(jdemooij)
Blocks: 1351769
Whiteboard: [qf] → [qf:p1]
Kannan had some fancytalk reasons why this should be p1.
I'm doing some Try pushes now. Removing changes from part 3 until I have a minimal patch that triggers the problem. Part 3 is not very big so hopefully we'll have more information soon.
It seems to be an MSVC compiler bug, triggered by the DoTypeMonitorFallback changes. Making small, almost-no-op modifications to that part of the patch makes it green or orange on Try.

I'll see if I can rewrite this code in a way that makes MSVC happy.
Pushed by jandemooij@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/d45d197ffb05
part 3 - Pass StackTypeSet* to addMonitorStubForValue. r=tcampbell
(In reply to Pulsebot from comment #22)
> Pushed by jandemooij@gmail.com:
> https://hg.mozilla.org/integration/mozilla-inbound/rev/d45d197ffb05
> part 3 - Pass StackTypeSet* to addMonitorStubForValue. r=tcampbell

Fingers crossed this one will stick. I rewrote DoTypeMonitorFallback a bit in a way that doesn't make Mn-e10s angry on Try. It's pretty weird, I tried some simpler workarounds but they didn't help - sometimes opt builds were green but then debug builds showed the problem...
Strange.. Did you keep any of those broken debug builds? It would be interesting to compare obj files and determine if miscompile is restricted to DoTypeMonitorFallback, or whether there is other fallout that may be pre-existing.
(In reply to Ted Campbell [:tcampbell] from comment #24)
> Strange.. Did you keep any of those broken debug builds? It would be
> interesting to compare obj files and determine if miscompile is restricted
> to DoTypeMonitorFallback, or whether there is other fallout that may be
> pre-existing.

Yeah it's strange only this test fails on Win64 even though this function is pretty hot - could be a compiler bug affecting code generated elsewhere. I may take a closer look at it but I've already spent a lot of time on this and I have a bunch of other bugs on my plate, so I don't know if it's worth it...
I noticed the problem manifesting as content processes on start-up being weird and the Mn test only noticed because it wasn't able to shutdown browser properly. I am suspicious other code might be messed up by the compiler.

Maybe if you could link up the version that causes debug to fail. We can look at some point later. Probably not worth you spending more time on though.
Pushed by jandemooij@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/c132697561b0
part 4 - Attach generalized type monitor stubs for unknown/unknownObject type sets. r=tcampbell
(In reply to Ted Campbell [:tcampbell] from comment #26)
> Maybe if you could link up the version that causes debug to fail.

See this Try push for instance: https://treeherder.mozilla.org/#/jobs?repo=try&revision=6d0f0f5e82972f4eb8e5a53adcc340204d7e8755&group_state=expanded
Flags: needinfo?(jdemooij)
Keywords: leave-open
https://hg.mozilla.org/mozilla-central/rev/c132697561b0
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
For posterity, this was at least a 6% improvement on the jslint benchmark on AWFY and there were some other improvements elsewhere.
Performance Impact: --- → P1
Whiteboard: [qf:p1]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: