mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out patch for bug 454039.
This commit is contained in:
parent
c7b40d9f99
commit
7d5c49516c
@ -2510,7 +2510,7 @@ js_Interpret(JSContext *cx)
|
||||
|
||||
# ifdef JS_TRACER
|
||||
# define CHECK_RECORDER() JS_BEGIN_MACRO \
|
||||
JS_ASSERT(!TRACE_RECORDER(cx) ^ \
|
||||
JS_ASSERT(!JS_TRACE_MONITOR(cx).recorder ^ \
|
||||
(jumpTable == recordingJumpTable)); \
|
||||
JS_END_MACRO
|
||||
# else
|
||||
@ -2569,11 +2569,11 @@ js_Interpret(JSContext *cx)
|
||||
#ifdef JS_TRACER
|
||||
/* We had better not be entering the interpreter from JIT-compiled code. */
|
||||
TraceRecorder *tr = NULL;
|
||||
if (JS_ON_TRACE(cx)) {
|
||||
tr = TRACE_RECORDER(cx);
|
||||
SET_TRACE_RECORDER(cx, NULL);
|
||||
if (JS_TRACE_MONITOR(cx).onTrace) {
|
||||
tr = JS_TRACE_MONITOR(cx).recorder;
|
||||
JS_TRACE_MONITOR(cx).recorder = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Check for too deep of a native thread stack. */
|
||||
JS_CHECK_RECURSION(cx, return JS_FALSE);
|
||||
@ -2695,13 +2695,13 @@ js_Interpret(JSContext *cx)
|
||||
# define LOAD_INTERRUPT_HANDLER(cx) \
|
||||
((void) (jumpTable = (cx)->debugHooks->interruptHandler \
|
||||
? interruptJumpTable \
|
||||
: TRACE_RECORDER(cx) \
|
||||
: JS_TRACE_MONITOR(cx).recorder \
|
||||
? recordingJumpTable \
|
||||
: normalJumpTable))
|
||||
# define ENABLE_TRACER(flag) \
|
||||
JS_BEGIN_MACRO \
|
||||
bool flag_ = (flag); \
|
||||
JS_ASSERT(flag_ == !!TRACE_RECORDER(cx)); \
|
||||
JS_ASSERT(flag_ == !!JS_TRACE_MONITOR(cx).recorder); \
|
||||
jumpTable = flag_ ? recordingJumpTable : normalJumpTable; \
|
||||
JS_END_MACRO
|
||||
#else /* !JS_TRACER */
|
||||
@ -2715,11 +2715,12 @@ js_Interpret(JSContext *cx)
|
||||
#ifdef JS_TRACER
|
||||
# define LOAD_INTERRUPT_HANDLER(cx) \
|
||||
((void) (switchMask = ((cx)->debugHooks->interruptHandler || \
|
||||
TRACE_RECORDER(cx)) ? 0 : 255))
|
||||
JS_TRACE_MONITOR(cx).recorder) \
|
||||
? 0 : 255))
|
||||
# define ENABLE_TRACER(flag) \
|
||||
JS_BEGIN_MACRO \
|
||||
bool flag_ = (flag); \
|
||||
JS_ASSERT(flag_ == !!TRACE_RECORDER(cx)); \
|
||||
JS_ASSERT(flag_ == !!JS_TRACE_MONITOR(cx).recorder); \
|
||||
switchMask = flag_ ? 0 : 255; \
|
||||
JS_END_MACRO
|
||||
#else /* !JS_TRACER */
|
||||
@ -3021,7 +3022,7 @@ js_Interpret(JSContext *cx)
|
||||
inlineCallCount--;
|
||||
if (JS_LIKELY(ok)) {
|
||||
#ifdef JS_TRACER
|
||||
if (TRACE_RECORDER(cx))
|
||||
if (JS_TRACE_MONITOR(cx).recorder)
|
||||
RECORD(LeaveFrame);
|
||||
#endif
|
||||
JS_ASSERT(js_CodeSpec[*regs.pc].length == JSOP_CALL_LENGTH);
|
||||
@ -3265,6 +3266,7 @@ js_Interpret(JSContext *cx)
|
||||
* that we take into account side effects of the iterator
|
||||
* call. See bug 372331.
|
||||
*/
|
||||
|
||||
if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
|
||||
goto error;
|
||||
if (prop)
|
||||
@ -4437,7 +4439,8 @@ js_Interpret(JSContext *cx)
|
||||
* will (possibly after the first iteration) always exist
|
||||
* in native object o.
|
||||
*/
|
||||
entry = &cache->table[PROPERTY_CACHE_HASH_PC(regs.pc, kshape)];
|
||||
entry = &cache->table[PROPERTY_CACHE_HASH_PC(regs.pc,
|
||||
kshape)];
|
||||
PCMETER(cache->tests++);
|
||||
PCMETER(cache->settests++);
|
||||
if (entry->kpc == regs.pc && entry->kshape == kshape) {
|
||||
@ -4451,8 +4454,6 @@ js_Interpret(JSContext *cx)
|
||||
JS_ASSERT(!(sprop->attrs & JSPROP_READONLY));
|
||||
JS_ASSERT(!SCOPE_IS_SEALED(OBJ_SCOPE(obj)));
|
||||
|
||||
TRACE_2(SetPropHit, kshape, sprop);
|
||||
|
||||
if (scope->object == obj) {
|
||||
/*
|
||||
* Fastest path: the cached sprop is already
|
||||
@ -4907,7 +4908,7 @@ js_Interpret(JSContext *cx)
|
||||
cx->fp = fp = &newifp->frame;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
if (TRACE_RECORDER(cx))
|
||||
if (JS_TRACE_MONITOR(cx).recorder)
|
||||
RECORD(EnterFrame);
|
||||
#endif
|
||||
|
||||
@ -6120,8 +6121,6 @@ js_Interpret(JSContext *cx)
|
||||
if (sprop->parent != scope->lastProp)
|
||||
goto do_initprop_miss;
|
||||
|
||||
TRACE_2(SetPropHit, kshape, sprop);
|
||||
|
||||
/*
|
||||
* Otherwise this entry must be for a direct property of
|
||||
* obj, not a proto-property, and there cannot have been
|
||||
@ -7027,7 +7026,7 @@ js_Interpret(JSContext *cx)
|
||||
JS_ASSERT(inlineCallCount == 0);
|
||||
JS_ASSERT(fp->regs == ®s);
|
||||
#ifdef JS_TRACER
|
||||
if (TRACE_RECORDER(cx))
|
||||
if (JS_TRACE_MONITOR(cx).recorder)
|
||||
js_AbortRecording(cx, regs.pc, "recording out of js_Interpret");
|
||||
#endif
|
||||
if (JS_UNLIKELY(fp->flags & JSFRAME_YIELDING)) {
|
||||
@ -7052,12 +7051,12 @@ js_Interpret(JSContext *cx)
|
||||
js_SetVersion(cx, originalVersion);
|
||||
--cx->interpLevel;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
#ifdef JS_TRACER
|
||||
if (tr) {
|
||||
SET_TRACE_RECORDER(cx, tr);
|
||||
JS_TRACE_MONITOR(cx).recorder = tr;
|
||||
tr->deepAbort();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return ok;
|
||||
|
||||
atom_not_defined:
|
||||
|
@ -2526,9 +2526,9 @@ js_MonitorLoopEdge(JSContext* cx, jsbytecode* oldpc, uintN& inlineCallCount)
|
||||
}
|
||||
|
||||
bool
|
||||
js_MonitorRecording(TraceRecorder* tr)
|
||||
js_MonitorRecording(JSContext* cx)
|
||||
{
|
||||
JSContext* cx = tr->cx;
|
||||
TraceRecorder *tr = JS_TRACE_MONITOR(cx).recorder;
|
||||
|
||||
// Clear one-shot flag used to communicate between record_JSOP_CALL and record_EnterFrame.
|
||||
tr->applyingArguments = false;
|
||||
@ -2540,12 +2540,11 @@ js_MonitorRecording(TraceRecorder* tr)
|
||||
}
|
||||
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
|
||||
/* If we hit a break, end the loop and generate an always taken loop exit guard. For other
|
||||
downward gotos (like if/else) continue recording. */
|
||||
if (*pc == JSOP_GOTO || *pc == JSOP_GOTOX) {
|
||||
if ((*pc == JSOP_GOTO) || (*pc == JSOP_GOTOX)) {
|
||||
jssrcnote* sn = js_GetSrcNote(cx->fp->script, pc);
|
||||
if (sn && SN_TYPE(sn) == SRC_BREAK) {
|
||||
if ((sn != NULL) && (SN_TYPE(sn) == SRC_BREAK)) {
|
||||
AUDIT(breakLoopExits);
|
||||
tr->endLoop(JS_TRACE_MONITOR(cx).fragmento);
|
||||
js_DeleteRecorder(cx);
|
||||
@ -4394,38 +4393,41 @@ TraceRecorder::record_JSOP_GETPROP()
|
||||
bool
|
||||
TraceRecorder::record_JSOP_SETPROP()
|
||||
{
|
||||
jsval& r = stackval(-1);
|
||||
jsval& l = stackval(-2);
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(l))
|
||||
ABORT_TRACE("primitive this for SETPROP");
|
||||
|
||||
JSObject* obj = JSVAL_TO_OBJECT(l);
|
||||
|
||||
if (obj->map->ops->setProperty != js_SetProperty)
|
||||
ABORT_TRACE("non-native JSObjectOps::setProperty");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TraceRecorder::record_SetPropHit(uint32 kshape, JSScopeProperty* sprop)
|
||||
{
|
||||
jsval& r = stackval(-1);
|
||||
jsval& l = stackval(-2);
|
||||
|
||||
JS_ASSERT(!JSVAL_IS_PRIMITIVE(l));
|
||||
JSObject* obj = JSVAL_TO_OBJECT(l);
|
||||
LIns* obj_ins = get(&l);
|
||||
|
||||
JSPropertyCache* cache = &JS_PROPERTY_CACHE(cx);
|
||||
uint32 kshape = OBJ_SHAPE(obj);
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
|
||||
JSPropCacheEntry* entry = &cache->table[PROPERTY_CACHE_HASH_PC(pc, kshape)];
|
||||
if (entry->kpc != pc || entry->kshape != kshape)
|
||||
ABORT_TRACE("cache miss");
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
|
||||
LIns* map_ins = lir->insLoad(LIR_ldp, obj_ins, (int)offsetof(JSObject, map));
|
||||
LIns* ops_ins;
|
||||
if (!map_is_native(obj->map, map_ins, ops_ins, offsetof(JSObjectOps, setProperty)))
|
||||
return false;
|
||||
|
||||
// The global object's shape is guarded at trace entry.
|
||||
if (obj != globalObj) {
|
||||
LIns* map_ins = lir->insLoad(LIR_ldp, obj_ins, (int)offsetof(JSObject, map));
|
||||
LIns* ops_ins;
|
||||
if (!map_is_native(obj->map, map_ins, ops_ins, offsetof(JSObjectOps, setProperty)))
|
||||
return false;
|
||||
|
||||
LIns* shape_ins = addName(lir->insLoad(LIR_ld, map_ins, offsetof(JSScope, shape)), "shape");
|
||||
guard(true, addName(lir->ins2i(LIR_eq, shape_ins, kshape), "guard(shape)"), MISMATCH_EXIT);
|
||||
}
|
||||
|
||||
JSScope* scope = OBJ_SCOPE(obj);
|
||||
JSScopeProperty* sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
if (scope->object != obj || !SCOPE_HAS_PROPERTY(scope, sprop)) {
|
||||
LIns* args[] = { INS_CONSTPTR(sprop), obj_ins, cx_ins };
|
||||
LIns* ok_ins = lir->insCall(F_AddProperty, args);
|
||||
@ -4439,9 +4441,7 @@ TraceRecorder::record_SetPropHit(uint32 kshape, JSScopeProperty* sprop)
|
||||
return false;
|
||||
if (!native_set(obj_ins, sprop, dslots_ins, boxed_ins))
|
||||
return false;
|
||||
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
if (*pc != JSOP_INITPROP && pc[JSOP_SETPROP_LENGTH] != JSOP_POP)
|
||||
if (*pc == JSOP_SETPROP && pc[JSOP_SETPROP_LENGTH] != JSOP_POP)
|
||||
stack(-2, v_ins);
|
||||
return true;
|
||||
}
|
||||
@ -5368,8 +5368,8 @@ TraceRecorder::record_JSOP_ENDINIT()
|
||||
bool
|
||||
TraceRecorder::record_JSOP_INITPROP()
|
||||
{
|
||||
// All the action is in record_SetPropHit.
|
||||
return true;
|
||||
// The common code avoids stacking the RHS if op is not JSOP_SETPROP.
|
||||
return record_JSOP_SETPROP();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -5457,6 +5457,8 @@ TraceRecorder::record_JSOP_ITER()
|
||||
bool
|
||||
TraceRecorder::forInLoop(jsval* vp)
|
||||
{
|
||||
if (!JSVAL_IS_STRING(*vp))
|
||||
ABORT_TRACE("for-in loop variable changed type from string");
|
||||
jsval& iterobj_val = stackval(-1);
|
||||
if (!JSVAL_IS_PRIMITIVE(iterobj_val)) {
|
||||
LIns* args[] = { get(&iterobj_val), cx_ins };
|
||||
@ -5465,11 +5467,10 @@ TraceRecorder::forInLoop(jsval* vp)
|
||||
|
||||
LIns* flag_ins = lir->ins_eq0(lir->ins2(LIR_eq, v_ins, INS_CONST(JSVAL_HOLE)));
|
||||
LIns* iter_ins = get(vp);
|
||||
jsval expected = JSVAL_IS_VOID(*vp) ? JSVAL_STRING : JSVAL_TAG(*vp);
|
||||
if (!box_jsval(expected, iter_ins))
|
||||
if (!box_jsval(JSVAL_STRING, iter_ins))
|
||||
return false;
|
||||
iter_ins = lir->ins_choose(flag_ins, v_ins, iter_ins, true);
|
||||
if (!unbox_jsval(expected, iter_ins))
|
||||
if (!unbox_jsval(JSVAL_STRING, iter_ins))
|
||||
return false;
|
||||
set(vp, iter_ins);
|
||||
stack(0, flag_ins);
|
||||
|
@ -334,7 +334,7 @@ class TraceRecorder {
|
||||
void fuseIf(jsbytecode* pc, bool cond, nanojit::LIns* x);
|
||||
|
||||
public:
|
||||
friend bool js_MonitorRecording(TraceRecorder* tr);
|
||||
friend bool js_MonitorRecording(JSContext* cx);
|
||||
|
||||
TraceRecorder(JSContext* cx, nanojit::GuardRecord*, nanojit::Fragment*, TreeInfo*,
|
||||
unsigned ngslots, uint8* globalTypeMap, uint8* stackTypeMap,
|
||||
@ -358,7 +358,6 @@ public:
|
||||
|
||||
bool record_EnterFrame();
|
||||
bool record_LeaveFrame();
|
||||
bool record_SetPropHit(uint32 kshape, JSScopeProperty* sprop);
|
||||
|
||||
void deepAbort() { deepAborted = true; }
|
||||
bool wasDeepAborted() { return deepAborted; }
|
||||
@ -370,43 +369,23 @@ public:
|
||||
};
|
||||
|
||||
#define TRACING_ENABLED(cx) JS_HAS_OPTION(cx, JSOPTION_JIT)
|
||||
#define TRACE_RECORDER(cx) (JS_TRACE_MONITOR(cx).recorder)
|
||||
#define SET_TRACE_RECORDER(cx,tr) (JS_TRACE_MONITOR(cx).recorder = (tr))
|
||||
|
||||
// See jsinterp.cpp for the ENABLE_TRACER definition.
|
||||
#define RECORD_ARGS(x,args) \
|
||||
#define RECORD(x) \
|
||||
JS_BEGIN_MACRO \
|
||||
TraceRecorder* tr_ = TRACE_RECORDER(cx); \
|
||||
if (!js_MonitorRecording(tr_)) \
|
||||
TraceRecorder* r = JS_TRACE_MONITOR(cx).recorder; \
|
||||
if (!js_MonitorRecording(cx)) { \
|
||||
ENABLE_TRACER(0); \
|
||||
else \
|
||||
TRACE_ARGS_(tr_,x,args); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define TRACE_ARGS_(tr,x,args) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (!tr->record_##x args) { \
|
||||
} else if (!r->record_##x()) { \
|
||||
js_AbortRecording(cx, NULL, #x); \
|
||||
ENABLE_TRACER(0); \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define TRACE_ARGS(x,args) \
|
||||
JS_BEGIN_MACRO \
|
||||
TraceRecorder* tr_ = TRACE_RECORDER(cx); \
|
||||
if (tr_) \
|
||||
TRACE_ARGS_(tr_, x, args); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define RECORD(x) RECORD_ARGS(x, ())
|
||||
#define TRACE_1(x,a) TRACE_ARGS(x, (a))
|
||||
#define TRACE_2(x,a,b) TRACE_ARGS(x, (a, b))
|
||||
|
||||
extern bool
|
||||
js_MonitorLoopEdge(JSContext* cx, jsbytecode* oldpc, uintN& inlineCallCount);
|
||||
|
||||
extern bool
|
||||
js_MonitorRecording(TraceRecorder *tr);
|
||||
js_MonitorRecording(JSContext* cx);
|
||||
|
||||
extern void
|
||||
js_AbortRecording(JSContext* cx, jsbytecode* abortpc, const char* reason);
|
||||
|
Loading…
Reference in New Issue
Block a user