Bug 508187: do stack push after all guards when tracing JSOP_INCNAME et al, r=gal

This commit is contained in:
David Mandelin 2009-08-10 13:03:50 -07:00
parent 335eeb15af
commit 86609aa9f8
3 changed files with 47 additions and 10 deletions

View File

@ -7267,12 +7267,10 @@ TraceRecorder::inc(jsval& v, jsint incr, bool pre)
* (pre- or post-increment as described by pre) is stacked.
*/
JS_REQUIRES_STACK JSRecordingStatus
TraceRecorder::inc(jsval& v, LIns*& v_ins, jsint incr, bool pre)
TraceRecorder::inc(jsval v, LIns*& v_ins, jsint incr, bool pre)
{
if (!isNumber(v))
ABORT_TRACE("can only inc numbers");
LIns* v_after = alu(LIR_fadd, asNumber(v), incr, v_ins, lir->insImmf(incr));
LIns* v_after;
CHECK_STATUS(incHelper(v, v_ins, v_after, incr));
const JSCodeSpec& cs = js_CodeSpec[*cx->fp->regs->pc];
JS_ASSERT(cs.ndefs == 1);
@ -7281,6 +7279,18 @@ TraceRecorder::inc(jsval& v, LIns*& v_ins, jsint incr, bool pre)
return JSRS_CONTINUE;
}
/*
* Do an increment operation without storing anything to the stack.
*/
JS_REQUIRES_STACK JSRecordingStatus
TraceRecorder::incHelper(jsval v, LIns* v_ins, LIns*& v_after, jsint incr)
{
if (!isNumber(v))
ABORT_TRACE("can only inc numbers");
v_after = alu(LIR_fadd, asNumber(v), incr, v_ins, lir->insImmf(incr));
return JSRS_CONTINUE;
}
JS_REQUIRES_STACK JSRecordingStatus
TraceRecorder::incProp(jsint incr, bool pre)
{
@ -9539,11 +9549,15 @@ TraceRecorder::incName(jsint incr, bool pre)
{
jsval* vp;
LIns* v_ins;
LIns* v_after;
NameResult nr;
CHECK_STATUS(name(vp, v_ins, nr));
CHECK_STATUS(inc(*vp, v_ins, incr, pre));
CHECK_STATUS(incHelper(*vp, v_ins, v_after, incr));
LIns* v_result = pre ? v_after : v_ins;
if (nr.tracked) {
set(vp, v_ins);
set(vp, v_after);
stack(0, v_result);
return JSRS_CONTINUE;
}
@ -9552,7 +9566,9 @@ TraceRecorder::incName(jsint incr, bool pre)
LIns* callobj_ins = get(&cx->fp->argv[-2]);
for (jsint i = 0; i < nr.scopeIndex; ++i)
callobj_ins = stobj_get_parent(callobj_ins);
return setCallProp(nr.obj, callobj_ins, nr.sprop, v_ins, *vp);
CHECK_STATUS(setCallProp(nr.obj, callobj_ins, nr.sprop, v_after, *vp));
stack(0, v_result);
return JSRS_CONTINUE;
}
JS_REQUIRES_STACK JSRecordingStatus

View File

@ -709,8 +709,10 @@ class TraceRecorder : public avmplus::GCObject {
JS_REQUIRES_STACK JSRecordingStatus tableswitch();
#endif
JS_REQUIRES_STACK JSRecordingStatus inc(jsval& v, jsint incr, bool pre = true);
JS_REQUIRES_STACK JSRecordingStatus inc(jsval& v, nanojit::LIns*& v_ins, jsint incr,
bool pre = true);
JS_REQUIRES_STACK JSRecordingStatus inc(jsval v, nanojit::LIns*& v_ins, jsint incr,
bool pre = true);
JS_REQUIRES_STACK JSRecordingStatus incHelper(jsval v, nanojit::LIns* v_ins,
nanojit::LIns*& v_after, jsint incr);
JS_REQUIRES_STACK JSRecordingStatus incProp(jsint incr, bool pre = true);
JS_REQUIRES_STACK JSRecordingStatus incElem(jsint incr, bool pre = true);
JS_REQUIRES_STACK JSRecordingStatus incName(jsint incr, bool pre = true);

View File

@ -5664,6 +5664,25 @@ function testMultipleArgumentsObjects() {
testMultipleArgumentsObjects.expected = ",,,,f";
test(testMultipleArgumentsObjects);
function testClosureIncrSideExit() {
let(f = function (y) {
let(ff = function (g) {
for each(let h in g) {
if (++y > 5) {
return 'ddd';
}
}
return 'qqq';
}) {
return ff(['', null, '', false, '', '', null]);
}
}) {
return f(-1);
}
}
testClosureIncrSideExit.expected = "ddd";
test(testClosureIncrSideExit);
/*****************************************************************************
* *
* _____ _ _ _____ ______ _____ _______ *