Open
Bug 1291850
Opened 10 years ago
Updated 2 years ago
Inline caches don't guard against JSObject::swap on an object in the middle of a prototype chain
Categories
(Core :: JavaScript Engine: JIT, defect, P3)
Core
JavaScript Engine: JIT
Tracking
()
NEW
People
(Reporter: spinda, Unassigned)
References
(Blocks 1 open bug)
Details
Attachments
(2 files)
This comment https://dxr.mozilla.org/mozilla-central/source/js/src/jit/IonCaches.cpp#412-417 is incorrect - |GeneratePrototypeGuards| doesn't actually do anything to help protect against |JSObject::swap| when generating a cache involving an object within a prototype chain.
Consider the following prototype chain:
+---------------------------+
Object |hasOwnProperty: [function] |
+-------------^-------------+
|
|
+
(...)
+---------------------------+
| | [HTMLHeadingElementPrototype]
+-------------^-------------+
|
|
+-------------+-------------+
x1 | | [HTMLHeadingElement]
+-------------^-------------+
|
|
+-------------+-------------+
x2 | | [Object.create(x1)]
+---------------------------+
|x1| is an |h1| element in the current document and |x2| is an object created with |Object.create(x2)|. If an inline cache is generated to read |x2.hasOwnProperty|, it will emit a shape guard on |x2|, a shape guard on |Object|, and a read.
If a script in an |iframe| within the document then calls |document.adoptNode| on |x1|, |x1| in the original compartment is spliced by |JSObject::swap| with a cross-compartment proxy pointing to |x1| in the |iframe|'s compartment. Then say |iframe|'s script sets |hasOwnProperty| on the swapped-in element to |"blue"|. This shadows |Object.hasOwnProperty|, causing a reshape of |Object| *within the |iframe|'s compartment*, intended to invalidate inline caches reading from it.
We now have:
+--[ iframe's compartment ]------------------------------------------------+
| |
| |
| +---------------------------+ |
| Object |hasOwnProperty: [function] | |
| +-------------^-------------+ |
| | |
| | |
| + |
| |
| (...) |
| |
| +---------------------------+ |
| | | [HTMLHeadingElementPrototype] |
| +-------------^-------------+ |
| | |
| | |
| +-------------+-------------+ |
| |hasOwnProperty: "blue" | [HTMLHeadingElement] |
| +-------------X-------------+ |
| X |
| X |
+-------------------------X------------------------------------------------+
X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+--[ parent's compartment ]----------------------------X-------------------+
| X |
| X |
| +---------------------------+ X |
| x1 | | [Cross-compartment proxy] |
| +-------------^-------------+ |
| | |
| | |
| +-------------+-------------+ |
| x2 | | [Object.create(x1)] |
| +---------------------------+ |
| |
| |
+--------------------------------------------------------------------------+
A subsequent read of |x2.hasOwnProperty| from the parent's compartment should return |"blue"|, from |x1.hasOwnProperty|. However, |Object| within this compartment has *not* been reshaped, so the previously-generated inline cache will check the shape of |x2| (match), check the shape of |Object| (match), and then read |Object.hasOwnProperty|. The code in |GeneratePrototypeGuards| that purports to deal with invalidating the cache in the case of |JSObject::swap| actually has nothing to do with |JSObject::swap|.
The attached mochitest demonstrates the above scenario.
I propose that |JSObject::swap| behave similarly to |SetPropertyByDefining|, which invokes |PurgeScopeChain| to reshape the objects necessary for cache invalidations.
| Reporter | ||
Comment 1•10 years ago
|
||
| Reporter | ||
Updated•10 years ago
|
Assignee: nobody → mismith
Status: NEW → ASSIGNED
Updated•10 years ago
|
Priority: -- → P3
Comment 2•8 years ago
|
||
Just reconfirmed this is still an issue.
FAIL Cache stub correctly handles JSObject::swap in the middle of a proto chain - got function hasOwnProperty() {
[native code]
}, expected "blue"
SimpleTest.is@SimpleTest/SimpleTest.js:312:5
@js/xpconnect/tests/mochitest/test_icswapproto.html:38:7
rval@SimpleTest/SimpleTest.js:146:17
EventHandlerNonNull*this.addLoadEvent@SimpleTest/SimpleTest.js:171:13
@SimpleTest/SimpleTest.js:1444:5
| Reporter | ||
Updated•7 years ago
|
Assignee: lists → nobody
Status: ASSIGNED → NEW
Updated•4 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•