Commit ffcaf3c
Fix identifying user instructions in LowerAllocObject
Summary:
`LowerAllocObject` performs a step where it identifies all of the
user instructions of a given `allocInst_` that are `StoreOwnProperty`
instructions, with the intention of merging some of them into a
serialised buffer.
However, this selection is not sufficiently targeted. Specifically,
an allocated object may be used by a `StoreOwnProperty` instruction
that is storing to a different object. Consider:
```
var x = {a: 5, b: 6}
var y = {e:5, f: x, g:6}
```
Here, we generate 3 `StoreOwnProperty` instructions that use `x`, 2
of which set the properties, and the third one assigns `x` to `y.f`.
That last instruction should never be considered for serialisation
into the buffer, since it is completely unrelated to initialising
`x`.
Our current code doesn't check for this, and does shortlist that last
instruction for serialisation. The only reason it doesn't end up
actually serialising it, is because of how it ends up interacting
with `LowerAllocObject::estimateBestNumElemsToSerialize`.
Specifically, because the `StoredValue` of the last instruction is an
object, it is not optimal to include it.
If we just change the return value of
`estimateBestNumElemsToSerialize` to instead be `curSize`, then the
above code generates the following IR:
```
%0 = HBCLoadConstInst 6 : number
%1 = HBCAllocObjectFromBufferInst 3 : number, "e" : string, 5 : number
%2 = HBCAllocObjectFromBufferInst 2 : number, "a" : string, 5 : number, "b" : string, 6 : number, "f" : string, null : null
%3 = StorePropertyInst %2 : object, %1 : object, "f" : string
%4 = StoreNewOwnPropertyInst %0 : number, %1 : object, "g" : string, true : boolean
```
In that, we can see that `x` now incorrectly has an `f` property.
This also breaks populating the `f` property on `y`, because it
does not emit the placeholder for `f`, which means that we are
not guaranteed that `f` is stored as an own property of `y`.
Less importantly this also blocks `y` from being optimised into a
serialised buffer, because the lowering of `x` changed the
`StoreOwnPropertyInst` into a `StorePropertyInst`.
Theoretically, there could be well formed IR that can cause this to
generate much more incorrect code. However, since we only generate
`StoreOwnProperty` from object and array literals, I couldn't think
of a way to generate an example to demonstrate this.
Reviewed By: tmikov
Differential Revision: D29002692
fbshipit-source-id: dd18b98a35fe527aa3470c0f950852abf29ebc811 parent 9531ab3 commit ffcaf3c
1 file changed
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
250 | 250 | | |
251 | 251 | | |
252 | 252 | | |
253 | | - | |
254 | | - | |
255 | | - | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
256 | 256 | | |
257 | 257 | | |
258 | 258 | | |
| |||
0 commit comments