[INFER] Use both inline and dynamic slots for objects other than dense arrays, bug 648321.
This commit is contained in:
@@ -972,7 +972,7 @@ array_trace(JSTracer *trc, JSObject *obj)
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
|
||||
uint32 capacity = obj->getDenseArrayInitializedLength();
|
||||
MarkValueRange(trc, capacity, obj->slots, "element");
|
||||
MarkValueRange(trc, capacity, obj->getDenseArrayElements(), "element");
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@@ -1075,7 +1075,24 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
if (!InitScopeForObject(cx, this, &js_SlowArrayClass, getType(), kind))
|
||||
return false;
|
||||
|
||||
uint32 initlen = getDenseArrayInitializedLength();
|
||||
backfillDenseArrayHoles();
|
||||
|
||||
uint32 arrayCapacity = getDenseArrayCapacity();
|
||||
|
||||
/*
|
||||
* Adjust the slots to account for the different layout between dense
|
||||
* arrays and other objects. The slots must be dynamic, and the fixed slots
|
||||
* are now available for newly added properties.
|
||||
*/
|
||||
if (denseArrayHasInlineSlots()) {
|
||||
if (!allocSlots(cx, numSlots())) {
|
||||
setMap(oldMap);
|
||||
return false;
|
||||
}
|
||||
JS_ASSERT(!denseArrayHasInlineSlots());
|
||||
}
|
||||
capacity = numFixedSlots() + arrayCapacity;
|
||||
clasp = &js_SlowArrayClass;
|
||||
|
||||
/*
|
||||
* Begin with the length property to share more of the property tree.
|
||||
@@ -1083,6 +1100,8 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
*/
|
||||
if (!AddLengthProperty(cx, this)) {
|
||||
setMap(oldMap);
|
||||
capacity = arrayCapacity;
|
||||
clasp = &js_ArrayClass;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1091,46 +1110,38 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
* remove holes, so that shapes use successive slots (as for other objects).
|
||||
*/
|
||||
uint32 next = 0;
|
||||
for (uint32 i = 0; i < initlen; i++) {
|
||||
for (uint32 i = 0; i < arrayCapacity; i++) {
|
||||
/* Dense array indexes can always fit in a jsid. */
|
||||
jsid id;
|
||||
if (!ValueToId(cx, Int32Value(i), &id)) {
|
||||
setMap(oldMap);
|
||||
return false;
|
||||
}
|
||||
JS_ALWAYS_TRUE(ValueToId(cx, Int32Value(i), &id));
|
||||
|
||||
if (getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE))
|
||||
if (slots[i].isMagic(JS_ARRAY_HOLE))
|
||||
continue;
|
||||
|
||||
setDenseArrayElement(next, getDenseArrayElement(i));
|
||||
setSlot(next, slots[i]);
|
||||
|
||||
if (!addDataProperty(cx, id, next, JSPROP_ENUMERATE)) {
|
||||
setMap(oldMap);
|
||||
capacity = arrayCapacity;
|
||||
clasp = &js_ArrayClass;
|
||||
return false;
|
||||
}
|
||||
|
||||
next++;
|
||||
}
|
||||
|
||||
clearSlotRange(next, capacity - next);
|
||||
|
||||
/* initialized length is not used anymore. */
|
||||
initializedLength = 0;
|
||||
JS_ASSERT(newType == NULL);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* that delegating instances can share shapes in the tree rooted at the
|
||||
* proto's empty shape.
|
||||
*/
|
||||
clasp = &js_SlowArrayClass;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user