зеркало из https://github.com/mozilla/gecko-dev.git
Bug 787282 - Initialize all slots in ParallelArray constructor when GC might trigger (r=billm)
This commit is contained in:
Родитель
d5c7aa9533
Коммит
3b0ec28eba
|
@ -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();
|
Загрузка…
Ссылка в новой задаче