This commit is contained in:
Andreas Gal 2009-03-09 17:30:06 -07:00
commit d3cc05e80b
4 changed files with 32 additions and 9 deletions

View File

@ -63,6 +63,28 @@ extern JSClass js_ArrayClass, js_SlowArrayClass;
#define OBJ_IS_ARRAY(cx,obj) (OBJ_IS_DENSE_ARRAY(cx, obj) || \
OBJ_GET_CLASS(cx, obj) == &js_SlowArrayClass)
/*
* Dense arrays are not native (OBJ_IS_NATIVE(cx, aobj) for a dense array aobj
* results in false, meaning aobj->map does not point to a JSScope).
*
* But Array methods are called via aobj.sort(), e.g., and the interpreter and
* the trace recorder must consult the property cache in order to perform well.
* The cache works only for native objects.
*
* Therefore the interpreter (js_Interpret in JSOP_GETPROP and JSOP_CALLPROP)
* and js_GetPropertyHelper use this inline function to skip up one link in the
* prototype chain when obj is a dense array, in order to find a likely-native
* object (to wit, Array.prototype) in which to probe for cached methods.
*
* Callers of js_GetProtoIfDenseArray must take care to use the original object
* (obj) for the |this| value of a getter, setter, or method call (bug 476447).
*/
static JS_INLINE JSObject *
js_GetProtoIfDenseArray(JSContext *cx, JSObject *obj)
{
return OBJ_IS_DENSE_ARRAY(cx, obj) ? OBJ_GET_PROTO(cx, obj) : obj;
}
extern JSObject *
js_InitArrayClass(JSContext *cx, JSObject *obj);

View File

@ -4263,7 +4263,7 @@ js_Interpret(JSContext *cx)
JSObject *aobj;
JSPropCacheEntry *entry;
aobj = OBJ_IS_DENSE_ARRAY(cx, obj) ? OBJ_GET_PROTO(cx, obj) : obj;
aobj = js_GetProtoIfDenseArray(cx, obj);
if (JS_LIKELY(aobj->map->ops->getProperty == js_GetProperty)) {
PROPERTY_CACHE_TEST(cx, regs.pc, aobj, obj2, entry, atom);
if (!atom) {
@ -4291,7 +4291,7 @@ js_Interpret(JSContext *cx)
}
id = ATOM_TO_JSID(atom);
if (entry
? !js_GetPropertyHelper(cx, aobj, id, &rval, &entry)
? !js_GetPropertyHelper(cx, obj, id, &rval, &entry)
: !OBJ_GET_PROPERTY(cx, obj, id, &rval)) {
goto error;
}
@ -4354,7 +4354,7 @@ js_Interpret(JSContext *cx)
goto error;
}
aobj = OBJ_IS_DENSE_ARRAY(cx, obj) ? OBJ_GET_PROTO(cx, obj) : obj;
aobj = js_GetProtoIfDenseArray(cx, obj);
if (JS_LIKELY(aobj->map->ops->getProperty == js_GetProperty)) {
PROPERTY_CACHE_TEST(cx, regs.pc, aobj, obj2, entry, atom);
if (!atom) {
@ -4399,7 +4399,7 @@ js_Interpret(JSContext *cx)
} else
#endif
if (entry
? !js_GetPropertyHelper(cx, aobj, id, &rval, &entry)
? !js_GetPropertyHelper(cx, obj, id, &rval, &entry)
: !OBJ_GET_PROPERTY(cx, obj, id, &rval)) {
goto error;
}

View File

@ -4205,9 +4205,9 @@ JSBool
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
JSPropCacheEntry **entryp)
{
JSObject *aobj, *obj2;
uint32 shape;
int protoIndex;
JSObject *obj2;
JSProperty *prop;
JSScopeProperty *sprop;
@ -4215,8 +4215,9 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
/* Convert string indices to integers if appropriate. */
CHECK_FOR_STRING_INDEX(id);
shape = OBJ_SHAPE(obj);
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
aobj = js_GetProtoIfDenseArray(cx, obj);
shape = OBJ_SHAPE(aobj);
protoIndex = js_LookupPropertyWithFlags(cx, aobj, id, cx->resolveFlags,
&obj2, &prop);
if (protoIndex < 0)
return JS_FALSE;
@ -4294,7 +4295,7 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
if (entryp) {
JS_ASSERT_NOT_ON_TRACE(cx);
js_FillPropertyCache(cx, obj, shape, 0, protoIndex, obj2, sprop, entryp);
js_FillPropertyCache(cx, aobj, shape, 0, protoIndex, obj2, sprop, entryp);
}
JS_UNLOCK_OBJ(cx, obj2);
return JS_TRUE;

View File

@ -2149,7 +2149,7 @@ class RegExpNativeCompiler {
}
}
LIns* to_fail = lir->insBranch(LIR_jf, lir->ins2(LIR_lt, pos, cpend), 0);
LIns* to_fail = lir->insBranch(LIR_jf, lir->ins2(LIR_lt, pos, lir->ins2(LIR_sub, cpend, lir->insImm(2))), 0);
fails.add(to_fail);
LIns* text_word = lir->insLoad(LIR_ld, pos, lir->insImm(0));
LIns* comp_word = useFastCI ?