Closed
Bug 889986
Opened 11 years ago
Closed 11 years ago
GenerationalGC: ensure that all ArrayBufferObject backing allocations are at least one word
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
mozilla27
People
(Reporter: terrence, Unassigned)
References
Details
Attachments
(1 file, 2 obsolete files)
(deleted),
patch
|
terrence
:
review+
|
Details | Diff | Splinter Review |
We need this word to store the forwarding pointer if the backing slots get put in the nursery. Since malloc isn't going to hand out less than one word anyway, this should not be any additional memory cost. We should also not need to track this size anywhere.
Comment 1•11 years ago
|
||
> Since malloc isn't going to hand out less than one word
Don't be so sure. jemalloc is able to hand out 2-byte and 4-byte allocations, even though this (IIRC) violates the C standard.
(The exception is Linux where we've disabled this capability -- for reasons I can't remember right now -- and the minimum is 8 bytes.)
Comment 2•11 years ago
|
||
Is the answer as simple as never allocating less than sizeof(RelocationOverlay) in Nursery::allocate()?
I checked and this we were not allocating less than this when running jit-tests anyway. But I also couldn't see how ArrayBufferObject managed to allocate from the nursery.
Attachment #813093 -
Flags: review?(terrence)
Comment 3•11 years ago
|
||
qref'd patch this time
Attachment #813093 -
Attachment is obsolete: true
Attachment #813093 -
Flags: review?(terrence)
Attachment #813094 -
Flags: review?(terrence)
Reporter | ||
Comment 4•11 years ago
|
||
Comment on attachment 813094 [details] [diff] [review]
reserve-space-for-forwarding
Review of attachment 813094 [details] [diff] [review]:
-----------------------------------------------------------------
This bug is actually about the slots and elements forwarding pointer, not about RelocationOverlay. The problem here is that Ion will pull out JSObject::{elements|slots} onto the stack or into a register and then hoist them above a minor GC. When we do a minor GC in this situation, if we move an object with inline or nursery allocated slots|elements, then the slots|elements pointer stored on the stack or in a register will be pointing into dead nursery space.
The communication here is a bit hard to follow; it took me awhile to page back in, so let me write it down. When we call MarkRuntime from Nursery::collect, we end up in MarkIonFrame. This function first marks all of the object pointers it knows about. This ends up calling move{Slots|Elements}ToTenured, which calls set{Slots|Elements}ForwardingPointer from [1,2]. These functions write the new malloced pointer into the first word of the inline or nursery storage. When MarkIonFrame finishes marking all objects it knows about, it visits all reserved stack slots and spilled register slots [3] and calls Nursery::forwardBufferPointer on each one. This method checks if the pointer is into the nursery and if it is, reads the first word out of the array (which we wrote the new address into) and writes it back into the slot [4], updating the reference.
1 - http://dxr.allizom.org/mozilla-central/source/js/src/gc/Nursery.cpp#l530 (and some others below)
2 - http://dxr.allizom.org/mozilla-central/source/js/src/gc/Nursery.cpp#l497
3 - http://dxr.allizom.org/mozilla-central/source/js/src/jit/IonFrames.cpp#l828 (and below for stack slots)
4 - http://dxr.allizom.org/mozilla-central/source/js/src/gc/Nursery.cpp#l346
The worrisome case is [1] above: if the array buffer's physical allocation is shorter than 4 bytes on x86 or 8 bytes on x64, then this write will overwrite the buffer.
::: js/src/gc/Nursery.cpp
@@ +97,5 @@
> {
> JS_ASSERT(!runtime()->isHeapBusy());
>
> + /* Ensure there's enough space to replace the contents with a RelocationOverlay. */
> + size = Max(size, sizeof(RelocationOverlay));
Please make this an assertion.
Attachment #813094 -
Flags: review?(terrence)
Comment 5•11 years ago
|
||
So both setElementsForwardingPointer and setSlotsForwarding pointer check there is space before writing the pointer. Is the idea that we should assert before we get to this point?
As far as I can see ArrayBufferObjects are always created with the maximum number of fixed slots so I don't think it's actually a problem right now.
Updated patch to assert in allocate() attached.
Attachment #813094 -
Attachment is obsolete: true
Attachment #813506 -
Flags: review?(terrence)
Reporter | ||
Comment 6•11 years ago
|
||
Comment on attachment 813506 [details] [diff] [review]
assert-space-for-reloc-overlay
Review of attachment 813506 [details] [diff] [review]:
-----------------------------------------------------------------
Excellent, thank you for auditing that! Since it is now known to be safe, please also assert that slot and element allocations are at least sizeof(void*).
Attachment #813506 -
Flags: review?(terrence) → review+
Comment 7•11 years ago
|
||
Comment 8•11 years ago
|
||
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla27
You need to log in
before you can comment on or make changes to this bug.
Description
•