зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
a7efd80fdd
Коммит
5fcbf234da
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
Загрузка…
Ссылка в новой задаче