WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
work in progress
blah.patch (text/plain), 33.49 KB, created by
Filip Pizlo
on 2013-05-26 11:20:34 PDT
(
hide
)
Description:
work in progress
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-05-26 11:20:34 PDT
Size:
33.49 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 150720) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,27 @@ >+2013-05-26 Filip Pizlo <fpizlo@apple.com> >+ >+ fourthTier: clean up ArithDiv/ArithMod in the DFG >+ https://bugs.webkit.org/show_bug.cgi?id=116793 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Work in progress. >+ >+ * dfg/DFGAbstractState.cpp: >+ (JSC::DFG::AbstractState::executeEffects): >+ * dfg/DFGFixupPhase.cpp: >+ (JSC::DFG::FixupPhase::fixupNode): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (DFG): >+ (JSC::DFG::SpeculativeJIT::compileArithDiv): >+ (JSC::DFG::SpeculativeJIT::compileArithMod): >+ * dfg/DFGSpeculativeJIT.h: >+ (SpeculativeJIT): >+ * dfg/DFGSpeculativeJIT32_64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ * dfg/DFGSpeculativeJIT64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ > 2013-05-26 Filip Pizlo <fpizlo@apple.com> > > Merge trunk r150694. >Index: Source/JavaScriptCore/dfg/DFGAbstractState.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractState.cpp (revision 150720) >+++ Source/JavaScriptCore/dfg/DFGAbstractState.cpp (working copy) >@@ -563,6 +563,11 @@ bool AbstractState::executeEffects(unsig > case ArithMod: { > JSValue left = forNode(node->child1()).value(); > JSValue right = forNode(node->child2()).value(); >+ if (node->op() == ArithMod && right && right.isNumber() && right.asNumber() == 1 >+ && trySetConstant(node, JSValue(0))) { >+ m_foundConstants = true; >+ break; >+ } > if (left && right && left.isNumber() && right.isNumber()) { > double a = left.asNumber(); > double b = right.asNumber(); >Index: Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (revision 150720) >+++ Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (working copy) >@@ -209,7 +209,8 @@ private: > break; > } > >- case ArithDiv: { >+ case ArithDiv: >+ case ArithMod: { > if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) > && node->canSpeculateInteger()) { > if (isX86() || isARMv7s()) { >@@ -235,8 +236,7 @@ private: > } > > case ArithMin: >- case ArithMax: >- case ArithMod: { >+ case ArithMax: { > if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) > && node->canSpeculateInteger()) { > setUseKindAndUnboxIfProfitable<Int32Use>(node->child1()); >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (revision 150720) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (working copy) >@@ -2247,35 +2247,7 @@ void SpeculativeJIT::compile(Node* node) > break; > > case ArithDiv: { >- switch (node->binaryUseKind()) { >- case Int32Use: { >-#if CPU(X86) >- compileIntegerArithDivForX86(node); >-#elif CPU(APPLE_ARMV7S) >- compileIntegerArithDivForARMv7s(node); >-#else // CPU type without integer divide >- RELEASE_ASSERT_NOT_REACHED(); // should have been coverted into a double divide. >-#endif >- break; >- } >- >- case NumberUse: { >- SpeculateDoubleOperand op1(this, node->child1()); >- SpeculateDoubleOperand op2(this, node->child2()); >- FPRTemporary result(this, op1); >- >- FPRReg reg1 = op1.fpr(); >- FPRReg reg2 = op2.fpr(); >- m_jit.divDouble(reg1, reg2, result.fpr()); >- >- doubleResult(result.fpr(), node); >- break; >- } >- >- default: >- RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >+ compileArithDiv(node); > break; > } > >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (revision 150720) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (working copy) >@@ -2188,29 +2188,7 @@ void SpeculativeJIT::compile(Node* node) > break; > > case ArithDiv: { >- switch (node->binaryUseKind()) { >- case Int32Use: { >- compileIntegerArithDivForX86(node); >- break; >- } >- >- case NumberUse: { >- SpeculateDoubleOperand op1(this, node->child1()); >- SpeculateDoubleOperand op2(this, node->child2()); >- FPRTemporary result(this, op1); >- >- FPRReg reg1 = op1.fpr(); >- FPRReg reg2 = op2.fpr(); >- m_jit.divDouble(reg1, reg2, result.fpr()); >- >- doubleResult(result.fpr(), node); >- break; >- } >- >- default: >- RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >+ compileArithDiv(node); > break; > } > >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (revision 150720) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (working copy) >@@ -2777,185 +2777,6 @@ void SpeculativeJIT::compileInstanceOf(N > #endif > } > >-void SpeculativeJIT::compileSoftModulo(Node* node) >-{ >- // In the fast path, the dividend value could be the final result >- // (in case of |dividend| < |divisor|), so we speculate it as strict int32. >- SpeculateStrictInt32Operand op1(this, node->child1()); >-#if CPU(X86) || CPU(X86_64) >- if (isInt32Constant(node->child2().node())) { >- int32_t divisor = valueOfInt32Constant(node->child2().node()); >- if (divisor) { >- GPRReg op1Gpr = op1.gpr(); >- >- GPRTemporary eax(this, X86Registers::eax); >- GPRTemporary edx(this, X86Registers::edx); >- GPRTemporary scratch(this); >- GPRReg scratchGPR = scratch.gpr(); >- >- GPRReg op1SaveGPR; >- if (op1Gpr == X86Registers::eax || op1Gpr == X86Registers::edx) { >- op1SaveGPR = allocate(); >- ASSERT(op1Gpr != op1SaveGPR); >- m_jit.move(op1Gpr, op1SaveGPR); >- } else >- op1SaveGPR = op1Gpr; >- ASSERT(op1SaveGPR != X86Registers::eax); >- ASSERT(op1SaveGPR != X86Registers::edx); >- >- m_jit.move(op1Gpr, eax.gpr()); >- m_jit.move(TrustedImm32(divisor), scratchGPR); >- if (divisor == -1) >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1))); >- m_jit.assembler().cdq(); >- m_jit.assembler().idivl_r(scratchGPR); >- // Check that we're not about to create negative zero. >- // FIXME: if the node use doesn't care about neg zero, we can do this more easily. >- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); >- numeratorPositive.link(&m_jit); >- >- if (op1SaveGPR != op1Gpr) >- unlock(op1SaveGPR); >- >- integerResult(edx.gpr(), node); >- return; >- } >- } >-#elif CPU(APPLE_ARMV7S) >- if (isInt32Constant(node->child2().node())) { >- int32_t divisor = valueOfInt32Constant(node->child2().node()); >- if (divisor > 0 && hasOneBitSet(divisor)) { // If power of 2 then just mask >- GPRReg dividendGPR = op1.gpr(); >- GPRTemporary result(this); >- GPRReg resultGPR = result.gpr(); >- >- m_jit.assembler().cmp(dividendGPR, ARMThumbImmediate::makeEncodedImm(0)); >- m_jit.assembler().it(ARMv7Assembler::ConditionLT, false); >- m_jit.assembler().neg(resultGPR, dividendGPR); >- m_jit.assembler().mov(resultGPR, dividendGPR); >- m_jit.and32(TrustedImm32(divisor - 1), resultGPR); >- m_jit.assembler().it(ARMv7Assembler::ConditionLT); >- m_jit.assembler().neg(resultGPR, resultGPR); >- >- integerResult(resultGPR, node); >- return; >- } >- } >-#endif >- >- SpeculateIntegerOperand op2(this, node->child2()); >-#if CPU(X86) || CPU(X86_64) >- GPRTemporary eax(this, X86Registers::eax); >- GPRTemporary edx(this, X86Registers::edx); >- GPRReg op1GPR = op1.gpr(); >- GPRReg op2GPR = op2.gpr(); >- >- GPRReg op2TempGPR; >- GPRReg temp; >- GPRReg op1SaveGPR; >- >- if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) { >- op2TempGPR = allocate(); >- temp = op2TempGPR; >- } else { >- op2TempGPR = InvalidGPRReg; >- if (op1GPR == X86Registers::eax) >- temp = X86Registers::edx; >- else >- temp = X86Registers::eax; >- } >- >- if (op1GPR == X86Registers::eax || op1GPR == X86Registers::edx) { >- op1SaveGPR = allocate(); >- ASSERT(op1GPR != op1SaveGPR); >- m_jit.move(op1GPR, op1SaveGPR); >- } else >- op1SaveGPR = op1GPR; >- >- ASSERT(temp != op1GPR); >- ASSERT(temp != op2GPR); >- ASSERT(op1SaveGPR != X86Registers::eax); >- ASSERT(op1SaveGPR != X86Registers::edx); >- >- m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp); >- >- JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1)); >- >- JITCompiler::Jump done; >- // FIXME: if the node is not used as number then we can do this more easily. >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1))); >- >- safeDenominator.link(&m_jit); >- >- if (op2TempGPR != InvalidGPRReg) { >- m_jit.move(op2GPR, op2TempGPR); >- op2GPR = op2TempGPR; >- } >- >- m_jit.move(op1GPR, eax.gpr()); >- m_jit.assembler().cdq(); >- m_jit.assembler().idivl_r(op2GPR); >- >- if (op2TempGPR != InvalidGPRReg) >- unlock(op2TempGPR); >- >- // Check that we're not about to create negative zero. >- // FIXME: if the node use doesn't care about neg zero, we can do this more easily. >- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); >- numeratorPositive.link(&m_jit); >- >- if (op1SaveGPR != op1GPR) >- unlock(op1SaveGPR); >- >- integerResult(edx.gpr(), node); >- >-#elif CPU(APPLE_ARMV7S) >- GPRTemporary temp(this); >- GPRTemporary quotientThenRemainder(this); >- GPRTemporary multiplyAnswer(this); >- GPRReg dividendGPR = op1.gpr(); >- GPRReg divisorGPR = op2.gpr(); >- GPRReg quotientThenRemainderGPR = quotientThenRemainder.gpr(); >- GPRReg multiplyAnswerGPR = multiplyAnswer.gpr(); >- >- m_jit.assembler().sdiv(quotientThenRemainderGPR, dividendGPR, divisorGPR); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR)); >- m_jit.assembler().sub(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR); >- >- // If the user cares about negative zero, then speculate that we're not about >- // to produce negative zero. >- if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { >- // Check that we're not about to create negative zero. >- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0)); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR)); >- numeratorPositive.link(&m_jit); >- } >- >- integerResult(quotientThenRemainderGPR, node); >-#else // not architecture that can do integer division >- // Do this the *safest* way possible: call out to a C function that will do the modulo, >- // and then attempt to convert back. >- GPRReg op1GPR = op1.gpr(); >- GPRReg op2GPR = op2.gpr(); >- >- FPRResult result(this); >- >- flushRegisters(); >- callOperation(operationFModOnInts, result.fpr(), op1GPR, op2GPR); >- >- FPRTemporary scratch(this); >- GPRTemporary intResult(this); >- JITCompiler::JumpList failureCases; >- m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr()); >- speculationCheck(Overflow, JSValueRegs(), 0, failureCases); >- >- integerResult(intResult.gpr(), node); >-#endif // CPU(X86) || CPU(X86_64) >-} >- > void SpeculativeJIT::compileAdd(Node* node) > { > switch (node->binaryUseKind()) { >@@ -3275,128 +3096,311 @@ void SpeculativeJIT::compileArithMul(Nod > } > } > >-#if CPU(X86) || CPU(X86_64) >-void SpeculativeJIT::compileIntegerArithDivForX86(Node* node) >+void SpeculativeJIT::compileArithDiv(Node* node) > { >- SpeculateIntegerOperand op1(this, node->child1()); >- SpeculateIntegerOperand op2(this, node->child2()); >- GPRTemporary eax(this, X86Registers::eax); >- GPRTemporary edx(this, X86Registers::edx); >- GPRReg op1GPR = op1.gpr(); >- GPRReg op2GPR = op2.gpr(); >- >- GPRReg op2TempGPR; >- GPRReg temp; >- if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) { >- op2TempGPR = allocate(); >- temp = op2TempGPR; >- } else { >- op2TempGPR = InvalidGPRReg; >- if (op1GPR == X86Registers::eax) >- temp = X86Registers::edx; >- else >- temp = X86Registers::eax; >- } >+ switch (node->binaryUseKind()) { >+ case Int32Use: { >+#if CPU(X86) || CPU(X86_64) >+ SpeculateIntegerOperand op1(this, node->child1()); >+ SpeculateIntegerOperand op2(this, node->child2()); >+ GPRTemporary eax(this, X86Registers::eax); >+ GPRTemporary edx(this, X86Registers::edx); >+ GPRReg op1GPR = op1.gpr(); >+ GPRReg op2GPR = op2.gpr(); >+ >+ GPRReg op2TempGPR; >+ GPRReg temp; >+ if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) { >+ op2TempGPR = allocate(); >+ temp = op2TempGPR; >+ } else { >+ op2TempGPR = InvalidGPRReg; >+ if (op1GPR == X86Registers::eax) >+ temp = X86Registers::edx; >+ else >+ temp = X86Registers::eax; >+ } > >- ASSERT(temp != op1GPR); >- ASSERT(temp != op2GPR); >+ ASSERT(temp != op1GPR); >+ ASSERT(temp != op2GPR); > >- m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp); >+ m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp); > >- JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1)); >+ JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1)); > >- JITCompiler::JumpList done; >- if (nodeUsedAsNumber(node->arithNodeFlags())) { >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1))); >- } else { >- // This is the case where we convert the result to an int after we're done, and we >- // already know that the denominator is either -1 or 0. So, if the denominator is >- // zero, then the result should be zero. If the denominator is not zero (i.e. it's >- // -1) and the numerator is -2^31 then the result should be -2^31. Otherwise we >- // are happy to fall through to a normal division, since we're just dividing >- // something by negative 1. >- >- JITCompiler::Jump notZero = m_jit.branchTest32(JITCompiler::NonZero, op2GPR); >- m_jit.move(TrustedImm32(0), eax.gpr()); >- done.append(m_jit.jump()); >- >- notZero.link(&m_jit); >- JITCompiler::Jump notNeg2ToThe31 = >- m_jit.branch32(JITCompiler::NotEqual, op1GPR, TrustedImm32(-2147483647-1)); >- m_jit.move(op1GPR, eax.gpr()); >- done.append(m_jit.jump()); >+ JITCompiler::JumpList done; >+ if (nodeUsedAsNumber(node->arithNodeFlags())) { >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1))); >+ } else { >+ // This is the case where we convert the result to an int after we're done, and we >+ // already know that the denominator is either -1 or 0. So, if the denominator is >+ // zero, then the result should be zero. If the denominator is not zero (i.e. it's >+ // -1) and the numerator is -2^31 then the result should be -2^31. Otherwise we >+ // are happy to fall through to a normal division, since we're just dividing >+ // something by negative 1. >+ >+ JITCompiler::Jump notZero = m_jit.branchTest32(JITCompiler::NonZero, op2GPR); >+ m_jit.move(TrustedImm32(0), eax.gpr()); >+ done.append(m_jit.jump()); >+ >+ notZero.link(&m_jit); >+ JITCompiler::Jump notNeg2ToThe31 = >+ m_jit.branch32(JITCompiler::NotEqual, op1GPR, TrustedImm32(-2147483647-1)); >+ m_jit.move(op1GPR, eax.gpr()); >+ done.append(m_jit.jump()); > >- notNeg2ToThe31.link(&m_jit); >- } >+ notNeg2ToThe31.link(&m_jit); >+ } > >- safeDenominator.link(&m_jit); >+ safeDenominator.link(&m_jit); > >- // If the user cares about negative zero, then speculate that we're not about >- // to produce negative zero. >- if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { >- MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); >- speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); >- numeratorNonZero.link(&m_jit); >- } >+ // If the user cares about negative zero, then speculate that we're not about >+ // to produce negative zero. >+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { >+ MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); >+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); >+ numeratorNonZero.link(&m_jit); >+ } > >- if (op2TempGPR != InvalidGPRReg) { >- m_jit.move(op2GPR, op2TempGPR); >- op2GPR = op2TempGPR; >- } >+ if (op2TempGPR != InvalidGPRReg) { >+ m_jit.move(op2GPR, op2TempGPR); >+ op2GPR = op2TempGPR; >+ } > >- m_jit.move(op1GPR, eax.gpr()); >- m_jit.assembler().cdq(); >- m_jit.assembler().idivl_r(op2GPR); >+ m_jit.move(op1GPR, eax.gpr()); >+ m_jit.assembler().cdq(); >+ m_jit.assembler().idivl_r(op2GPR); > >- if (op2TempGPR != InvalidGPRReg) >- unlock(op2TempGPR); >+ if (op2TempGPR != InvalidGPRReg) >+ unlock(op2TempGPR); > >- // Check that there was no remainder. If there had been, then we'd be obligated to >- // produce a double result instead. >- if (nodeUsedAsNumber(node->arithNodeFlags())) >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr())); >- else >- done.link(&m_jit); >+ // Check that there was no remainder. If there had been, then we'd be obligated to >+ // produce a double result instead. >+ if (nodeUsedAsNumber(node->arithNodeFlags())) >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr())); >+ else >+ done.link(&m_jit); > >- integerResult(eax.gpr(), node); >-} >+ integerResult(eax.gpr(), node); > #elif CPU(APPLE_ARMV7S) >-void SpeculativeJIT::compileIntegerArithDivForARMv7s(Node* node) >-{ >- SpeculateIntegerOperand op1(this, node->child1()); >- SpeculateIntegerOperand op2(this, node->child2()); >- GPRReg op1GPR = op1.gpr(); >- GPRReg op2GPR = op2.gpr(); >- GPRTemporary quotient(this); >- GPRTemporary multiplyAnswer(this); >+ SpeculateIntegerOperand op1(this, node->child1()); >+ SpeculateIntegerOperand op2(this, node->child2()); >+ GPRReg op1GPR = op1.gpr(); >+ GPRReg op2GPR = op2.gpr(); >+ GPRTemporary quotient(this); >+ GPRTemporary multiplyAnswer(this); > >- // If the user cares about negative zero, then speculate that we're not about >- // to produce negative zero. >- if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { >- MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); >- speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); >- numeratorNonZero.link(&m_jit); >- } >+ // If the user cares about negative zero, then speculate that we're not about >+ // to produce negative zero. >+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { >+ MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); >+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); >+ numeratorNonZero.link(&m_jit); >+ } > >- m_jit.assembler().sdiv(quotient.gpr(), op1GPR, op2GPR); >+ m_jit.assembler().sdiv(quotient.gpr(), op1GPR, op2GPR); > >- // Check that there was no remainder. If there had been, then we'd be obligated to >- // produce a double result instead. >- if (nodeUsedAsNumber(node->arithNodeFlags())) { >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotient.gpr(), op2GPR, multiplyAnswer.gpr())); >- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::NotEqual, multiplyAnswer.gpr(), op1GPR)); >- } >+ // Check that there was no remainder. If there had been, then we'd be obligated to >+ // produce a double result instead. >+ if (nodeUsedAsNumber(node->arithNodeFlags())) { >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotient.gpr(), op2GPR, multiplyAnswer.gpr())); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::NotEqual, multiplyAnswer.gpr(), op1GPR)); >+ } > >- integerResult(quotient.gpr(), node); >-} >+ integerResult(quotient.gpr(), node); >+#else >+ RELEASE_ASSERT_NOT_REACHED(); > #endif >+ break; >+ } >+ >+ case NumberUse: { >+ SpeculateDoubleOperand op1(this, node->child1()); >+ SpeculateDoubleOperand op2(this, node->child2()); >+ FPRTemporary result(this, op1); >+ >+ FPRReg reg1 = op1.fpr(); >+ FPRReg reg2 = op2.fpr(); >+ m_jit.divDouble(reg1, reg2, result.fpr()); >+ >+ doubleResult(result.fpr(), node); >+ break; >+ } >+ >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+} > > void SpeculativeJIT::compileArithMod(Node* node) > { > switch (node->binaryUseKind()) { > case Int32Use: { >- compileSoftModulo(node); >+ // In the fast path, the dividend value could be the final result >+ // (in case of |dividend| < |divisor|), so we speculate it as strict int32. >+ SpeculateStrictInt32Operand op1(this, node->child1()); >+ >+ if (isInt32Constant(node->child2().node())) { >+ int32_t divisor = valueOfInt32Constant(node->child2().node()); >+ if (divisor > 0 && hasOneBitSet(divisor)) { >+ ASSERT(divisor != 1); >+ unsigned logarithm = WTF::fastLog2(divisor); >+ GPRReg dividendGPR = op1.gpr(); >+ GPRTemporary result(this); >+ GPRReg resultGPR = result.gpr(); >+ >+ // Don't ask. This is what LLVM generates. >+ m_jit.move(dividendGPR, resultGPR); >+ m_jit.rshift32(TrustedImm32(31), resultGPR); >+ m_jit.urshift32(TrustedImm32(32 - logarithm), resultGPR); >+ m_jit.add32(dividendGPR, resultGPR); >+ m_jit.and32(TrustedImm32(-divisor), resultGPR); >+ m_jit.neg32(resultGPR); >+ m_jit.add32(dividendGPR, resultGPR); >+ >+ integerResult(resultGPR, node); >+ return; >+ } >+ } >+ >+#if CPU(X86) || CPU(X86_64) >+ if (isInt32Constant(node->child2().node())) { >+ int32_t divisor = valueOfInt32Constant(node->child2().node()); >+ if (divisor) { >+ GPRReg op1Gpr = op1.gpr(); >+ >+ GPRTemporary eax(this, X86Registers::eax); >+ GPRTemporary edx(this, X86Registers::edx); >+ GPRTemporary scratch(this); >+ GPRReg scratchGPR = scratch.gpr(); >+ >+ GPRReg op1SaveGPR; >+ if (op1Gpr == X86Registers::eax || op1Gpr == X86Registers::edx) { >+ op1SaveGPR = allocate(); >+ ASSERT(op1Gpr != op1SaveGPR); >+ m_jit.move(op1Gpr, op1SaveGPR); >+ } else >+ op1SaveGPR = op1Gpr; >+ ASSERT(op1SaveGPR != X86Registers::eax); >+ ASSERT(op1SaveGPR != X86Registers::edx); >+ >+ m_jit.move(op1Gpr, eax.gpr()); >+ m_jit.move(TrustedImm32(divisor), scratchGPR); >+ if (divisor == -1) >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1))); >+ m_jit.assembler().cdq(); >+ m_jit.assembler().idivl_r(scratchGPR); >+ // Check that we're not about to create negative zero. >+ // FIXME: if the node use doesn't care about neg zero, we can do this more easily. >+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); >+ numeratorPositive.link(&m_jit); >+ >+ if (op1SaveGPR != op1Gpr) >+ unlock(op1SaveGPR); >+ >+ integerResult(edx.gpr(), node); >+ return; >+ } >+ } >+#endif >+ >+ SpeculateIntegerOperand op2(this, node->child2()); >+#if CPU(X86) || CPU(X86_64) >+ GPRTemporary eax(this, X86Registers::eax); >+ GPRTemporary edx(this, X86Registers::edx); >+ GPRReg op1GPR = op1.gpr(); >+ GPRReg op2GPR = op2.gpr(); >+ >+ GPRReg op2TempGPR; >+ GPRReg temp; >+ GPRReg op1SaveGPR; >+ >+ if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) { >+ op2TempGPR = allocate(); >+ temp = op2TempGPR; >+ } else { >+ op2TempGPR = InvalidGPRReg; >+ if (op1GPR == X86Registers::eax) >+ temp = X86Registers::edx; >+ else >+ temp = X86Registers::eax; >+ } >+ >+ if (op1GPR == X86Registers::eax || op1GPR == X86Registers::edx) { >+ op1SaveGPR = allocate(); >+ ASSERT(op1GPR != op1SaveGPR); >+ m_jit.move(op1GPR, op1SaveGPR); >+ } else >+ op1SaveGPR = op1GPR; >+ >+ ASSERT(temp != op1GPR); >+ ASSERT(temp != op2GPR); >+ ASSERT(op1SaveGPR != X86Registers::eax); >+ ASSERT(op1SaveGPR != X86Registers::edx); >+ >+ m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp); >+ >+ JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1)); >+ >+ JITCompiler::Jump done; >+ // FIXME: if the node is not used as number then we can do this more easily. >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1))); >+ >+ safeDenominator.link(&m_jit); >+ >+ if (op2TempGPR != InvalidGPRReg) { >+ m_jit.move(op2GPR, op2TempGPR); >+ op2GPR = op2TempGPR; >+ } >+ >+ m_jit.move(op1GPR, eax.gpr()); >+ m_jit.assembler().cdq(); >+ m_jit.assembler().idivl_r(op2GPR); >+ >+ if (op2TempGPR != InvalidGPRReg) >+ unlock(op2TempGPR); >+ >+ // Check that we're not about to create negative zero. >+ // FIXME: if the node use doesn't care about neg zero, we can do this more easily. >+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); >+ numeratorPositive.link(&m_jit); >+ >+ if (op1SaveGPR != op1GPR) >+ unlock(op1SaveGPR); >+ >+ integerResult(edx.gpr(), node); >+ >+#elif CPU(APPLE_ARMV7S) >+ GPRTemporary temp(this); >+ GPRTemporary quotientThenRemainder(this); >+ GPRTemporary multiplyAnswer(this); >+ GPRReg dividendGPR = op1.gpr(); >+ GPRReg divisorGPR = op2.gpr(); >+ GPRReg quotientThenRemainderGPR = quotientThenRemainder.gpr(); >+ GPRReg multiplyAnswerGPR = multiplyAnswer.gpr(); >+ >+ m_jit.assembler().sdiv(quotientThenRemainderGPR, dividendGPR, divisorGPR); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR)); >+ m_jit.assembler().sub(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR); >+ >+ // If the user cares about negative zero, then speculate that we're not about >+ // to produce negative zero. >+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { >+ // Check that we're not about to create negative zero. >+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0)); >+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR)); >+ numeratorPositive.link(&m_jit); >+ } >+ >+ integerResult(quotientThenRemainderGPR, node); >+#else // not architecture that can do integer division >+ RELEASE_ASSERT_NOT_REACHED(); >+#endif > return; > } > >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (revision 150720) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (working copy) >@@ -2138,13 +2138,8 @@ public: > void compileArithSub(Node*); > void compileArithNegate(Node*); > void compileArithMul(Node*); >-#if CPU(X86) || CPU(X86_64) >- void compileIntegerArithDivForX86(Node*); >-#elif CPU(APPLE_ARMV7S) >- void compileIntegerArithDivForARMv7s(Node*); >-#endif >+ void compileArithDiv(Node*); > void compileArithMod(Node*); >- void compileSoftModulo(Node*); > void compileGetIndexedPropertyStorage(Node*); > void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node*, size_t elementSize, TypedArraySignedness); > void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node*, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding); >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 150720) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,14 @@ >+2013-05-26 Filip Pizlo <fpizlo@apple.com> >+ >+ fourthTier: clean up ArithDiv/ArithMod in the DFG >+ https://bugs.webkit.org/show_bug.cgi?id=116793 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js: >+ (myModBy2): >+ (myModBy1073741824): >+ > 2013-05-26 Filip Pizlo <fpizlo@apple.com> > > Merge trunk r150694. >Index: LayoutTests/fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js >=================================================================== >--- LayoutTests/fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js (revision 150720) >+++ LayoutTests/fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js (working copy) >@@ -1,5 +1,5 @@ > description( >-"Tests that -2^31/-1 does the right thing." >+"Tests that -2^31/-1 (and a bunch of other corner cases) does the right thing." > ); > > function myDiv(a, b) { >@@ -22,6 +22,14 @@ function myModByNeg1(a) { > return a % -1; > } > >+function myModBy2(a) { >+ return a % 2; >+} >+ >+function myModBy1073741824(a) { >+ return a % 1073741824; >+} >+ > function myModNeg2ToThe31(b) { > return -2147483648 % b; > } >@@ -68,6 +76,12 @@ for (var i = 0; i < 200; ++i) { > shouldBe("myMod(x, y)", "-0"); > shouldBe("myMod(x, z)", "-2"); > shouldBe("myModByNeg1(x)", "-0"); >+ shouldBe("myModBy2(x)", "0"); >+ shouldBe("myModBy1073741824(x)", "0"); >+ shouldBe("myModBy2(y)", "-1"); >+ shouldBe("myModBy1073741824(y)", "-1"); >+ shouldBe("myModBy2(z)", "1"); >+ shouldBe("myModBy1073741824(z)", "3"); > shouldBe("myModNeg2ToThe31(y)", "-0"); > if (i > 100) { > w = x;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 116793
:
202927
|
202945