Closed
Bug 814177
Opened 12 years ago
Closed 12 years ago
IonMonkey: InstanceOf codegen uses 2 consecutive calls.
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
FIXED
mozilla20
Tracking | Status | |
---|---|---|
firefox17 | --- | unaffected |
firefox18 | + | fixed |
firefox19 | + | fixed |
firefox20 | + | fixed |
firefox-esr10 | --- | unaffected |
firefox-esr17 | --- | unaffected |
People
(Reporter: bhackett1024, Assigned: nbp)
References
(Depends on 1 open bug)
Details
(Keywords: sec-critical, Whiteboard: [adv-main18-])
Attachments
(1 file)
15.81 KB,
patch
|
dvander
:
review+
akeybl
:
approval-mozilla-aurora+
akeybl
:
approval-mozilla-beta+
|
Details | Diff | Splinter Review |
The live registers in a safepoint include those which are live after the instruction ends (excluding the outputs of the instruction). HasInstance uses a GetProperty cache followed by a HasInstance test, where both involve an OOL VM call which uses the instruction's safepoint. If inputs to the safepoint are in registers (which LSRA does not seem to do in this case, but other register allocators could), they are not required to be in the live registers, but if the GetPropertyCache call is then made it will not restore the input registers, and incorrect values can flow into the second HasInstance call and cause it to behave incorrectly.
Assignee | ||
Comment 1•12 years ago
|
||
A simple rule:
- One runtime call at most per codegen.
Failing to respect this rule might have plenty of bad consequences such as bad marking, bad invalidation or bad bailouts.
No ->rejoin() should appear before an ->entry(), Good catch.
Assignee | ||
Comment 2•12 years ago
|
||
This is not the same as Bug 814396 as CharCodeAt as only one call site.
The problem with multiple calls per codegen is that the backward patch made during the invalidation might *cause random code to be executed* in the rare case where one of the call is calling the same function and enter the other branch causing an invalidation.
Group: core-security
Severity: normal → critical
status-firefox18:
--- → affected
status-firefox19:
--- → affected
status-firefox20:
--- → affected
tracking-firefox18:
--- → ?
tracking-firefox19:
--- → ?
tracking-firefox20:
--- → ?
Keywords: sec-critical
Assignee | ||
Updated•12 years ago
|
Assignee: general → nicolas.b.pierron
Status: NEW → ASSIGNED
Summary: IonMonkey: InstanceOf does not respect safepoint info correctly → IonMonkey: InstanceOf codegen uses 2 consecutive calls.
What plan of attack are you considering? I was thinking we'd have a specialized IC or decomposed opcodes (that might be tricky), but I think Brian also had a plan to use more type information.
Assignee | ||
Comment 4•12 years ago
|
||
My plan is to split it in to different codegen, such as we can get an OSIpoint in the middle. The problem is that this solution is not a good solution as it might cause a double execution effect if we do not resume the second part of the instanceOf operation.
Another solution would be to produce an out-of-line path used in case of invalidation where a non-backward patched call can be used, but this sounds too hacky to me.
Ideally we just wouldn't have that GetPropertyCache sitting in the middle. Either the whole thing could be a specialized IC, or maybe we can inline more aggressively with good type information.
Assignee | ||
Comment 6•12 years ago
|
||
Bug introduced while fixing Bug 794947, and later modified by Bug 803730 for fixing another issue on the same code.
(In reply to David Anderson [:dvander] from comment #5)
> Ideally we just wouldn't have that GetPropertyCache sitting in the middle.
> Either the whole thing could be a specialized IC, or maybe we can inline
> more aggressively with good type information.
I agree, after looking more at the code, the best would be to have an inline cache for it. More type information does not solve the problem as we have to be able to compile without any type information to handle non-visited branches.
Blocks: 794947
Assignee | ||
Comment 7•12 years ago
|
||
The faulty function CodeGenerator::emitInstanceOf implements fun_hasInstance (sadly not named in any comments near the function) and fallback to the VM function call if this is not a function. Which means that the GetProperty IC which is used is constantly used with a function object. The GetProperty is done to recover the prototype of the function object. The second loop inline the function IsDelegate and fallback to the VM function call in case the getProto is made on a Proxy.
So,
1/ The path which test that we obtain an object at the end of the getProperty should raise an exception instead of jumping to the done label with a bad output. (see fun_hasInstance)
2/ Calling the VM function as a fallback in the IsDelegate assembly version is wrong because it cause a re-evaluation of the GetProperty.
I suggest to do 2 fixes:
1/ Make an IC which do a GetProperty (of .prototype) & IsDelegate, which means that the loop unrolling bind-links (which fallback on the ool call) can reduce the number of inputs of the cache. [fix this bug]
2/ Add an unconditional halt to the reverse patch mechanism to prevent random code execution (cause a controlled crash) and check that there is enough space since the last masm.bind to prevent erasing a path from a return value to the osi point. (assuming we don't generate dead code this should be enough) [prevent useful exploit of this kind of bug]
Reporter | ||
Comment 8•12 years ago
|
||
Why not just make instanceof a VM call in cases where type information is bad? I'm working right now on an optimized instanceof that bakes in knowledge of rhs-is-a-function and the rhs's .prototype (will file that in a separate bug). Skimming, that should handle every instanceof in the benchmarks (basically just earley-boyer), and all the uses of instanceof in jQuery and Prototype.js except one which the existing GetPropertyCache mechanism probably doesn't handle well either. Also, bug 717466 comment 3 suggests there is relatively little to be gained from the assembly version (so little static information is being baked in), though I don't know how different that is from what's in the tree.
Reporter | ||
Comment 9•12 years ago
|
||
Bug 814861 has the type specialized paths for instanceof. Also, given how awful v8 is at polymorphic instanceof (even with statically known rhs, see bug 814861), I think it should be fine if Ion just does a stub call if rhs is not statically known.
Assignee | ||
Comment 10•12 years ago
|
||
(In reply to Brian Hackett (:bhackett) from comment #8)
> Why not just make instanceof a VM call in cases where type information is
> bad?
Sounds like a good solution if we don't regress dromaeo or other benchmarks otherwise we would have to backport the type-specialized version too.
Assignee | ||
Comment 11•12 years ago
|
||
As bhackett mentionned, Bug 814861 is supposed to cover common patterns where the rhs can be assumed as a constant. Still when the rhs has never been evaluated before, we have to use a generic instanceOf implementation.
This patch use a callVM to handle all cases of InstanceOf via the corresponding interpreter function. This will cause a slow down in our IonMonkey implementation, but will provide a fault-free solution while waiting for Bug 814861.
If there is any performance slow down, we should think of backporting Bug 814861 patch, which does not have the issue reported in this bug because the getProperty is done while building the IonGraph.
Note: The test case for Bug 794947 should be modify to work with --no-jm, because this patch will be used by the eager compilation and would mute the test case for testing Bug 814861.
Attachment #684896 -
Flags: review?(dvander)
Updated•12 years ago
|
Comment on attachment 684896 [details] [diff] [review]
Use callVM to implement all cases of InstanceOf.
Review of attachment 684896 [details] [diff] [review]:
-----------------------------------------------------------------
Good to get rid of this code... r=me with some renamings now that bhackett's patch landed:
MInstanceOf -> MCallInstanceOf
LInstanceOfV -> LCallInstanceOf
MInstanceOfTyped -> MInstanceOf
LInstanceOfTyped -> LInstanceOf
Attachment #684896 -
Flags: review?(dvander) → review+
Assignee | ||
Comment 13•12 years ago
|
||
Flags: in-testsuite-
Comment 14•12 years ago
|
||
FYI this causes a 3% regression in v8-raytrace
Comment 15•12 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla20
Assignee | ||
Comment 16•12 years ago
|
||
Comment on attachment 684896 [details] [diff] [review]
Use callVM to implement all cases of InstanceOf.
[Approval Request Comment]
Bug caused by (feature/regressing bug #):
Bug 794947
User impact if declined:
Random code execution / crash
Testing completed (on m-c, etc.):
see comment 15.
Risk to taking this patch (and alternatives if risky):
Possible performance regressions with IonMonkey instanceof usage. In such case we can backport Bug 814861 too which should handle most of the common use cases without having any similar issue as the previous implementation.
String or UUID changes made by this patch:
N/A
Attachment #684896 -
Flags: approval-mozilla-beta?
Attachment #684896 -
Flags: approval-mozilla-aurora?
Updated•12 years ago
|
status-firefox-esr10:
--- → unaffected
status-firefox17:
--- → unaffected
status-firefox-esr17:
--- → unaffected
Comment 17•12 years ago
|
||
Comment on attachment 684896 [details] [diff] [review]
Use callVM to implement all cases of InstanceOf.
[Triage Comment]
To prevent a FF18 sec-critical regression.
Attachment #684896 -
Flags: approval-mozilla-beta?
Attachment #684896 -
Flags: approval-mozilla-beta+
Attachment #684896 -
Flags: approval-mozilla-aurora?
Attachment #684896 -
Flags: approval-mozilla-aurora+
Assignee | ||
Comment 18•12 years ago
|
||
status-firefox-esr10:
unaffected → ---
status-firefox17:
unaffected → ---
status-firefox-esr17:
unaffected → ---
Updated•12 years ago
|
Updated•12 years ago
|
status-firefox-esr10:
--- → unaffected
status-firefox17:
--- → unaffected
status-firefox-esr17:
--- → unaffected
Assignee | ||
Comment 19•12 years ago
|
||
Comment 20•12 years ago
|
||
On branches, this is a 5% hit or so on V8-v7 on Mac. Is that expected?
Good catch, Boris. This patch should have gone in with or before bug 814861.
Assignee | ||
Comment 22•12 years ago
|
||
(In reply to Boris Zbarsky (:bz) from comment #20)
> On branches, this is a 5% hit or so on V8-v7 on Mac. Is that expected?
Yes, as mentioned in comment 16.
> Risk to taking this patch (and alternatives if risky):
> Possible performance regressions with IonMonkey instanceof usage. In such
> case we can backport Bug 814861 too which should handle most of the common
> use cases without having any similar issue as the previous implementation.
(In reply to David Anderson [:dvander] from Bug 814861 comment #9)
> Since bug 814177 regressed beta performance significantly, we should either
> back that out or take this on beta. I think this is low risk enough - what
> do you think, Brian?
Doing a backout of this patch on aurora / beta sounds like a bad solution without a substitute. As you & I are mentioning, Bug 814177 seems like a low risk which does not have any of the bug found on the previous InstanceOf implementation.
Comment 23•12 years ago
|
||
This regressed v8 on Aurora. Intentional?
Regression V8 version 7 decrease 8.73% on Win7 Mozilla-Aurora
----------------------------------------------------------------
Previous: avg 6477.200 stddev 116.582 of 30 runs up to revision bf1ceb185f0c
New : avg 5911.488 stddev 70.268 of 5 runs since revision 5038ad88dabe
Change : -565.712 (8.73% / z=4.852)
Graph : http://mzl.la/YOFzXT
Changeset range: http://hg.mozilla.org/releases/mozilla-aurora/pushloghtml?fromchange=bf1ceb185f0c&tochange=5038ad88dabe
Changesets:
* http://hg.mozilla.org/releases/mozilla-aurora/rev/0c2e87d10933
: Sriram Ramasubramanian <sriram@mozilla.com> - Bug 786982: Add the hiding of close tab, while swiping. r=lucasr a=lsblakk
: http://bugzilla.mozilla.org/show_bug.cgi?id=786982
* http://hg.mozilla.org/releases/mozilla-aurora/rev/5038ad88dabe
: Nicolas B. Pierron <nicolas.b.pierron@mozilla.com> - Bug 814177 - Use a callVM for generic InstanceOf cases. r=dvander a=akeybl
: http://bugzilla.mozilla.org/show_bug.cgi?id=814177
Bugs:
* http://bugzilla.mozilla.org/show_bug.cgi?id=814177
* http://bugzilla.mozilla.org/show_bug.cgi?id=786982 - The user should be able to close the last remaining tab
_______________________________________________
dev-tree-management mailing list
dev-tree-management@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tree-management
Comment 24•12 years ago
|
||
(Same for beta)
Regression V8 version 7 decrease 4.27% on MacOSX 10.7 Mozilla-Beta
---------------------------------------------------------------------
Previous: avg 5573.204 stddev 65.916 of 30 runs up to revision 7d4da1832dcc
New : avg 5334.976 stddev 31.586 of 5 runs since revision 6b8651fe7c5d
Change : -238.228 (4.27% / z=3.614)
Graph : http://mzl.la/RADufY
Changeset range: http://hg.mozilla.org/releases/mozilla-beta/pushloghtml?fromchange=7d4da1832dcc&tochange=6b8651fe7c5d
Changesets:
* http://hg.mozilla.org/releases/mozilla-beta/rev/6b8651fe7c5d
: Nicolas B. Pierron <nicolas.b.pierron@mozilla.com> - Bug 814177 - Use a callVM for generic InstanceOf cases. r=dvander a=akeybl
: http://bugzilla.mozilla.org/show_bug.cgi?id=814177
Bugs:
* http://bugzilla.mozilla.org/show_bug.cgi?id=814177
_______________________________________________
dev-tree-management mailing list
dev-tree-management@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tree-management
Comment 25•12 years ago
|
||
Sorry, didn't read the bug well enough!
Updated•12 years ago
|
Whiteboard: [adv-main17-]
Updated•12 years ago
|
Whiteboard: [adv-main17-] → [adv-main18-]
Updated•12 years ago
|
Group: core-security
You need to log in
before you can comment on or make changes to this bug.
Description
•