Browser spuriously sets runtime->anyArrayPrototypeHasElement and makes perf bad (481251, r=mrbkap).

This commit is contained in:
Andreas Gal
2009-03-03 18:04:15 -08:00
parent 583676b976
commit 8dd119a9f2
9 changed files with 54 additions and 41 deletions

View File

@@ -822,6 +822,32 @@ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return JS_TRUE;
}
JSBool FASTCALL
js_ObjectHasNumericPropertiesInAnyPrototype(JSContext *cx, JSObject *obj)
{
JSObject *pobj = obj;
/* Walk up the prototype chain and see if this indexed element already exists. */
for (;;) {
pobj = JSVAL_TO_OBJECT(pobj->fslots[JSSLOT_PROTO]);
/*
* If we hit the end of the prototype chain, its safe to set the element on the
* original object.
*/
if (!pobj)
break;
/*
* If the prototype is a dense array, or a non-dense array that has numeric
* properties, return true.
*/
if (OBJ_IS_DENSE_ARRAY(cx, pobj) || (SCOPE_HAS_INDEXED_PROPERTIES(OBJ_SCOPE(pobj))))
return JS_TRUE;
}
return JS_FALSE;
}
#ifdef JS_TRACER
JSBool FASTCALL
js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
@@ -843,8 +869,9 @@ js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
return JS_FALSE;
if (obj->dslots[u] == JSVAL_HOLE) {
if (cx->runtime->anyArrayProtoHasElement)
if (js_ObjectHasNumericPropertiesInAnyPrototype(cx, obj))
return JS_FALSE;
if (u >= jsuint(obj->fslots[JSSLOT_ARRAY_LENGTH]))
obj->fslots[JSSLOT_ARRAY_LENGTH] = u + 1;
++obj->fslots[JSSLOT_ARRAY_COUNT];
@@ -3478,3 +3505,5 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewUninitializedArray, CONTEXT, OBJECT,
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_FastNewArrayWithLength, CONTEXT, OBJECT, UINT32, 0, 0)
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_Array_1str, CONTEXT, OBJECT, STRING, 0, 0)
JS_DEFINE_CALLINFO_3(extern, BOOL, js_ArrayCompPush, CONTEXT, OBJECT, JSVAL, 0, 0)
JS_DEFINE_CALLINFO_2(extern, BOOL, js_ObjectHasNumericPropertiesInAnyPrototype,
CONTEXT, OBJECT, 0, 0)