mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset cc7311c09b56 (bug 602397) due to Maemo Talos breakage.
This commit is contained in:
parent
76f4d326e3
commit
585033aa98
@ -1713,6 +1713,51 @@ fcallinfo(LIns *ins)
|
|||||||
return ins->isop(LIR_calld) ? ins->callInfo() : NULL;
|
return ins->isop(LIR_calld) ? ins->callInfo() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine whether this operand is guaranteed to not overflow the specified
|
||||||
|
* integer operation.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ChecksRequired(LOpcode op, LIns* op1, LIns* op2,
|
||||||
|
bool* needsOverflowCheck, bool* needsNegZeroCheck)
|
||||||
|
{
|
||||||
|
Interval x = Interval::of(op1, 3);
|
||||||
|
Interval y = Interval::of(op2, 3);
|
||||||
|
Interval z(0, 0);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case LIR_addi:
|
||||||
|
z = Interval::add(x, y);
|
||||||
|
*needsNegZeroCheck = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_subi:
|
||||||
|
z = Interval::sub(x, y);
|
||||||
|
*needsNegZeroCheck = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_muli: {
|
||||||
|
z = Interval::mul(x, y);
|
||||||
|
// A would-be negative zero result can only occur if we have
|
||||||
|
// mul(0, -n) or mul(-n, 0), where n != 0. In particular, a multiply
|
||||||
|
// where one operand is a positive immediate cannot result in negative
|
||||||
|
// zero.
|
||||||
|
//
|
||||||
|
// This assumes that -0 cannot be an operand; if one had occurred we
|
||||||
|
// would have already exited the trace in order to promote the
|
||||||
|
// computation back to doubles.
|
||||||
|
*needsNegZeroCheck = (x.canBeZero() && y.canBeNegative()) ||
|
||||||
|
(y.canBeZero() && x.canBeNegative());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
JS_NOT_REACHED("needsOverflowCheck");
|
||||||
|
}
|
||||||
|
|
||||||
|
*needsOverflowCheck = z.hasOverflowed;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* JSStackFrame::numActualArgs is only defined for function frames. Since the
|
* JSStackFrame::numActualArgs is only defined for function frames. Since the
|
||||||
* actual arguments of the entry frame are kept on trace, argc is included in
|
* actual arguments of the entry frame are kept on trace, argc is included in
|
||||||
@ -4424,6 +4469,30 @@ TraceRecorder::guard(bool expected, LIns* cond, ExitType exitType,
|
|||||||
return guard(expected, cond, snapshot(exitType), abortIfAlwaysExits);
|
return guard(expected, cond, snapshot(exitType), abortIfAlwaysExits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit a guard a 32-bit integer arithmetic operation op(d0, d1) and
|
||||||
|
* using the supplied side exit if it overflows.
|
||||||
|
*/
|
||||||
|
JS_REQUIRES_STACK LIns*
|
||||||
|
TraceRecorder::guard_xov(LOpcode op, LIns* d0, LIns* d1, VMSideExit* exit)
|
||||||
|
{
|
||||||
|
JS_ASSERT(exit->exitType == OVERFLOW_EXIT);
|
||||||
|
|
||||||
|
GuardRecord* guardRec = createGuardRecord(exit);
|
||||||
|
switch (op) {
|
||||||
|
case LIR_addi:
|
||||||
|
return w.addxovi(d0, d1, guardRec);
|
||||||
|
case LIR_subi:
|
||||||
|
return w.subxovi(d0, d1, guardRec);
|
||||||
|
case LIR_muli:
|
||||||
|
return w.mulxovi(d0, d1, guardRec);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JS_NOT_REACHED("unexpected opcode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
JS_REQUIRES_STACK VMSideExit*
|
JS_REQUIRES_STACK VMSideExit*
|
||||||
TraceRecorder::copy(VMSideExit* copy)
|
TraceRecorder::copy(VMSideExit* copy)
|
||||||
{
|
{
|
||||||
@ -8320,31 +8389,17 @@ TraceRecorder::guardNonNeg(LIns* d0, LIns* d1, VMSideExit* exit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JS_REQUIRES_STACK LIns*
|
JS_REQUIRES_STACK LIns*
|
||||||
TraceRecorder::tryToDemote(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
|
TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If the operands and result of an arithmetic operation are all integers
|
* To even consider this operation for demotion, both operands have to be
|
||||||
* at record-time, and the oracle doesn't direct us otherwise, we
|
* integers and the oracle must not give us a negative hint for the
|
||||||
* speculatively emit a demoted (integer) operation, betting that at
|
* instruction.
|
||||||
* runtime we will get integer results again.
|
|
||||||
*
|
|
||||||
* We also have to protect against various edge cases. For example,
|
|
||||||
* to protect against overflow we emit a guard that will inform the oracle
|
|
||||||
* on overflow and cause a non-demoted trace to be attached that uses
|
|
||||||
* floating-point math for this operation; the exception to this case is
|
|
||||||
* if the operands guarantee that the result will be an integer (e.g.
|
|
||||||
* z = d0 * d1 with 0 <= (d0|d1) <= 0xffff guarantees z <= fffe0001).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!oracle || oracle->isInstructionUndemotable(cx->regs->pc) ||
|
if (!oracle || oracle->isInstructionUndemotable(cx->regs->pc) ||
|
||||||
!IsPromotedInt32(s0) || !IsPromotedInt32(s1))
|
!IsPromotedInt32(s0) || !IsPromotedInt32(s1)) {
|
||||||
{
|
out:
|
||||||
undemotable:
|
|
||||||
if (v == LIR_modd) {
|
if (v == LIR_modd) {
|
||||||
/*
|
|
||||||
* LIR_modd is a placeholder that Nanojit doesn't actually support!
|
|
||||||
* Convert it to a call.
|
|
||||||
*/
|
|
||||||
LIns* args[] = { s1, s0 };
|
LIns* args[] = { s1, s0 };
|
||||||
return w.call(&js_dmod_ci, args);
|
return w.call(&js_dmod_ci, args);
|
||||||
}
|
}
|
||||||
@ -8353,96 +8408,58 @@ TraceRecorder::tryToDemote(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns*
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jsdouble r;
|
||||||
|
switch (v) {
|
||||||
|
case LIR_addd:
|
||||||
|
r = v0 + v1;
|
||||||
|
break;
|
||||||
|
case LIR_subd:
|
||||||
|
r = v0 - v1;
|
||||||
|
break;
|
||||||
|
case LIR_muld:
|
||||||
|
r = v0 * v1;
|
||||||
|
if (r == 0.0 && (v0 < 0.0 || v1 < 0.0))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
#if defined NANOJIT_IA32 || defined NANOJIT_X64
|
||||||
|
case LIR_divd:
|
||||||
|
if (v1 == 0)
|
||||||
|
goto out;
|
||||||
|
r = v0 / v1;
|
||||||
|
break;
|
||||||
|
case LIR_modd:
|
||||||
|
if (v0 < 0 || v1 == 0 || (s1->isImmD() && v1 < 0))
|
||||||
|
goto out;
|
||||||
|
r = js_dmod(v0, v1);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The result must be an integer at record time, otherwise there is no
|
||||||
|
* point in trying to demote it.
|
||||||
|
*/
|
||||||
|
if (jsint(r) != r || JSDOUBLE_IS_NEGZERO(r))
|
||||||
|
goto out;
|
||||||
|
|
||||||
LIns* d0 = w.demoteToInt32(s0);
|
LIns* d0 = w.demoteToInt32(s0);
|
||||||
LIns* d1 = w.demoteToInt32(s1);
|
LIns* d1 = w.demoteToInt32(s1);
|
||||||
jsdouble r;
|
|
||||||
|
/*
|
||||||
|
* Speculatively emit an integer operation, betting that at runtime we
|
||||||
|
* will get integer results again.
|
||||||
|
*/
|
||||||
|
VMSideExit* exit = NULL;
|
||||||
LIns* result;
|
LIns* result;
|
||||||
|
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case LIR_addd: {
|
|
||||||
r = v0 + v1;
|
|
||||||
if (jsint(r) != r || JSDOUBLE_IS_NEGZERO(r))
|
|
||||||
goto undemotable;
|
|
||||||
|
|
||||||
Interval i0 = Interval::of(d0, 3);
|
|
||||||
Interval i1 = Interval::of(d1, 3);
|
|
||||||
result = Interval::add(i0, i1).hasOverflowed
|
|
||||||
? w.addxovi(d0, d1, createGuardRecord(snapshot(OVERFLOW_EXIT)))
|
|
||||||
: w.addi(d0, d1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LIR_subd: {
|
|
||||||
r = v0 - v1;
|
|
||||||
if (jsint(r) != r || JSDOUBLE_IS_NEGZERO(r))
|
|
||||||
goto undemotable;
|
|
||||||
|
|
||||||
Interval i0 = Interval::of(d0, 3);
|
|
||||||
Interval i1 = Interval::of(d1, 3);
|
|
||||||
result = Interval::sub(i0, i1).hasOverflowed
|
|
||||||
? w.subxovi(d0, d1, createGuardRecord(snapshot(OVERFLOW_EXIT)))
|
|
||||||
: w.subi(d0, d1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LIR_muld: {
|
|
||||||
r = v0 * v1;
|
|
||||||
if (jsint(r) != r || JSDOUBLE_IS_NEGZERO(r))
|
|
||||||
goto undemotable;
|
|
||||||
if (r == 0.0 && (v0 < 0.0 || v1 < 0.0))
|
|
||||||
goto undemotable;
|
|
||||||
|
|
||||||
Interval i0 = Interval::of(d0, 3);
|
|
||||||
Interval i1 = Interval::of(d1, 3);
|
|
||||||
result = Interval::mul(i0, i1).hasOverflowed
|
|
||||||
? w.mulxovi(d0, d1, createGuardRecord(snapshot(OVERFLOW_EXIT)))
|
|
||||||
: w.muli(d0, d1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A would-be negative zero result can only occur if we have
|
|
||||||
* mul(0, -n) or mul(-n, 0), where n != 0. In particular, a multiply
|
|
||||||
* where one operand is a positive immediate cannot result in negative
|
|
||||||
* zero.
|
|
||||||
*
|
|
||||||
* This assumes that -0 cannot be an operand; if one had occurred we
|
|
||||||
* would have already exited the trace in order to promote the
|
|
||||||
* computation back to doubles.
|
|
||||||
*/
|
|
||||||
bool needsNegZeroCheck = (i0.canBeZero() && i1.canBeNegative()) ||
|
|
||||||
(i1.canBeZero() && i0.canBeNegative());
|
|
||||||
if (needsNegZeroCheck) {
|
|
||||||
/*
|
|
||||||
* Make sure we don't lose a -0. We exit if the result is zero and if
|
|
||||||
* either operand is negative. We start out using a weaker guard, checking
|
|
||||||
* if either argument is negative. If this ever fails, we recompile with
|
|
||||||
* a stronger, but slower, guard.
|
|
||||||
*/
|
|
||||||
if (v0 < 0.0 || v1 < 0.0 || oracle->isInstructionSlowZeroTest(cx->regs->pc)) {
|
|
||||||
guard(true,
|
|
||||||
w.eqi0(w.andi(w.eqi0(result),
|
|
||||||
w.ori(w.ltiN(d0, 0),
|
|
||||||
w.ltiN(d1, 0)))),
|
|
||||||
snapshot(OVERFLOW_EXIT));
|
|
||||||
} else {
|
|
||||||
guardNonNeg(d0, d1, snapshot(MUL_ZERO_EXIT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined NANOJIT_IA32 || defined NANOJIT_X64
|
#if defined NANOJIT_IA32 || defined NANOJIT_X64
|
||||||
case LIR_divd: {
|
case LIR_divd:
|
||||||
if (v1 == 0)
|
|
||||||
goto undemotable;
|
|
||||||
r = v0 / v1;
|
|
||||||
if (jsint(r) != r || JSDOUBLE_IS_NEGZERO(r))
|
|
||||||
goto undemotable;
|
|
||||||
|
|
||||||
/* Check for this case ourselves; Nanojit won't do it for us. */
|
|
||||||
if (d0->isImmI() && d1->isImmI())
|
if (d0->isImmI() && d1->isImmI())
|
||||||
return w.i2d(w.immi(jsint(r)));
|
return w.i2d(w.immi(jsint(r)));
|
||||||
|
|
||||||
VMSideExit* exit = snapshot(OVERFLOW_EXIT);
|
exit = snapshot(OVERFLOW_EXIT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the divisor is greater than zero its always safe to execute
|
* If the divisor is greater than zero its always safe to execute
|
||||||
@ -8456,8 +8473,9 @@ TraceRecorder::tryToDemote(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns*
|
|||||||
w.eqiN(d1, -1))), exit);
|
w.eqiN(d1, -1))), exit);
|
||||||
w.label(mbr);
|
w.label(mbr);
|
||||||
}
|
}
|
||||||
} else if (d1->immI() == -1) {
|
} else {
|
||||||
guard(false, w.eqiN(d0, 0x80000000), exit);
|
if (d1->immI() == -1)
|
||||||
|
guard(false, w.eqiN(d0, 0x80000000), exit);
|
||||||
}
|
}
|
||||||
v = LIR_divi;
|
v = LIR_divi;
|
||||||
result = w.divi(d0, d1);
|
result = w.divi(d0, d1);
|
||||||
@ -8467,22 +8485,13 @@ TraceRecorder::tryToDemote(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns*
|
|||||||
|
|
||||||
/* Don't lose a -0. */
|
/* Don't lose a -0. */
|
||||||
guard(false, w.eqi0(result), exit);
|
guard(false, w.eqi0(result), exit);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case LIR_modd: {
|
case LIR_modd: {
|
||||||
if (v0 < 0 || v1 == 0 || (s1->isImmD() && v1 < 0))
|
|
||||||
goto undemotable;
|
|
||||||
r = js_dmod(v0, v1);
|
|
||||||
if (jsint(r) != r || JSDOUBLE_IS_NEGZERO(r))
|
|
||||||
goto undemotable;
|
|
||||||
|
|
||||||
/* Check for this case ourselves; Nanojit won't do it for us. */
|
|
||||||
if (d0->isImmI() && d1->isImmI())
|
if (d0->isImmI() && d1->isImmI())
|
||||||
return w.i2d(w.immi(jsint(r)));
|
return w.i2d(w.immi(jsint(r)));
|
||||||
|
|
||||||
VMSideExit* exit = snapshot(OVERFLOW_EXIT);
|
exit = snapshot(OVERFLOW_EXIT);
|
||||||
|
|
||||||
/* Make sure we don't trigger division by zero at runtime. */
|
/* Make sure we don't trigger division by zero at runtime. */
|
||||||
if (!d1->isImmI())
|
if (!d1->isImmI())
|
||||||
@ -8490,12 +8499,12 @@ TraceRecorder::tryToDemote(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns*
|
|||||||
v = LIR_modi;
|
v = LIR_modi;
|
||||||
result = w.modi(w.divi(d0, d1));
|
result = w.modi(w.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.
|
|
||||||
* Otherwise, we must exit if the lhs is negative since the result is
|
|
||||||
* -0 in this case, which is not in the integer domain.
|
|
||||||
*/
|
|
||||||
if (MaybeBranch mbr = w.jf(w.eqi0(result))) {
|
if (MaybeBranch mbr = w.jf(w.eqi0(result))) {
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
guard(false, w.ltiN(d0, 0), exit);
|
guard(false, w.ltiN(d0, 0), exit);
|
||||||
w.label(mbr);
|
w.label(mbr);
|
||||||
}
|
}
|
||||||
@ -8503,16 +8512,50 @@ TraceRecorder::tryToDemote(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
JS_NOT_REACHED("tryToDemote");
|
v = arithOpcodeD2I(v);
|
||||||
result = NULL;
|
JS_ASSERT(v == LIR_addi || v == LIR_muli || v == LIR_subi);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the operands guarantee that the result will be an integer (e.g.
|
||||||
|
* z = x * y with 0 <= (x|y) <= 0xffff guarantees z <= fffe0001), we
|
||||||
|
* don't have to guard against an overflow. Otherwise we emit a guard
|
||||||
|
* that will inform the oracle and cause a non-demoted trace to be
|
||||||
|
* attached that uses floating-point math for this operation.
|
||||||
|
*/
|
||||||
|
bool needsOverflowCheck = true, needsNegZeroCheck = true;
|
||||||
|
ChecksRequired(v, d0, d1, &needsOverflowCheck, &needsNegZeroCheck);
|
||||||
|
if (needsOverflowCheck) {
|
||||||
|
exit = snapshot(OVERFLOW_EXIT);
|
||||||
|
result = guard_xov(v, d0, d1, exit);
|
||||||
|
} else {
|
||||||
|
result = w.ins2(v, d0, d1);
|
||||||
|
}
|
||||||
|
if (needsNegZeroCheck) {
|
||||||
|
JS_ASSERT(v == LIR_muli);
|
||||||
|
/*
|
||||||
|
* Make sure we don't lose a -0. We exit if the result is zero and if
|
||||||
|
* either operand is negative. We start out using a weaker guard, checking
|
||||||
|
* if either argument is negative. If this ever fails, we recompile with
|
||||||
|
* a stronger, but slower, guard.
|
||||||
|
*/
|
||||||
|
if (v0 < 0.0 || v1 < 0.0
|
||||||
|
|| !oracle || oracle->isInstructionSlowZeroTest(cx->regs->pc))
|
||||||
|
{
|
||||||
|
if (!exit)
|
||||||
|
exit = snapshot(OVERFLOW_EXIT);
|
||||||
|
|
||||||
|
guard(true,
|
||||||
|
w.eqi0(w.andi(w.eqi0(result),
|
||||||
|
w.ori(w.ltiN(d0, 0),
|
||||||
|
w.ltiN(d1, 0)))),
|
||||||
|
exit);
|
||||||
|
} else {
|
||||||
|
guardNonNeg(d0, d1, snapshot(MUL_ZERO_EXIT));
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Successful demotion! Convert result to a double. This i2d will be
|
|
||||||
* removed if the result feeds into another integer or demoted operation.
|
|
||||||
*/
|
|
||||||
JS_ASSERT_IF(d0->isImmI() && d1->isImmI(), result->isImmI(jsint(r)));
|
JS_ASSERT_IF(d0->isImmI() && d1->isImmI(), result->isImmI(jsint(r)));
|
||||||
return w.i2d(result);
|
return w.i2d(result);
|
||||||
}
|
}
|
||||||
@ -8818,7 +8861,7 @@ TraceRecorder::incHelper(const Value &v, LIns*& v_ins, Value &v_after,
|
|||||||
AutoValueRooter tvr(cx);
|
AutoValueRooter tvr(cx);
|
||||||
*tvr.addr() = v;
|
*tvr.addr() = v;
|
||||||
ValueToNumber(cx, tvr.value(), &num);
|
ValueToNumber(cx, tvr.value(), &num);
|
||||||
v_ins_after = tryToDemote(LIR_addd, num, incr, v_ins, w.immd(incr));
|
v_ins_after = alu(LIR_addd, num, incr, v_ins, w.immd(incr));
|
||||||
v_after.setDouble(num + incr);
|
v_after.setDouble(num + incr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9272,13 +9315,17 @@ TraceRecorder::relational(LOpcode op, bool tryBranchAfterCond)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JS_REQUIRES_STACK RecordingStatus
|
JS_REQUIRES_STACK RecordingStatus
|
||||||
TraceRecorder::unaryIntOp(LOpcode op)
|
TraceRecorder::unary(LOpcode op)
|
||||||
{
|
{
|
||||||
Value& v = stackval(-1);
|
Value& v = stackval(-1);
|
||||||
JS_ASSERT(retTypes[op] == LTy_I);
|
bool intop = retTypes[op] == LTy_I;
|
||||||
if (v.isNumber()) {
|
if (v.isNumber()) {
|
||||||
LIns* a = get(&v);
|
LIns* a = get(&v);
|
||||||
a = w.i2d(w.ins1(op, d2i(a)));
|
if (intop)
|
||||||
|
a = d2i(a);
|
||||||
|
a = w.ins1(op, a);
|
||||||
|
if (intop)
|
||||||
|
a = w.i2d(a);
|
||||||
set(&v, a);
|
set(&v, a);
|
||||||
return RECORD_CONTINUE;
|
return RECORD_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -9362,12 +9409,12 @@ TraceRecorder::binary(LOpcode op)
|
|||||||
}
|
}
|
||||||
if (leftIsNumber && rightIsNumber) {
|
if (leftIsNumber && rightIsNumber) {
|
||||||
if (intop) {
|
if (intop) {
|
||||||
a = (op == LIR_rshui)
|
a = (op == LIR_rshui) ? d2u(a) : d2i(a);
|
||||||
? w.ui2d(w.ins2(op, d2u(a), d2i(b)))
|
b = d2i(b);
|
||||||
: w.i2d(w.ins2(op, d2i(a), d2i(b)));
|
|
||||||
} else {
|
|
||||||
a = tryToDemote(op, lnum, rnum, a, b);
|
|
||||||
}
|
}
|
||||||
|
a = alu(op, lnum, rnum, a, b);
|
||||||
|
if (intop)
|
||||||
|
a = (op == LIR_rshui) ? w.ui2d(a) : w.i2d(a);
|
||||||
set(&l, a);
|
set(&l, a);
|
||||||
return RECORD_CONTINUE;
|
return RECORD_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -10785,7 +10832,7 @@ TraceRecorder::record_JSOP_NOT()
|
|||||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||||
TraceRecorder::record_JSOP_BITNOT()
|
TraceRecorder::record_JSOP_BITNOT()
|
||||||
{
|
{
|
||||||
return InjectStatus(unaryIntOp(LIR_noti));
|
return InjectStatus(unary(LIR_noti));
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||||
@ -10814,7 +10861,7 @@ TraceRecorder::record_JSOP_NEG()
|
|||||||
-v.toNumber() == (int)-v.toNumber())
|
-v.toNumber() == (int)-v.toNumber())
|
||||||
{
|
{
|
||||||
VMSideExit* exit = snapshot(OVERFLOW_EXIT);
|
VMSideExit* exit = snapshot(OVERFLOW_EXIT);
|
||||||
a = w.subxovi(w.immi(0), w.demoteToInt32(a), createGuardRecord(exit));
|
a = guard_xov(LIR_subi, w.immi(0), w.demoteToInt32(a), exit);
|
||||||
if (!a->isImmI() && a->isop(LIR_subxovi)) {
|
if (!a->isImmI() && a->isop(LIR_subxovi)) {
|
||||||
guard(false, w.eqiN(a, 0), exit); // make sure we don't lose a -0
|
guard(false, w.eqiN(a, 0), exit); // make sure we don't lose a -0
|
||||||
}
|
}
|
||||||
@ -15707,7 +15754,7 @@ TraceRecorder::record_JSOP_ARGCNT()
|
|||||||
// interpreter, so we have to check for that in the trace entry frame.
|
// interpreter, so we have to check for that in the trace entry frame.
|
||||||
// We also have to check that arguments.length has not been mutated
|
// We also have to check that arguments.length has not been mutated
|
||||||
// at record time, because if so we will generate incorrect constant
|
// at record time, because if so we will generate incorrect constant
|
||||||
// LIR, which will assert in tryToDemote().
|
// LIR, which will assert in alu().
|
||||||
if (fp->hasArgsObj() && fp->argsObj().isArgsLengthOverridden())
|
if (fp->hasArgsObj() && fp->argsObj().isArgsLengthOverridden())
|
||||||
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());
|
||||||
|
@ -1199,6 +1199,8 @@ class TraceRecorder
|
|||||||
bool abortIfAlwaysExits = false);
|
bool abortIfAlwaysExits = false);
|
||||||
JS_REQUIRES_STACK RecordingStatus guard(bool expected, nanojit::LIns* cond, VMSideExit* exit,
|
JS_REQUIRES_STACK RecordingStatus guard(bool expected, nanojit::LIns* cond, VMSideExit* exit,
|
||||||
bool abortIfAlwaysExits = false);
|
bool abortIfAlwaysExits = false);
|
||||||
|
JS_REQUIRES_STACK nanojit::LIns* guard_xov(nanojit::LOpcode op, nanojit::LIns* d0,
|
||||||
|
nanojit::LIns* d1, VMSideExit* exit);
|
||||||
|
|
||||||
nanojit::LIns* writeBack(nanojit::LIns* i, nanojit::LIns* base, ptrdiff_t offset,
|
nanojit::LIns* writeBack(nanojit::LIns* i, nanojit::LIns* base, ptrdiff_t offset,
|
||||||
bool shouldDemoteToInt32);
|
bool shouldDemoteToInt32);
|
||||||
@ -1274,8 +1276,8 @@ class TraceRecorder
|
|||||||
JS_REQUIRES_STACK void stack(int n, nanojit::LIns* i);
|
JS_REQUIRES_STACK void stack(int n, nanojit::LIns* i);
|
||||||
|
|
||||||
JS_REQUIRES_STACK void guardNonNeg(nanojit::LIns* d0, nanojit::LIns* d1, VMSideExit* exit);
|
JS_REQUIRES_STACK void guardNonNeg(nanojit::LIns* d0, nanojit::LIns* d1, VMSideExit* exit);
|
||||||
JS_REQUIRES_STACK nanojit::LIns* tryToDemote(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);
|
||||||
|
|
||||||
nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false);
|
nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false);
|
||||||
nanojit::LIns* d2u(nanojit::LIns* d);
|
nanojit::LIns* d2u(nanojit::LIns* d);
|
||||||
@ -1311,7 +1313,7 @@ class TraceRecorder
|
|||||||
Value& rval);
|
Value& rval);
|
||||||
JS_REQUIRES_STACK AbortableRecordingStatus relational(nanojit::LOpcode op, bool tryBranchAfterCond);
|
JS_REQUIRES_STACK AbortableRecordingStatus relational(nanojit::LOpcode op, bool tryBranchAfterCond);
|
||||||
|
|
||||||
JS_REQUIRES_STACK RecordingStatus unaryIntOp(nanojit::LOpcode op);
|
JS_REQUIRES_STACK RecordingStatus unary(nanojit::LOpcode op);
|
||||||
JS_REQUIRES_STACK RecordingStatus binary(nanojit::LOpcode op);
|
JS_REQUIRES_STACK RecordingStatus binary(nanojit::LOpcode op);
|
||||||
|
|
||||||
JS_REQUIRES_STACK RecordingStatus guardShape(nanojit::LIns* obj_ins, JSObject* obj,
|
JS_REQUIRES_STACK RecordingStatus guardShape(nanojit::LIns* obj_ins, JSObject* obj,
|
||||||
|
Loading…
Reference in New Issue
Block a user