Bug 787282 - Initialize all slots in ParallelArray constructor when GC might trigger (r=billm)

This commit is contained in:
Shu-yu Guo 2012-08-31 21:33:04 -07:00
Родитель d5c7aa9533
Коммит 3b0ec28eba
2 изменённых файлов: 27 добавлений и 8 удалений

Просмотреть файл

@ -121,10 +121,11 @@ NewDenseCopiedArrayWithType(JSContext *cx, uint32_t length, HandleObject source)
uint32_t srclen;
uint32_t copyUpTo;
// Optimize for the common case: if we have a dense array source, copy
// whatever we can, truncating to length, and filling the rest with
// undefineds. Holes are converted to undefineds eagerly.
if (source->isDenseArray() && !js_PrototypeHasIndexedProperties(cx, source)) {
// Optimize for the common case: if we have a dense array source, copy
// whatever we can, truncating to length. This path doesn't trigger
// GC, so we don't need to initialize all the array's slots before
// copying.
const Value *srcvp = source->getDenseArrayElements();
srclen = source->getDenseArrayInitializedLength();
@ -136,7 +137,17 @@ NewDenseCopiedArrayWithType(JSContext *cx, uint32_t length, HandleObject source)
elem = srcvp[i].isMagic(JS_ARRAY_HOLE) ? UndefinedValue() : srcvp[i];
buffer->initDenseArrayElementWithType(cx, i, elem);
}
// Fill the rest with undefineds.
for (uint32_t i = copyUpTo; i < length; i++)
buffer->initDenseArrayElementWithType(cx, i, UndefinedValue());
} else {
// This path might GC. The GC expects an object's slots to be
// initialized, so we have to make sure all the array's slots are
// initialized.
for (uint32_t i = 0; i < length; i++)
buffer->initDenseArrayElementWithType(cx, i, UndefinedValue());
IndexInfo siv(cx);
RootedParallelArrayObject sourcePA(cx);
@ -149,14 +160,10 @@ NewDenseCopiedArrayWithType(JSContext *cx, uint32_t length, HandleObject source)
for (uint32_t i = 0; i < copyUpTo; i++) {
if (!GetElementFromArrayLikeObject(cx, source, sourcePA, siv, i, &elem))
return NULL;
buffer->initDenseArrayElementWithType(cx, i, elem);
buffer->setDenseArrayElementWithType(cx, i, elem);
}
}
// Fill the rest with undefineds.
for (uint32_t i = copyUpTo; i < length; i++)
buffer->initDenseArrayElementWithType(cx, i, UndefinedValue());
if (!SetArrayNewType(cx, buffer))
return NULL;

Просмотреть файл

@ -0,0 +1,12 @@
// |jit-test| error: TypeError
var protoArr = Proxy.create({}, null);
void (Array.prototype.__proto__ = protoArr);
gczeal(2);
function testCopyBigArray() {
var a = new Array(10000);
for (var cnt = 0; cnt < a.length; cnt+=2) {
var p = new ParallelArray(a);
}
}
testCopyBigArray();