зеркало из https://github.com/mozilla/gecko-dev.git
Bug 600779 - TM: allow for branches that are always taken. r=dmandelin.
This commit is contained in:
Родитель
0276090aa4
Коммит
cbe62cd2cb
|
@ -2512,10 +2512,10 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
|
||||||
LIns* counterPtr = INS_CONSTPTR((void *) &JS_THREAD_DATA(cx)->iterationCounter);
|
LIns* counterPtr = INS_CONSTPTR((void *) &JS_THREAD_DATA(cx)->iterationCounter);
|
||||||
LIns* counterValue = lir->insLoad(LIR_ldi, counterPtr, 0, ACCSET_OTHER, LOAD_VOLATILE);
|
LIns* counterValue = lir->insLoad(LIR_ldi, counterPtr, 0, ACCSET_OTHER, LOAD_VOLATILE);
|
||||||
LIns* test = lir->ins2ImmI(LIR_lti, counterValue, MIN_LOOP_ITERS);
|
LIns* test = lir->ins2ImmI(LIR_lti, counterValue, MIN_LOOP_ITERS);
|
||||||
LIns *branch = lir->insBranch(LIR_jf, test, NULL);
|
LIns *branch = unoptimizableCondBranch(LIR_jf, test);
|
||||||
counterValue = lir->ins2(LIR_addi, counterValue, INS_CONST(1));
|
counterValue = lir->ins2(LIR_addi, counterValue, INS_CONST(1));
|
||||||
lir->insStore(counterValue, counterPtr, 0, ACCSET_OTHER);
|
lir->insStore(counterValue, counterPtr, 0, ACCSET_OTHER);
|
||||||
label(branch);
|
labelForBranch(branch);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3964,8 +3964,7 @@ TraceRecorder::addr(Value* p)
|
||||||
{
|
{
|
||||||
return isGlobal(p)
|
return isGlobal(p)
|
||||||
? lir->ins2(LIR_addp, eos_ins, INS_CONSTWORD(nativeGlobalOffset(p)))
|
? lir->ins2(LIR_addp, eos_ins, INS_CONSTWORD(nativeGlobalOffset(p)))
|
||||||
: lir->ins2(LIR_addp, lirbuf->sp,
|
: lir->ins2(LIR_addp, lirbuf->sp, INS_CONSTWORD(nativespOffset(p)));
|
||||||
INS_CONSTWORD(nativespOffset(p)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_REQUIRES_STACK inline bool
|
JS_REQUIRES_STACK inline bool
|
||||||
|
@ -5374,13 +5373,13 @@ TraceRecorder::emitTreeCall(TreeFragment* inner, VMSideExit* exit)
|
||||||
#endif
|
#endif
|
||||||
LIns* rec = lir->insCall(ci, args);
|
LIns* rec = lir->insCall(ci, args);
|
||||||
LIns* lr = lir->insLoad(LIR_ldp, rec, offsetof(GuardRecord, exit), ACCSET_OTHER);
|
LIns* lr = lir->insLoad(LIR_ldp, rec, offsetof(GuardRecord, exit), ACCSET_OTHER);
|
||||||
LIns* nested = lir->insBranch(LIR_jt,
|
LIns* nested =
|
||||||
lir->ins2ImmI(LIR_eqi,
|
unoptimizableCondBranch(LIR_jt,
|
||||||
lir->insLoad(LIR_ldi, lr,
|
lir->ins2ImmI(LIR_eqi,
|
||||||
offsetof(VMSideExit, exitType),
|
lir->insLoad(LIR_ldi, lr,
|
||||||
ACCSET_OTHER),
|
offsetof(VMSideExit, exitType),
|
||||||
NESTED_EXIT),
|
ACCSET_OTHER),
|
||||||
NULL);
|
NESTED_EXIT));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the tree exits on a regular (non-nested) guard, keep updating lastTreeExitGuard
|
* If the tree exits on a regular (non-nested) guard, keep updating lastTreeExitGuard
|
||||||
|
@ -5395,13 +5394,13 @@ TraceRecorder::emitTreeCall(TreeFragment* inner, VMSideExit* exit)
|
||||||
* and we unwind the tree call stack. We store the first (innermost) tree call guard in state
|
* and we unwind the tree call stack. We store the first (innermost) tree call guard in state
|
||||||
* and we will try to grow the outer tree the failing call was in starting at that guard.
|
* and we will try to grow the outer tree the failing call was in starting at that guard.
|
||||||
*/
|
*/
|
||||||
label(nested);
|
labelForBranch(nested);
|
||||||
LIns* done2 = lir->insBranch(LIR_jf,
|
LIns* done2 =
|
||||||
lir->insEqP_0(lir->insLoad(LIR_ldp,
|
unoptimizableCondBranch(LIR_jf,
|
||||||
lirbuf->state,
|
lir->insEqP_0(lir->insLoad(LIR_ldp,
|
||||||
offsetof(TracerState, lastTreeCallGuard),
|
lirbuf->state,
|
||||||
ACCSET_OTHER)),
|
offsetof(TracerState, lastTreeCallGuard),
|
||||||
NULL);
|
ACCSET_OTHER)));
|
||||||
lir->insStore(lr, lirbuf->state, offsetof(TracerState, lastTreeCallGuard), ACCSET_OTHER);
|
lir->insStore(lr, lirbuf->state, offsetof(TracerState, lastTreeCallGuard), ACCSET_OTHER);
|
||||||
lir->insStore(lir->ins2(LIR_addp,
|
lir->insStore(lir->ins2(LIR_addp,
|
||||||
lir->insLoad(LIR_ldp, lirbuf->state, offsetof(TracerState, rp),
|
lir->insLoad(LIR_ldp, lirbuf->state, offsetof(TracerState, rp),
|
||||||
|
@ -5413,7 +5412,7 @@ TraceRecorder::emitTreeCall(TreeFragment* inner, VMSideExit* exit)
|
||||||
sizeof(void*) == 4 ? 2 : 3))),
|
sizeof(void*) == 4 ? 2 : 3))),
|
||||||
lirbuf->state,
|
lirbuf->state,
|
||||||
offsetof(TracerState, rpAtLastTreeCall), ACCSET_OTHER);
|
offsetof(TracerState, rpAtLastTreeCall), ACCSET_OTHER);
|
||||||
label(done1, done2);
|
labelForBranches(done1, done2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep updating outermostTreeExit so that TracerState always contains the most recent
|
* Keep updating outermostTreeExit so that TracerState always contains the most recent
|
||||||
|
@ -8406,12 +8405,14 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
|
||||||
* into -2147483648 / -1, because it can raise an overflow exception.
|
* into -2147483648 / -1, because it can raise an overflow exception.
|
||||||
*/
|
*/
|
||||||
if (!d1->isImmI()) {
|
if (!d1->isImmI()) {
|
||||||
LIns* gt = lir->insBranch(LIR_jt, lir->ins2ImmI(LIR_gti, d1, 0), NULL);
|
LIns* br;
|
||||||
guard(false, lir->insEqI_0(d1), exit);
|
if (condBranch(LIR_jt, lir->ins2ImmI(LIR_gti, d1, 0), &br)) {
|
||||||
guard(false, lir->ins2(LIR_andi,
|
guard(false, lir->insEqI_0(d1), exit);
|
||||||
lir->ins2ImmI(LIR_eqi, d0, 0x80000000),
|
guard(false, lir->ins2(LIR_andi,
|
||||||
lir->ins2ImmI(LIR_eqi, d1, -1)), exit);
|
lir->ins2ImmI(LIR_eqi, d0, 0x80000000),
|
||||||
label(gt);
|
lir->ins2ImmI(LIR_eqi, d1, -1)), exit);
|
||||||
|
labelForBranch(br);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (d1->immI() == -1)
|
if (d1->immI() == -1)
|
||||||
guard(false, lir->ins2ImmI(LIR_eqi, d0, 0x80000000), exit);
|
guard(false, lir->ins2ImmI(LIR_eqi, d0, 0x80000000), exit);
|
||||||
|
@ -8437,14 +8438,15 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
|
||||||
result = lir->ins1(v = LIR_modi, lir->ins2(LIR_divi, d0, d1));
|
result = lir->ins1(v = LIR_modi, lir->ins2(LIR_divi, d0, d1));
|
||||||
|
|
||||||
/* If the result is not 0, it is always within the integer domain. */
|
/* If the result is not 0, it is always within the integer domain. */
|
||||||
LIns* branch = lir->insBranch(LIR_jf, lir->insEqI_0(result), NULL);
|
LIns* br;
|
||||||
|
if (condBranch(LIR_jf, lir->insEqI_0(result), &br)) {
|
||||||
/*
|
/*
|
||||||
* If the result is zero, we must exit if the lhs is negative since
|
* If the result is zero, we must exit if the lhs is negative since
|
||||||
* the result is -0 in this case, which is not in the integer domain.
|
* the result is -0 in this case, which is not in the integer domain.
|
||||||
*/
|
*/
|
||||||
guard(false, lir->ins2ImmI(LIR_lti, d0, 0), exit);
|
guard(false, lir->ins2ImmI(LIR_lti, d0, 0), exit);
|
||||||
label(branch);
|
labelForBranch(br);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -8482,24 +8484,68 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
|
||||||
return lir->ins1(LIR_i2d, result);
|
return lir->ins1(LIR_i2d, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inserts a label and updates 'branch' to branch to it, if 'branch' is non-NULL. */
|
/*
|
||||||
void
|
* If the branch is always taken, return false; the code jumped over by the
|
||||||
TraceRecorder::label(LIns* br)
|
* branch need not be generated. If the branch is never taken, return true
|
||||||
|
* and put NULL in *brOut. Otherwise, return true and put the branch in
|
||||||
|
* *brOut.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
TraceRecorder::condBranch(LOpcode op, LIns* cond, LIns** brOut)
|
||||||
{
|
{
|
||||||
if (br)
|
JS_ASSERT(op == LIR_jt || op == LIR_jf);
|
||||||
br->setTarget(lir->ins0(LIR_label));
|
*brOut = NULL;
|
||||||
|
if (cond->isImmI()) {
|
||||||
|
int32 condval = cond->immI();
|
||||||
|
JS_ASSERT(condval == 0 || condval == 1);
|
||||||
|
if ((op == LIR_jt && condval == 1) || (op == LIR_jf && condval == 0))
|
||||||
|
return false; /* branch is always taken */
|
||||||
|
}
|
||||||
|
*brOut = lir->insBranch(op, cond, NULL);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Similar to the other label(), but for two branches. */
|
/*
|
||||||
|
* Like condBranch(), but for when we know the branch condition cannot be
|
||||||
|
* optimized to a constant, eg. because one of the operands is the result of a
|
||||||
|
* volatile load.
|
||||||
|
*/
|
||||||
|
LIns*
|
||||||
|
TraceRecorder::unoptimizableCondBranch(LOpcode op, LIns* cond)
|
||||||
|
{
|
||||||
|
JS_ASSERT(op == LIR_jt || op == LIR_jf);
|
||||||
|
JS_ASSERT(!cond->isImmI());
|
||||||
|
return lir->insBranch(op, cond, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inserts a label and updates 'branch' to branch to it, if 'branch' is non-NULL.
|
||||||
|
* ('branch' may be NULL if it was a conditional branch and its condition was
|
||||||
|
* a constant value that resulted in the branch never being taken.)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
TraceRecorder::label(LIns* br1, LIns* br2)
|
TraceRecorder::labelForBranch(LIns* br)
|
||||||
|
{
|
||||||
|
if (br) {
|
||||||
|
JS_ASSERT(br->isop(LIR_j) || br->isop(LIR_jt) || br->isop(LIR_jf));
|
||||||
|
br->setTarget(lir->ins0(LIR_label));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar to the other labelForBranch(), but for two branches. */
|
||||||
|
void
|
||||||
|
TraceRecorder::labelForBranches(LIns* br1, LIns* br2)
|
||||||
{
|
{
|
||||||
if (br1 || br2) {
|
if (br1 || br2) {
|
||||||
LIns* label = lir->ins0(LIR_label);
|
LIns* label = lir->ins0(LIR_label);
|
||||||
if (br1)
|
if (br1) {
|
||||||
|
JS_ASSERT(br1->isop(LIR_j) || br1->isop(LIR_jt) || br1->isop(LIR_jf));
|
||||||
br1->setTarget(label);
|
br1->setTarget(label);
|
||||||
if (br2)
|
}
|
||||||
|
if (br2) {
|
||||||
|
JS_ASSERT(br2->isop(LIR_j) || br2->isop(LIR_jt) || br2->isop(LIR_jf));
|
||||||
br2->setTarget(label);
|
br2->setTarget(label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10587,17 +10633,22 @@ TraceRecorder::record_JSOP_ARGUMENTS()
|
||||||
|
|
||||||
LIns* mem_ins = lir->insAlloc(sizeof(JSObject *));
|
LIns* mem_ins = lir->insAlloc(sizeof(JSObject *));
|
||||||
|
|
||||||
LIns* br1 = lir->insBranch(LIR_jt, lir->insEqP_0(a_ins), NULL);
|
LIns* isZero_ins = lir->insEqP_0(a_ins);
|
||||||
lir->insStore(a_ins, mem_ins, 0, ACCSET_OTHER);
|
if (isZero_ins->isImmI(0)) {
|
||||||
LIns* br2 = lir->insBranch(LIR_j, NULL, NULL);
|
lir->insStore(a_ins, mem_ins, 0, ACCSET_OTHER);
|
||||||
|
} else if (isZero_ins->isImmI(1)) {
|
||||||
label(br1);
|
LIns* call_ins = newArguments(callee_ins, strict);
|
||||||
|
lir->insStore(call_ins, mem_ins, 0, ACCSET_OTHER);
|
||||||
LIns* call_ins = newArguments(callee_ins, strict);
|
} else {
|
||||||
lir->insStore(call_ins, mem_ins, 0, ACCSET_OTHER);
|
LIns* br1 = unoptimizableCondBranch(LIR_jt, isZero_ins);
|
||||||
|
lir->insStore(a_ins, mem_ins, 0, ACCSET_OTHER);
|
||||||
label(br2);
|
LIns* br2 = lir->insBranch(LIR_j, NULL, NULL);
|
||||||
|
labelForBranch(br1);
|
||||||
|
|
||||||
|
LIns* call_ins = newArguments(callee_ins, strict);
|
||||||
|
lir->insStore(call_ins, mem_ins, 0, ACCSET_OTHER);
|
||||||
|
labelForBranch(br2);
|
||||||
|
}
|
||||||
args_ins = lir->insLoad(LIR_ldp, mem_ins, 0, ACCSET_OTHER);
|
args_ins = lir->insLoad(LIR_ldp, mem_ins, 0, ACCSET_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12530,13 +12581,16 @@ TraceRecorder::getCharCodeAt(JSString *str, LIns* str_ins, LIns* idx_ins, LIns**
|
||||||
idx_ins = lir->insUI2P(idx_ins);
|
idx_ins = lir->insUI2P(idx_ins);
|
||||||
LIns *length_ins = lir->insLoad(LIR_ldp, str_ins, offsetof(JSString, mLengthAndFlags),
|
LIns *length_ins = lir->insLoad(LIR_ldp, str_ins, offsetof(JSString, mLengthAndFlags),
|
||||||
ACCSET_OTHER);
|
ACCSET_OTHER);
|
||||||
LIns *br = lir->insBranch(LIR_jt,
|
LIns *br;
|
||||||
lir->insEqP_0(lir->ins2(LIR_andp,
|
if (condBranch(LIR_jt,
|
||||||
length_ins,
|
lir->insEqP_0(lir->ins2(LIR_andp,
|
||||||
INS_CONSTWORD(JSString::ROPE_BIT))),
|
length_ins,
|
||||||
NULL);
|
INS_CONSTWORD(JSString::ROPE_BIT))),
|
||||||
lir->insCall(&js_Flatten_ci, &str_ins);
|
&br))
|
||||||
label(br);
|
{
|
||||||
|
lir->insCall(&js_Flatten_ci, &str_ins);
|
||||||
|
labelForBranch(br);
|
||||||
|
}
|
||||||
|
|
||||||
guard(true,
|
guard(true,
|
||||||
lir->ins2(LIR_ltup, idx_ins, lir->ins2ImmI(LIR_rshup, length_ins, JSString::FLAGS_LENGTH_SHIFT)),
|
lir->ins2(LIR_ltup, idx_ins, lir->ins2ImmI(LIR_rshup, length_ins, JSString::FLAGS_LENGTH_SHIFT)),
|
||||||
|
@ -12576,13 +12630,16 @@ TraceRecorder::getCharAt(JSString *str, LIns* str_ins, LIns* idx_ins, JSOp mode,
|
||||||
LIns *length_ins = lir->insLoad(LIR_ldp, str_ins, offsetof(JSString, mLengthAndFlags),
|
LIns *length_ins = lir->insLoad(LIR_ldp, str_ins, offsetof(JSString, mLengthAndFlags),
|
||||||
ACCSET_OTHER);
|
ACCSET_OTHER);
|
||||||
|
|
||||||
LIns *br1 = lir->insBranch(LIR_jt,
|
LIns *br1;
|
||||||
lir->insEqP_0(lir->ins2(LIR_andp,
|
if (condBranch(LIR_jt,
|
||||||
length_ins,
|
lir->insEqP_0(lir->ins2(LIR_andp,
|
||||||
INS_CONSTWORD(JSString::ROPE_BIT))),
|
length_ins,
|
||||||
NULL);
|
INS_CONSTWORD(JSString::ROPE_BIT))),
|
||||||
lir->insCall(&js_Flatten_ci, &str_ins);
|
&br1))
|
||||||
label(br1);
|
{
|
||||||
|
lir->insCall(&js_Flatten_ci, &str_ins);
|
||||||
|
labelForBranch(br1);
|
||||||
|
}
|
||||||
|
|
||||||
LIns* inRange = lir->ins2(LIR_ltup,
|
LIns* inRange = lir->ins2(LIR_ltup,
|
||||||
idx_ins,
|
idx_ins,
|
||||||
|
@ -12596,11 +12653,12 @@ TraceRecorder::getCharAt(JSString *str, LIns* str_ins, LIns* idx_ins, JSOp mode,
|
||||||
LIns *phi_ins = lir->insAlloc(sizeof(JSString *));
|
LIns *phi_ins = lir->insAlloc(sizeof(JSString *));
|
||||||
lir->insStore(LIR_stp, INS_CONSTSTR(cx->runtime->emptyString), phi_ins, 0, ACCSET_OTHER);
|
lir->insStore(LIR_stp, INS_CONSTSTR(cx->runtime->emptyString), phi_ins, 0, ACCSET_OTHER);
|
||||||
|
|
||||||
LIns* br2 = lir->insBranch(LIR_jf, inRange, NULL);
|
LIns* br2;
|
||||||
LIns *unitstr_ins = getUnitString(str_ins, idx_ins);
|
if (condBranch(LIR_jf, inRange, &br2)) {
|
||||||
lir->insStore(LIR_stp, unitstr_ins, phi_ins, 0, ACCSET_OTHER);
|
LIns *unitstr_ins = getUnitString(str_ins, idx_ins);
|
||||||
label(br2);
|
lir->insStore(LIR_stp, unitstr_ins, phi_ins, 0, ACCSET_OTHER);
|
||||||
|
labelForBranch(br2);
|
||||||
|
}
|
||||||
*out = lir->insLoad(LIR_ldp, phi_ins, 0, ACCSET_OTHER);
|
*out = lir->insLoad(LIR_ldp, phi_ins, 0, ACCSET_OTHER);
|
||||||
}
|
}
|
||||||
return RECORD_CONTINUE;
|
return RECORD_CONTINUE;
|
||||||
|
@ -13069,11 +13127,13 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
||||||
addName(lir->insLoad(LIR_ldi, obj_ins,
|
addName(lir->insLoad(LIR_ldi, obj_ins,
|
||||||
offsetof(JSObject, capacity), ACCSET_OTHER),
|
offsetof(JSObject, capacity), ACCSET_OTHER),
|
||||||
"capacity");
|
"capacity");
|
||||||
LIns* br = lir->insBranch(LIR_jt, lir->ins2(LIR_ltui, idx_ins, capacity_ins), NULL);
|
LIns* br;
|
||||||
LIns* args[] = { idx_ins, obj_ins, cx_ins };
|
if (condBranch(LIR_jt, lir->ins2(LIR_ltui, idx_ins, capacity_ins), &br)) {
|
||||||
LIns* res_ins = lir->insCall(&js_EnsureDenseArrayCapacity_ci, args);
|
LIns* args[] = { idx_ins, obj_ins, cx_ins };
|
||||||
guard(false, lir->insEqI_0(res_ins), mismatchExit);
|
LIns* res_ins = lir->insCall(&js_EnsureDenseArrayCapacity_ci, args);
|
||||||
label(br);
|
guard(false, lir->insEqI_0(res_ins), mismatchExit);
|
||||||
|
labelForBranch(br);
|
||||||
|
}
|
||||||
|
|
||||||
// Get the address of the element.
|
// Get the address of the element.
|
||||||
LIns *dslots_ins =
|
LIns *dslots_ins =
|
||||||
|
@ -13096,12 +13156,14 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
||||||
JSVAL_TAG_SHIFT)),
|
JSVAL_TAG_SHIFT)),
|
||||||
#endif
|
#endif
|
||||||
INS_CONSTU(JSVAL_TAG_MAGIC));
|
INS_CONSTU(JSVAL_TAG_MAGIC));
|
||||||
LIns* br2 = lir->insBranch(LIR_jf, cond, NULL);
|
LIns* br2;
|
||||||
LIns* args2[] = { idx_ins, obj_ins, cx_ins };
|
if (condBranch(LIR_jf, cond, &br2)) {
|
||||||
LIns* res_ins2 = addName(lir->insCall(&js_Array_dense_setelem_hole_ci, args2),
|
LIns* args[] = { idx_ins, obj_ins, cx_ins };
|
||||||
"hasNoIndexedProperties");
|
LIns* res_ins = addName(lir->insCall(&js_Array_dense_setelem_hole_ci, args),
|
||||||
guard(false, lir->insEqI_0(res_ins2), mismatchExit);
|
"hasNoIndexedProperties");
|
||||||
label(br2);
|
guard(false, lir->insEqI_0(res_ins), mismatchExit);
|
||||||
|
labelForBranch(br2);
|
||||||
|
}
|
||||||
|
|
||||||
// Right, actually set the element.
|
// Right, actually set the element.
|
||||||
box_value_into(v, v_ins, addr_ins, 0, ACCSET_OTHER);
|
box_value_into(v, v_ins, addr_ins, 0, ACCSET_OTHER);
|
||||||
|
@ -15347,9 +15409,11 @@ TraceRecorder::record_JSOP_ARGCNT()
|
||||||
RETURN_STOP_A("can't trace JSOP_ARGCNT if arguments.length has been modified");
|
RETURN_STOP_A("can't trace JSOP_ARGCNT if arguments.length has been modified");
|
||||||
LIns *a_ins = getFrameObjPtr(fp->addressOfArgs());
|
LIns *a_ins = getFrameObjPtr(fp->addressOfArgs());
|
||||||
if (callDepth == 0) {
|
if (callDepth == 0) {
|
||||||
LIns *br = lir->insBranch(LIR_jt, lir->insEqP_0(a_ins), NULL);
|
LIns *br;
|
||||||
guardArgsLengthNotAssigned(a_ins);
|
if (condBranch(LIR_jt, lir->insEqP_0(a_ins), &br)) {
|
||||||
label(br);
|
guardArgsLengthNotAssigned(a_ins);
|
||||||
|
labelForBranch(br);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack(0, lir->insImmD(fp->numActualArgs()));
|
stack(0, lir->insImmD(fp->numActualArgs()));
|
||||||
return ARECORD_CONTINUE;
|
return ARECORD_CONTINUE;
|
||||||
|
|
|
@ -1115,8 +1115,11 @@ class TraceRecorder
|
||||||
JS_REQUIRES_STACK nanojit::LIns* alu(nanojit::LOpcode op, jsdouble v0, jsdouble v1,
|
JS_REQUIRES_STACK nanojit::LIns* alu(nanojit::LOpcode op, jsdouble v0, jsdouble v1,
|
||||||
nanojit::LIns* s0, nanojit::LIns* s1);
|
nanojit::LIns* s0, nanojit::LIns* s1);
|
||||||
|
|
||||||
void label(nanojit::LIns* br);
|
bool condBranch(nanojit::LOpcode op, nanojit::LIns* cond, nanojit::LIns** brOut);
|
||||||
void label(nanojit::LIns* br1, nanojit::LIns* br2);
|
nanojit::LIns* unoptimizableCondBranch(nanojit::LOpcode op, nanojit::LIns* cond);
|
||||||
|
void labelForBranch(nanojit::LIns* br);
|
||||||
|
void labelForBranches(nanojit::LIns* br1, nanojit::LIns* br2);
|
||||||
|
|
||||||
nanojit::LIns* i2d(nanojit::LIns* i);
|
nanojit::LIns* i2d(nanojit::LIns* i);
|
||||||
nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false);
|
nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false);
|
||||||
nanojit::LIns* f2u(nanojit::LIns* f);
|
nanojit::LIns* f2u(nanojit::LIns* f);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче