mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Fix fixed slots invariant for slow arrays, bug 610592. r=brendan
This commit is contained in:
parent
f9af2830e6
commit
3f497e1eae
29
js/src/jit-test/tests/basic/bug610592.js
Normal file
29
js/src/jit-test/tests/basic/bug610592.js
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
/* Don't confuse JIT code by making slow arrays that use inline slots inconsistently. */
|
||||
|
||||
function foo(a)
|
||||
{
|
||||
assertEq(a.x, 5);
|
||||
}
|
||||
|
||||
function bar()
|
||||
{
|
||||
for (var i = 0; i < 50; i++) {
|
||||
var a = [];
|
||||
a[i] = 0;
|
||||
delete a[i];
|
||||
a.x = 5;
|
||||
foo(a);
|
||||
}
|
||||
|
||||
var b = [1,,2,,3,,4,,5];
|
||||
assertEq(b.toString(), "1,,2,,3,,4,,5");
|
||||
b.x = 0;
|
||||
assertEq(b.toString(), "1,,2,,3,,4,,5");
|
||||
delete b.x;
|
||||
delete b[8];
|
||||
delete b[6];
|
||||
delete b[4];
|
||||
assertEq(b.toString(), "1,,2,,,,,,");
|
||||
}
|
||||
bar();
|
@ -1043,12 +1043,10 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
*/
|
||||
JSObjectMap *oldMap = map;
|
||||
|
||||
/*
|
||||
* Create a native scope. All slow arrays other than Array.prototype get
|
||||
* the same initial shape.
|
||||
*/
|
||||
/* Create a native scope. */
|
||||
JSObject *arrayProto = getProto();
|
||||
if (!InitScopeForObject(cx, this, &js_SlowArrayClass, arrayProto, FINALIZE_OBJECT0))
|
||||
js::gc::FinalizeKind kind = js::gc::FinalizeKind(arena()->header()->thingKind);
|
||||
if (!InitScopeForObject(cx, this, &js_SlowArrayClass, arrayProto, kind))
|
||||
return false;
|
||||
|
||||
uint32 capacity = getDenseArrayCapacity();
|
||||
@ -1064,7 +1062,11 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create new properties pointing to existing elements. */
|
||||
/*
|
||||
* Create new properties pointing to existing elements. Pack the array to
|
||||
* remove holes, so that shapes use successive slots (as for other objects).
|
||||
*/
|
||||
uint32 next = 0;
|
||||
for (uint32 i = 0; i < capacity; i++) {
|
||||
jsid id;
|
||||
if (!ValueToId(cx, Int32Value(i), &id)) {
|
||||
@ -1072,17 +1074,28 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
|
||||
setDenseArrayElement(i, UndefinedValue());
|
||||
if (getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addDataProperty(cx, id, i, JSPROP_ENUMERATE)) {
|
||||
setDenseArrayElement(next, getDenseArrayElement(i));
|
||||
|
||||
if (!addDataProperty(cx, id, next, JSPROP_ENUMERATE)) {
|
||||
setMap(oldMap);
|
||||
return false;
|
||||
}
|
||||
|
||||
next++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dense arrays with different numbers of slots but the same number of fixed
|
||||
* slots and the same non-hole indexes must use their fixed slots consistently.
|
||||
*/
|
||||
if (hasSlotsArray() && next <= numFixedSlots())
|
||||
revertToFixedSlots(cx);
|
||||
|
||||
ClearValueRange(slots + next, this->capacity - next, false);
|
||||
|
||||
/*
|
||||
* Finally, update class. If |this| is Array.prototype, then js_InitClass
|
||||
* will create an emptyShape whose class is &js_SlowArrayClass, to ensure
|
||||
|
Loading…
Reference in New Issue
Block a user