Back out patch for bug 454039.

This commit is contained in:
Brendan Eich 2008-09-09 16:55:07 -07:00
parent c7b40d9f99
commit 7d5c49516c
3 changed files with 54 additions and 75 deletions

View File

@ -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,9 +2569,9 @@ 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
@ -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 == &regs);
#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)) {
@ -7054,7 +7053,7 @@ js_Interpret(JSContext *cx)
#ifdef JS_TRACER
if (tr) {
SET_TRACE_RECORDER(cx, tr);
JS_TRACE_MONITOR(cx).recorder = tr;
tr->deepAbort();
}
#endif

View File

@ -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);
// The global object's shape is guarded at trace entry.
if (obj != globalObj) {
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* 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);

View File

@ -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);