author | Matthew Gaudet <mgaudet@mozilla.com> |
Tue, 01 May 2018 13:56:32 -0400 | |
changeset 428598 | 5b25886cfb6444c950bb40b01c306b0d74d1abc3 |
parent 428597 | b0ff1059472bf9435ae1c99dcd1a1471045262ba |
child 428599 | 7cb598e5f90c43782070de16aa1e82c7182483c5 |
push id | 34337 |
push user | ncsoregi@mozilla.com |
push date | Thu, 26 Jul 2018 21:58:45 +0000 |
treeherder | mozilla-central@8f2f847b2f9d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1438727 |
milestone | 63.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -4952,16 +4952,17 @@ DoCacheIRBinaryArithFallback(JSContext* // Ensure we're only generating for an enabled opcode. switch(op) { case JSOP_ADD: case JSOP_SUB: case JSOP_BITOR: case JSOP_BITXOR: case JSOP_BITAND: case JSOP_MUL: + case JSOP_DIV: break; default: return false; // Fallback to shared IC. } FallbackICSpew(cx, stub, "CacheIRBinaryArith(%s,%d,%d)", CodeName[op], int(lhs.isDouble() ? JSVAL_TYPE_DOUBLE : lhs.extractNonDoubleType()), int(rhs.isDouble() ? JSVAL_TYPE_DOUBLE : rhs.extractNonDoubleType()));
--- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -5154,17 +5154,18 @@ BinaryArithIRGenerator::tryAttachDouble( return true; } bool BinaryArithIRGenerator::tryAttachInt32() { if (op_ != JSOP_ADD && op_ != JSOP_SUB && op_ != JSOP_BITOR && op_ != JSOP_BITAND && - op_ != JSOP_BITXOR && op_ != JSOP_MUL) + op_ != JSOP_BITXOR && op_ != JSOP_MUL && + op_ != JSOP_DIV) { return false; } if (!lhs_.isInt32() || !rhs_.isInt32()) return false; ValOperandId lhsId(writer.setInputOperandId(0)); @@ -5181,16 +5182,20 @@ BinaryArithIRGenerator::tryAttachInt32() case JSOP_SUB: writer.int32SubResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.Int32.Sub"); break; case JSOP_MUL: writer.int32MulResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.Int32.Mul"); break; + case JSOP_DIV: + writer.int32DivResult(lhsIntId, rhsIntId); + trackAttached("BinaryArith.Int32.Div"); + break; case JSOP_BITOR: writer.int32BitOrResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.Int32.BitOr"); break; case JSOP_BITXOR: writer.int32BitXOrResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.Int32.BitXOr"); break; @@ -5206,17 +5211,17 @@ BinaryArithIRGenerator::tryAttachInt32() return true; } bool BinaryArithIRGenerator::tryAttachBooleanWithInt32() { if (op_ != JSOP_ADD && op_ != JSOP_SUB && op_ != JSOP_BITOR && op_ != JSOP_BITAND && - op_ != JSOP_BITXOR && op_!= JSOP_MUL) + op_ != JSOP_BITXOR && op_ != JSOP_MUL && op_ != JSOP_DIV) return false; if (!(lhs_.isBoolean() && (rhs_.isBoolean() || rhs_.isInt32())) && !(rhs_.isBoolean() && (lhs_.isBoolean() || lhs_.isInt32()))) return false; ValOperandId lhsId(writer.setInputOperandId(0)); @@ -5235,16 +5240,20 @@ BinaryArithIRGenerator::tryAttachBoolean case JSOP_SUB: writer.int32SubResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.BooleanInt32.Sub"); break; case JSOP_MUL: writer.int32MulResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.BooleanInt32.Mul"); break; + case JSOP_DIV: + writer.int32DivResult(lhsIntId, rhsIntId); + trackAttached("BinaryArith.BooleanInt32.Div"); + break; case JSOP_BITOR: writer.int32BitOrResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.BooleanInt32.BitOr"); break; case JSOP_BITXOR: writer.int32BitXOrResult(lhsIntId, rhsIntId); trackAttached("BinaryArith.BooleanInt32.BitXOr"); break;
--- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -293,16 +293,17 @@ extern const char* CacheKindNames[]; _(LoadInstanceOfObjectResult) \ _(LoadTypeOfObjectResult) \ _(DoubleAddResult) \ _(DoubleSubResult) \ _(DoubleMulResult) \ _(Int32AddResult) \ _(Int32SubResult) \ _(Int32MulResult) \ + _(Int32DivResult) \ _(Int32BitOrResult) \ _(Int32BitXorResult) \ _(Int32BitAndResult) \ _(Int32NotResult) \ _(Int32NegationResult) \ _(DoubleNegationResult) \ _(LoadInt32TruthyResult) \ _(LoadDoubleTruthyResult) \ @@ -1025,16 +1026,20 @@ class MOZ_RAII CacheIRWriter : public JS void int32SubResult(Int32OperandId lhs, Int32OperandId rhs) { writeOpWithOperandId(CacheOp::Int32SubResult, lhs); writeOperandId(rhs); } void int32MulResult(Int32OperandId lhs, Int32OperandId rhs) { writeOpWithOperandId(CacheOp::Int32MulResult, lhs); writeOperandId(rhs); } + void int32DivResult(Int32OperandId lhs, Int32OperandId rhs) { + writeOpWithOperandId(CacheOp::Int32DivResult, lhs); + writeOperandId(rhs); + } void int32BitOrResult(Int32OperandId lhs, Int32OperandId rhs) { writeOpWithOperandId(CacheOp::Int32BitOrResult, lhs); writeOperandId(rhs); } void int32BitXOrResult(Int32OperandId lhs, Int32OperandId rhs) { writeOpWithOperandId(CacheOp::Int32BitXorResult, lhs); writeOperandId(rhs); }
--- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -2053,16 +2053,49 @@ CacheIRCompiler::emitInt32MulResult() // Result is -0 if exactly one of lhs or rhs is negative. masm.or32(rhs, scratch); masm.branchTest32(Assembler::Signed, scratch, scratch, failure->label()); masm.bind(&done); EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output); return true; } + +bool +CacheIRCompiler::emitInt32DivResult() +{ + AutoOutputRegister output(*this); + Register lhs = allocator.useRegister(masm, reader.int32OperandId()); + Register rhs = allocator.useRegister(masm, reader.int32OperandId()); + AutoScratchRegister rem(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) + return false; + + // Prevent division by 0. + masm.branchTest32(Assembler::Zero, rhs, rhs, failure->label()); + + // Prevent negative 0 and -2147483648 / -1. + masm.branch32(Assembler::Equal, lhs, Imm32(INT32_MIN), failure->label()); + + Label notZero; + masm.branch32(Assembler::NotEqual, lhs, Imm32(0), ¬Zero); + masm.branchTest32(Assembler::Signed, rhs, rhs, failure->label()); + masm.bind(¬Zero); + + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); + masm.flexibleDivMod32(rhs, lhs, rem, false, volatileRegs); + + // A remainder implies a double result. + masm.branchTest32(Assembler::NonZero, rem, rem, failure->label()); + EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output); + return true; +} + bool CacheIRCompiler::emitInt32BitOrResult() { AutoOutputRegister output(*this); Register lhs = allocator.useRegister(masm, reader.int32OperandId()); Register rhs = allocator.useRegister(masm, reader.int32OperandId());
--- a/js/src/jit/CacheIRCompiler.h +++ b/js/src/jit/CacheIRCompiler.h @@ -53,16 +53,17 @@ namespace jit { _(LoadBooleanResult) \ _(LoadInt32ArrayLengthResult) \ _(DoubleAddResult) \ _(DoubleSubResult) \ _(DoubleMulResult) \ _(Int32AddResult) \ _(Int32SubResult) \ _(Int32MulResult) \ + _(Int32DivResult) \ _(Int32BitOrResult) \ _(Int32BitXorResult) \ _(Int32BitAndResult) \ _(Int32NegationResult) \ _(Int32NotResult) \ _(DoubleNegationResult) \ _(TruncateDoubleToUInt32) \ _(LoadArgumentsObjectLengthResult) \
--- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -3567,23 +3567,24 @@ IonBuilder::arithTrySharedStub(bool* emi MOZ_ASSERT_IF(op == JSOP_MUL, left->maybeConstantValue() && left->maybeConstantValue()->toInt32() == -1); MOZ_ASSERT_IF(op != JSOP_MUL, !left); stub = MUnaryCache::New(alloc(), right); break; case JSOP_ADD: case JSOP_SUB: case JSOP_MUL: + case JSOP_DIV: + // If not disabled, prefer the cache IR stub. if (!JitOptions.disableCacheIRBinaryArith) { stub = MBinaryCache::New(alloc(), left, right); break; } MOZ_FALLTHROUGH; - case JSOP_DIV: case JSOP_MOD: case JSOP_POW: stub = MBinarySharedStub::New(alloc(), left, right); break; default: MOZ_CRASH("unsupported arith"); }
--- a/js/src/jit/IonIC.cpp +++ b/js/src/jit/IonIC.cpp @@ -574,16 +574,20 @@ IonBinaryArithIC::update(JSContext* cx, case JSOP_SUB: if (!SubValues(cx, &lhsCopy, &rhsCopy, ret)) return false; break; case JSOP_MUL: if (!MulValues(cx, &lhsCopy, &rhsCopy, ret)) return false; break; + case JSOP_DIV: + if (!DivValues(cx, &lhsCopy, &rhsCopy, ret)) + return false; + break; case JSOP_BITOR: { int32_t result; if (!BitOr(cx, lhs, rhs, &result)) return false; ret.setInt32(result); break; } case JSOP_BITXOR: {