Bug 539553 - Correctness regression on the r-tree benchmark. r=dmandelin.

This commit is contained in:
Jason Orendorff 2010-01-14 18:23:05 -06:00
Родитель 7bd235775f
Коммит e4260dacfd
4 изменённых файлов: 40 добавлений и 8 удалений

Просмотреть файл

@ -13961,6 +13961,17 @@ TraceRecorder::record_JSOP_ARGSUB()
RETURN_STOP_A("can't trace JSOP_ARGSUB hard case"); RETURN_STOP_A("can't trace JSOP_ARGSUB hard case");
} }
JS_REQUIRES_STACK LIns*
TraceRecorder::guardArgsLengthNotAssigned(LIns* argsobj_ins)
{
// The following implements js_IsOverriddenArgsLength on trace.
// The '2' bit is set if length was overridden.
LIns *len_ins = stobj_get_fslot(argsobj_ins, JSSLOT_ARGS_LENGTH);
LIns *ovr_ins = lir->ins2(LIR_piand, len_ins, INS_CONSTWORD(2));
guard(true, lir->ins_peq0(ovr_ins), snapshot(BRANCH_EXIT));
return len_ins;
}
JS_REQUIRES_STACK AbortableRecordingStatus JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_ARGCNT() TraceRecorder::record_JSOP_ARGCNT()
{ {
@ -13978,13 +13989,7 @@ TraceRecorder::record_JSOP_ARGCNT()
LIns *a_ins = get(&cx->fp->argsobj); LIns *a_ins = get(&cx->fp->argsobj);
if (callDepth == 0) { if (callDepth == 0) {
LIns *br = lir->insBranch(LIR_jt, lir->ins_peq0(a_ins), NULL); LIns *br = lir->insBranch(LIR_jt, lir->ins_peq0(a_ins), NULL);
guardArgsLengthNotAssigned(a_ins);
// The following implements js_IsOverriddenArgsLength on trace.
// The '2' bit is set if length was overridden.
LIns *len_ins = stobj_get_fslot(a_ins, JSSLOT_ARGS_LENGTH);
LIns *ovr_ins = lir->ins2(LIR_piand, len_ins, INS_CONSTWORD(2));
guard(true, lir->ins_peq0(ovr_ins), snapshot(BRANCH_EXIT));
LIns *label = lir->ins0(LIR_label); LIns *label = lir->ins0(LIR_label);
br->setTarget(label); br->setTarget(label);
} }
@ -14827,7 +14832,15 @@ TraceRecorder::record_JSOP_LENGTH()
if (!afp) if (!afp)
RETURN_STOP_A("can't reach arguments object's frame"); RETURN_STOP_A("can't reach arguments object's frame");
LIns* v_ins = lir->ins1(LIR_i2f, INS_CONST(afp->argc)); // We must both check at record time and guard at run time that
// arguments.length has not been reassigned, redefined or deleted.
if (js_IsOverriddenArgsLength(obj))
RETURN_STOP_A("can't trace JSOP_ARGCNT if arguments.length has been modified");
LIns* slot_ins = guardArgsLengthNotAssigned(obj_ins);
// slot_ins is the value from the slot; right-shift by 2 bits to get
// the length (see GetArgsLength in jsfun.cpp).
LIns* v_ins = lir->ins1(LIR_i2f, lir->ins2i(LIR_rsh, slot_ins, 2));
set(&l, v_ins); set(&l, v_ins);
return ARECORD_CONTINUE; return ARECORD_CONTINUE;
} }

Просмотреть файл

@ -1297,6 +1297,7 @@ class TraceRecorder
JS_REQUIRES_STACK RecordingStatus guardCallee(jsval& callee); JS_REQUIRES_STACK RecordingStatus guardCallee(jsval& callee);
JS_REQUIRES_STACK JSStackFrame *guardArguments(JSObject *obj, nanojit::LIns* obj_ins, JS_REQUIRES_STACK JSStackFrame *guardArguments(JSObject *obj, nanojit::LIns* obj_ins,
unsigned *depthp); unsigned *depthp);
JS_REQUIRES_STACK nanojit::LIns* guardArgsLengthNotAssigned(nanojit::LIns* argsobj_ins);
JS_REQUIRES_STACK RecordingStatus getClassPrototype(JSObject* ctor, JS_REQUIRES_STACK RecordingStatus getClassPrototype(JSObject* ctor,
nanojit::LIns*& proto_ins); nanojit::LIns*& proto_ins);
JS_REQUIRES_STACK RecordingStatus getClassPrototype(JSProtoKey key, JS_REQUIRES_STACK RecordingStatus getClassPrototype(JSProtoKey key,

Просмотреть файл

@ -0,0 +1,7 @@
function f() {
var x = arguments;
arguments.length = {};
for (var i = 0; i < 9; i++)
x.length.toSource();
}
f();

Просмотреть файл

@ -0,0 +1,11 @@
function g(x) {
assertEq(x.length, 1);
}
function f() {
arguments.length = 1;
for (var i = 0; i < 9; i++)
g(arguments);
}
f();