Bug 993768 - Handle TypeArrayObjects when tenuring r=terrence

This commit is contained in:
Jon Coppeard 2014-04-10 13:46:58 +01:00
parent 5b6bf3a4aa
commit dc1acbbbdc
4 changed files with 48 additions and 3 deletions

View File

@ -569,7 +569,7 @@ js::Nursery::moveObjectToTenured(JSObject *dst, JSObject *src, AllocKind dstKind
tenuredSize += moveElementsToTenured(dst, src, dstKind);
if (src->is<TypedArrayObject>())
dst->setPrivate(dst->fixedData(TypedArrayObject::FIXED_DATA_START));
forwardTypedArrayPointers(dst, src);
/* The shape's list head may point into the old object. */
if (&src->shape_ == dst->shape_->listp)
@ -578,6 +578,36 @@ js::Nursery::moveObjectToTenured(JSObject *dst, JSObject *src, AllocKind dstKind
return tenuredSize;
}
void
js::Nursery::forwardTypedArrayPointers(JSObject *dst, JSObject *src)
{
/*
* Typed array data may be stored inline inside the object's fixed slots. If
* so, we need update the private pointer and leave a forwarding pointer at
* the start of the data.
*/
TypedArrayObject &typedArray = src->as<TypedArrayObject>();
JS_ASSERT_IF(typedArray.buffer(), !isInside(src->getPrivate()));
if (typedArray.buffer())
return;
void *srcData = src->fixedData(TypedArrayObject::FIXED_DATA_START);
void *dstData = dst->fixedData(TypedArrayObject::FIXED_DATA_START);
JS_ASSERT(src->getPrivate() == srcData);
dst->setPrivate(dstData);
/*
* We don't know the number of slots here, but
* TypedArrayObject::AllocKindForLazyBuffer ensures that it's always at
* least one.
*/
size_t nslots = 1;
setSlotsForwardingPointer(reinterpret_cast<HeapSlot*>(srcData),
reinterpret_cast<HeapSlot*>(dstData),
nslots);
}
size_t
js::Nursery::moveSlotsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind)
{

View File

@ -267,6 +267,7 @@ class Nursery
size_t moveObjectToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
size_t moveElementsToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
size_t moveSlotsToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
void forwardTypedArrayPointers(JSObject *dst, JSObject *src);
/* Handle relocation of slots/elements pointers stored in Ion frames. */
void setSlotsForwardingPointer(HeapSlot *oldSlots, HeapSlot *newSlots, uint32_t nslots);

View File

@ -0,0 +1,13 @@
var SECTION = "";
gcPreserveCode()
gczeal(9, 1000);
function test() {
var f32 = new Float32Array(10);
f32[0] = 5;
var i = 0;
for (var j = 0; j < 10000; ++j) {
f32[i + 1] = f32[i] - 1;
SECTION += 1;
}
}
test();

View File

@ -51,8 +51,9 @@ class TypedArrayObject : public ArrayBufferViewObject
AllocKindForLazyBuffer(size_t nbytes)
{
JS_ASSERT(nbytes <= INLINE_BUFFER_LIMIT);
int dataSlots = (nbytes - 1) / sizeof(Value) + 1;
JS_ASSERT(int(nbytes) <= dataSlots * int(sizeof(Value)));
/* For GGC we need at least one slot in which to store a forwarding pointer. */
size_t dataSlots = Max(size_t(1), AlignBytes(nbytes, sizeof(Value)) / sizeof(Value));
JS_ASSERT(nbytes <= dataSlots * sizeof(Value));
return gc::GetGCObjectKind(FIXED_DATA_START + dataSlots);
}