Bug 582081 - Dense array patches regressed empty Array creation on Dromaeo. r=jwalden

This commit is contained in:
Andreas Gal
2010-07-27 16:42:58 -07:00
parent 1c72495064
commit 863c22eb06
6 changed files with 63 additions and 60 deletions

View File

@@ -321,7 +321,7 @@ JSObject::growDenseArrayElements(JSContext *cx, uint32 oldcap, uint32 newcap)
return JS_FALSE;
}
/* dslots can be briefly NULL during array creation */
/* dslots can be NULL during array creation. */
Value *slots = dslots ? dslots - 1 : NULL;
Value *newslots = (Value *) cx->realloc(slots, (size_t(newcap) + 1) * sizeof(Value));
if (!newslots)
@@ -355,8 +355,7 @@ JSObject::ensureDenseArrayElements(JSContext *cx, uint32 newcap)
*/
static const size_t CAPACITY_CHUNK = 1024 * 1024 / sizeof(Value);
/* While creating arrays, dslots can be NULL. */
uint32 oldcap = dslots ? getDenseArrayCapacity() : 0;
uint32 oldcap = getDenseArrayCapacity();
if (newcap > oldcap) {
/*
@@ -1077,16 +1076,12 @@ JSObject::makeDenseArraySlow(JSContext *cx)
if (!scope)
return JS_FALSE;
uint32 capacity = obj->getDenseArrayCapacity();
/* For a brief moment the object has NULL dslots until we slowify it during construction. */
uint32 capacity = dslots ? obj->getDenseArrayCapacity() : 0;
if (capacity) {
scope->freeslot = obj->numSlots() + JS_INITIAL_NSLOTS;
// XXX: changing the capacity like this is awful. Bug 558263 will remove
// the need for this.
obj->setDenseArrayCapacity(JS_INITIAL_NSLOTS + capacity);
} else {
scope->freeslot = obj->numSlots();
}
if (obj->dslots)
obj->dslots[-1].setPrivateUint32(JS_INITIAL_NSLOTS + capacity);
scope->freeslot = obj->numSlots();
/* Begin with the length property to share more of the property tree. */
if (!scope->addProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
@@ -1459,8 +1454,9 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const Value *vector
JS_ASSERT(obj->isDenseArray());
obj->setArrayLength(length);
obj->setDenseArrayCapacity(0);
if (!vector || !length)
return obj->ensureDenseArrayElements(cx, ARRAY_CAPACITY_MIN);
return true;
if (!obj->ensureDenseArrayElements(cx, length))
return false;
memcpy(obj->getDenseArrayElements(), vector, length * sizeof(Value));
@@ -2983,8 +2979,11 @@ js_Array(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
}
JSObject* JS_FASTCALL
js_NewArrayWithSlots(JSContext* cx, JSObject* proto, uint32 len)
js_NewEmptyArray(JSContext* cx, JSObject* proto, int32 len)
{
if (len < 0)
return NULL;
JS_ASSERT(proto->isArray());
JSObject* obj = js_NewGCObject(cx);
@@ -2995,28 +2994,33 @@ js_NewArrayWithSlots(JSContext* cx, JSObject* proto, uint32 len)
obj->map = const_cast<JSObjectMap *>(&SharedArrayMap);
obj->init(&js_ArrayClass, proto, proto->getParent(), NullValue());
obj->setArrayLength(len);
obj->setDenseArrayCapacity(0);
return obj;
}
#ifdef JS_TRACER
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewEmptyArray, CONTEXT, OBJECT, INT32, 0,
nanojit::ACC_STORE_ANY)
#endif
JSObject* JS_FASTCALL
js_NewPreallocatedArray(JSContext* cx, JSObject* proto, int32 len)
{
JSObject *obj = js_NewEmptyArray(cx, proto, len);
if (!obj)
return NULL;
if (!obj->growDenseArrayElements(cx, 0, JS_MAX(len, ARRAY_CAPACITY_MIN)))
return NULL;
return obj;
}
#ifdef JS_TRACER
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewArrayWithSlots, CONTEXT, OBJECT, UINT32, 0,
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewPreallocatedArray, CONTEXT, OBJECT, INT32, 0,
nanojit::ACC_STORE_ANY)
#endif
JSObject* JS_FASTCALL
js_NewEmptyArray(JSContext* cx, JSObject* proto)
{
return js_NewArrayWithSlots(cx, proto, 0);
}
#ifdef JS_TRACER
JS_DEFINE_CALLINFO_2(extern, OBJECT, js_NewEmptyArray, CONTEXT, OBJECT, 0, nanojit::ACC_STORE_ANY)
#endif
JSObject *
js_InitArrayClass(JSContext *cx, JSObject *obj)
{
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ArrayClass, js_Array, 1,
JSObject *proto = js_InitClass(cx, obj, NULL, &js_SlowArrayClass, js_Array, 1,
NULL, array_methods, NULL, array_static_methods);
if (!proto)
return NULL;
@@ -3038,11 +3042,8 @@ js_NewArrayObject(JSContext *cx, jsuint length, const Value *vector)
*/
JS_ASSERT(obj->getProto());
{
AutoObjectRooter tvr(cx, obj);
if (!InitArrayObject(cx, obj, length, vector))
obj = NULL;
}
if (!InitArrayObject(cx, obj, length, vector))
obj = NULL;
/* Set/clear newborn root, in case we lost it. */
cx->weakRoots.finalizableNewborns[FINALIZE_OBJECT] = obj;