Limit tree growth to side exits that expicitly declare that they want to be grown.

This commit is contained in:
Andreas Gal 2008-07-29 11:13:41 -07:00
parent 76237b5e15
commit 20185cf2d8
3 changed files with 11 additions and 13 deletions

View File

@ -1512,12 +1512,10 @@ js_LoopEdge(JSContext* cx, jsbytecode* oldpc)
case LOOP_EXIT: case LOOP_EXIT:
/* if this exits the loop, resume interpretation */ /* if this exits the loop, resume interpretation */
return false; return false;
case OVERFLOW_EXIT:
/* a speculation failed, we should probably de-speculate */
return false;
default: default:
JS_ASSERT(lr->exit->exitType == nanojit::OOM_EXIT); JS_ASSERT(lr->exit->exitType == DONT_GROW);
/* we ran out of heap, exit for now and re-enter once the GC ran */ /* We ran out of heap, or an unsupported instruction. Exit for now and re-enter once the
GC ran. */
return false; return false;
} }
} }
@ -1634,15 +1632,15 @@ bool TraceRecorder::ifop()
{ {
jsval& v = stackval(-1); jsval& v = stackval(-1);
if (JSVAL_IS_BOOLEAN(v)) { if (JSVAL_IS_BOOLEAN(v)) {
guard(!JSVAL_TO_BOOLEAN(v), lir->ins_eq0(get(&v))); guard(!JSVAL_TO_BOOLEAN(v), lir->ins_eq0(get(&v)), BRANCH_EXIT);
} else if (JSVAL_IS_OBJECT(v)) { } else if (JSVAL_IS_OBJECT(v)) {
guard(!JSVAL_IS_NULL(v), lir->ins_eq0(get(&v))); guard(!JSVAL_IS_NULL(v), lir->ins_eq0(get(&v)), BRANCH_EXIT);
} else if (isNumber(v)) { } else if (isNumber(v)) {
jsdouble d = asNumber(v); jsdouble d = asNumber(v);
jsdpun u; jsdpun u;
u.d = 0; u.d = 0;
/* XXX need to handle NaN! */ /* XXX need to handle NaN! */
guard(d == 0, lir->ins2(LIR_feq, get(&v), lir->insImmq(u.u64))); guard(d == 0, lir->ins2(LIR_feq, get(&v), lir->insImmq(u.u64)), BRANCH_EXIT);
} else if (JSVAL_IS_STRING(v)) { } else if (JSVAL_IS_STRING(v)) {
ABORT_TRACE("strings not supported"); ABORT_TRACE("strings not supported");
} else { } else {
@ -1760,7 +1758,7 @@ TraceRecorder::cmp(LOpcode op, bool negate)
/* The interpreter fuses comparisons and the following branch, /* The interpreter fuses comparisons and the following branch,
so we have to do that here as well. */ so we have to do that here as well. */
if (cx->fp->regs->pc[1] == JSOP_IFEQ || cx->fp->regs->pc[1] == JSOP_IFNE) if (cx->fp->regs->pc[1] == JSOP_IFEQ || cx->fp->regs->pc[1] == JSOP_IFNE)
guard(cond, x); guard(cond, x, BRANCH_EXIT);
/* We update the stack after the guard. This is safe since /* We update the stack after the guard. This is safe since
the guard bails out at the comparison and the interpreter the guard bails out at the comparison and the interpreter
@ -2254,7 +2252,7 @@ bool TraceRecorder::record_JSOP_ADD()
if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) { if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) {
LIns* args[] = { get(&r), get(&l), cx_ins }; LIns* args[] = { get(&r), get(&l), cx_ins };
LIns* concat = lir->insCall(F_ConcatStrings, args); LIns* concat = lir->insCall(F_ConcatStrings, args);
guard(false, lir->ins_eq0(concat)); guard(false, lir->ins_eq0(concat), OOM_EXIT);
set(&l, concat); set(&l, concat);
return true; return true;
} }
@ -2708,7 +2706,7 @@ bool TraceRecorder::record_JSOP_CALL()
LIns* res_ins = lir->insCall(known->builtin, args); LIns* res_ins = lir->insCall(known->builtin, args);
if (known->fallible) if (known->fallible)
guard(false, lir->ins_eq0(res_ins)); guard(false, lir->ins_eq0(res_ins), OOM_EXIT);
set(&fval, res_ins); set(&fval, res_ins);
return true; return true;
} }

View File

@ -151,7 +151,7 @@ class TraceRecorder {
unsigned getCallDepth() const; unsigned getCallDepth() const;
nanojit::LIns* guard(bool expected, nanojit::LIns* cond, nanojit::LIns* guard(bool expected, nanojit::LIns* cond,
nanojit::ExitType exitType = nanojit::BRANCH_EXIT); nanojit::ExitType exitType = nanojit::DONT_GROW);
nanojit::LIns* addName(nanojit::LIns* ins, const char* name); nanojit::LIns* addName(nanojit::LIns* ins, const char* name);
nanojit::LIns* get(jsval* p); nanojit::LIns* get(jsval* p);

View File

@ -129,7 +129,7 @@ namespace nanojit
class Fragment; class Fragment;
enum ExitType { enum ExitType {
BRANCH_EXIT, LOOP_EXIT, OOM_EXIT, OVERFLOW_EXIT DONT_GROW, BRANCH_EXIT, LOOP_EXIT, OOM_EXIT=DONT_GROW, OVERFLOW_EXIT=DONT_GROW
}; };
struct SideExit struct SideExit