Leave a hint for GetProperty in the context so it can figure out the current bytecode location without de-optimizing (476238, r=jorendorff).

This commit is contained in:
Andreas Gal 2009-02-02 17:25:59 -08:00
parent a7efd80fdd
commit 5fcbf234da
4 changed files with 57 additions and 28 deletions

View File

@ -130,6 +130,7 @@ typedef struct JSTraceMonitor {
* JS_ReportOutOfMemory when failing due to runtime limits.
*/
JSBool onTrace;
CLS(nanojit::LirBuffer) lirbuf;
CLS(nanojit::Fragmento) fragmento;
CLS(TraceRecorder) recorder;
@ -980,8 +981,14 @@ struct JSContext {
/* Stored here to avoid passing it around as a parameter. */
uintN resolveFlags;
/* Current bytecode location (or NULL if no hint was supplied). */
jsbytecode *pcHint;
};
#define BEGIN_PC_HINT(pc) cx->pcHint = pc
#define END_PC_HINT() cx->pcHint = NULL
#ifdef JS_THREADSAFE
# define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0)
#endif

View File

@ -4280,11 +4280,12 @@ js_Interpret(JSContext *cx)
LOAD_ATOM(i);
}
id = ATOM_TO_JSID(atom);
if (entry
? !js_GetPropertyHelper(cx, aobj, id, &rval, &entry)
: !OBJ_GET_PROPERTY(cx, obj, id, &rval)) {
goto error;
}
BEGIN_PC_HINT(regs.pc);
if (entry
? !js_GetPropertyHelper(cx, aobj, id, &rval, &entry)
: !OBJ_GET_PROPERTY(cx, obj, id, &rval))
goto error;
END_PC_HINT();
} while (0);
STORE_OPND(-1, rval);
@ -4388,17 +4389,20 @@ js_Interpret(JSContext *cx)
goto error;
} else
#endif
if (entry
? !js_GetPropertyHelper(cx, aobj, id, &rval, &entry)
: !OBJ_GET_PROPERTY(cx, obj, id, &rval)) {
goto error;
}
BEGIN_PC_HINT(regs.pc);
if (entry
? !js_GetPropertyHelper(cx, aobj, id, &rval, &entry)
: !OBJ_GET_PROPERTY(cx, obj, id, &rval))
goto error;
END_PC_HINT();
STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
STORE_OPND(-2, rval);
} else {
JS_ASSERT(obj->map->ops->getProperty == js_GetProperty);
if (!js_GetPropertyHelper(cx, obj, id, &rval, &entry))
goto error;
BEGIN_PC_HINT(regs.pc);
if (!js_GetPropertyHelper(cx, obj, id, &rval, &entry))
goto error;
END_PC_HINT();
STORE_OPND(-1, lval);
STORE_OPND(-2, rval);
}
@ -6877,6 +6881,9 @@ js_Interpret(JSContext *cx)
#endif /* !JS_THREADED_INTERP */
error:
// Reset current pc location hinting.
cx->pcHint = NULL;
if (fp->imacpc && cx->throwing) {
// To keep things simple, we hard-code imacro exception handlers here.
if (*fp->imacpc == JSOP_NEXTITER) {

View File

@ -3896,6 +3896,22 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp)
return JS_TRUE;
}
/*
* Find out where we currently are in the code. If no hint was supplied,
* de-optimize and consult the stack frame.
*/
static jsbytecode*
js_GetCurrentBytecodePC(JSContext* cx)
{
jsbytecode *pc = cx->pcHint;
if (!pc) {
JSStackFrame* fp = js_GetTopStackFrame(cx);
if (fp && fp->regs)
pc = fp->regs->pc;
}
return pc;
}
JSBool
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
JSPropCacheEntry **entryp)
@ -3904,7 +3920,6 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
int protoIndex;
JSObject *obj2;
JSProperty *prop;
JSStackFrame *fp;
JSScopeProperty *sprop;
JS_ASSERT_IF(entryp, !JS_ON_TRACE(cx));
@ -3918,8 +3933,6 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
if (protoIndex < 0)
return JS_FALSE;
if (!prop) {
jsbytecode *pc;
*vp = JSVAL_VOID;
if (!OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, ID_TO_VALUE(id), vp))
@ -3934,11 +3947,11 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
* Give a strict warning if foo.bar is evaluated by a script for an
* object foo with no property named 'bar'.
*/
if (JSVAL_IS_VOID(*vp) && (fp = js_GetTopStackFrame(cx)) && fp->regs) {
jsbytecode *pc;
if (JSVAL_IS_VOID(*vp) && ((pc = js_GetCurrentBytecodePC(cx)) != NULL)) {
JSOp op;
uintN flags;
pc = fp->regs->pc;
op = (JSOp) *pc;
if (op == JSOP_GETXPROP) {
flags = JSREPORT_ERROR;
@ -3956,7 +3969,6 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
return JS_TRUE;
/* Kludge to allow (typeof foo == "undefined") tests. */
JS_ASSERT(fp->script);
pc += js_CodeSpec[op].length;
if (Detecting(cx, pc))
return JS_TRUE;

View File

@ -6887,15 +6887,16 @@ GetProperty(JSContext *cx, uintN argc, jsval *vp)
}
static jsval FASTCALL
GetProperty_tn(JSContext *cx, JSObject *obj, JSString *name)
GetProperty_tn(JSContext *cx, jsbytecode *pc, JSObject *obj, JSString *name)
{
jsid id;
jsval v;
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(name), &id) ||
!OBJ_GET_PROPERTY(cx, obj, id, &v)) {
return JSVAL_ERROR_COOKIE;
}
BEGIN_PC_HINT(pc);
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(name), &id) ||
!OBJ_GET_PROPERTY(cx, obj, id, &v))
v = JSVAL_ERROR_COOKIE;
END_PC_HINT();
return v;
}
@ -6915,22 +6916,24 @@ GetElement(JSContext *cx, uintN argc, jsval *vp)
}
static jsval FASTCALL
GetElement_tn(JSContext* cx, JSObject* obj, int32 index)
GetElement_tn(JSContext* cx, jsbytecode *pc, JSObject* obj, int32 index)
{
jsval v;
jsid id;
if (!js_Int32ToId(cx, index, &id))
return JSVAL_ERROR_COOKIE;
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
return JSVAL_ERROR_COOKIE;
BEGIN_PC_HINT(pc);
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
v = JSVAL_ERROR_COOKIE;
END_PC_HINT();
return v;
}
JS_DEFINE_TRCINFO_1(GetProperty,
(3, (static, JSVAL_FAIL, GetProperty_tn, CONTEXT, THIS, STRING, 0, 0)))
(4, (static, JSVAL_FAIL, GetProperty_tn, CONTEXT, PC, THIS, STRING, 0, 0)))
JS_DEFINE_TRCINFO_1(GetElement,
(3, (extern, JSVAL_FAIL, GetElement_tn, CONTEXT, THIS, INT32, 0, 0)))
(4, (extern, JSVAL_FAIL, GetElement_tn, CONTEXT, PC, THIS, INT32, 0, 0)))
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_GETELEM()