From ee58225166bee4ad54e73157a62e50e4ff5b3175 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 15 Apr 2010 17:12:28 -0700 Subject: [PATCH] Bug 558814 - nanojit: handle const conditions for LIR_jt/LIR_jf (TM-specific part). r=dvander. --- js/src/jstracer.cpp | 44 +++++++++++----------- js/src/trace-test/tests/basic/bug558814.js | 10 +++++ 2 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 js/src/trace-test/tests/basic/bug558814.js diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 0719e155c2e6..672b92a514be 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -13017,29 +13017,31 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_ } /* If not idx < length, stay on trace (and read value as undefined). */ - LIns* br2 = lir->insBranch(LIR_jf, - lir->ins2(LIR_pult, - pidx_ins, - stobj_get_fslot(obj_ins, JSObject::JSSLOT_ARRAY_LENGTH)), - NULL); + LIns* length = stobj_get_fslot(obj_ins, JSObject::JSSLOT_ARRAY_LENGTH); + if (pidx_ins != length) { + LIns* br2 = lir->insBranch(LIR_jf, + lir->ins2(LIR_pult, pidx_ins, length), + NULL); - /* If dslots is NULL, stay on trace (and read value as undefined). */ - LIns* br3 = lir->insBranch(LIR_jt, lir->ins_peq0(dslots_ins), NULL); + /* If dslots is NULL, stay on trace (and read value as undefined). */ + LIns* br3 = lir->insBranch(LIR_jt, lir->ins_peq0(dslots_ins), NULL); - /* If not idx < capacity, stay on trace (and read value as undefined). */ - LIns* br4 = lir->insBranch(LIR_jf, - lir->ins2(LIR_pult, - pidx_ins, - lir->insLoad(LIR_ldp, dslots_ins, - -(int)sizeof(jsval), ACC_OTHER)), - NULL); - lir->insGuard(LIR_x, NULL, createGuardRecord(exit)); - LIns* label = lir->ins0(LIR_label); - if (br1) - br1->setTarget(label); - br2->setTarget(label); - br3->setTarget(label); - br4->setTarget(label); + /* If not idx < capacity, stay on trace (and read value as undefined). */ + LIns* br4 = lir->insBranch(LIR_jf, + lir->ins2(LIR_pult, + pidx_ins, + lir->insLoad(LIR_ldp, dslots_ins, + -(int)sizeof(jsval), ACC_OTHER)), + NULL); + + lir->insGuard(LIR_x, NULL, createGuardRecord(exit)); + LIns* label = lir->ins0(LIR_label); + if (br1) + br1->setTarget(label); + br2->setTarget(label); + br3->setTarget(label); + br4->setTarget(label); + } CHECK_STATUS(guardPrototypeHasNoIndexedProperties(obj, obj_ins, MISMATCH_EXIT)); diff --git a/js/src/trace-test/tests/basic/bug558814.js b/js/src/trace-test/tests/basic/bug558814.js new file mode 100644 index 000000000000..63a9f877ba2c --- /dev/null +++ b/js/src/trace-test/tests/basic/bug558814.js @@ -0,0 +1,10 @@ +function f() +{ + var a = []; + a.length = 10; + for (var i = 0; i < 100; i++) { + var y = a[a.length]; + } +} +f(); +// No assertEq() call, the test is just that it shouldn't assert or crash.