Changeset 194113 in webkit
- Timestamp:
- Dec 15, 2015, 1:19:31 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 18 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r194112 r194113 1 2015-12-15 Mark Lam <mark.lam@apple.com> 2 3 Polymorphic operand types for DFG and FTL bit operators. 4 https://bugs.webkit.org/show_bug.cgi?id=152191 5 6 Reviewed by Saam Barati. 7 8 * js/regress/ftl-polymorphic-bitand-expected.txt: Added. 9 * js/regress/ftl-polymorphic-bitand.html: Added. 10 * js/regress/ftl-polymorphic-bitor-expected.txt: Added. 11 * js/regress/ftl-polymorphic-bitor.html: Added. 12 * js/regress/ftl-polymorphic-bitxor-expected.txt: Added. 13 * js/regress/ftl-polymorphic-bitxor.html: Added. 14 * js/regress/ftl-polymorphic-lshift-expected.txt: Added. 15 * js/regress/ftl-polymorphic-lshift.html: Added. 16 * js/regress/ftl-polymorphic-rshift-expected.txt: Added. 17 * js/regress/ftl-polymorphic-rshift.html: Added. 18 * js/regress/ftl-polymorphic-urshift-expected.txt: Added. 19 * js/regress/ftl-polymorphic-urshift.html: Added. 20 * js/regress/script-tests/ftl-polymorphic-bitand.js: Added. 21 (o1.valueOf): 22 (foo): 23 * js/regress/script-tests/ftl-polymorphic-bitor.js: Added. 24 (o1.valueOf): 25 (foo): 26 * js/regress/script-tests/ftl-polymorphic-bitxor.js: Added. 27 (o1.valueOf): 28 (foo): 29 * js/regress/script-tests/ftl-polymorphic-lshift.js: Added. 30 (o1.valueOf): 31 (foo): 32 * js/regress/script-tests/ftl-polymorphic-rshift.js: Added. 33 (o1.valueOf): 34 (foo): 35 * js/regress/script-tests/ftl-polymorphic-urshift.js: Added. 36 (o1.valueOf): 37 (foo): 38 1 39 2015-12-15 Adam Bergkvist <adam.bergkvist@ericsson.com> 2 40 -
trunk/Source/JavaScriptCore/ChangeLog
r194107 r194113 1 2015-12-15 Mark Lam <mark.lam@apple.com> 2 3 Polymorphic operand types for DFG and FTL bit operators. 4 https://bugs.webkit.org/show_bug.cgi?id=152191 5 6 Reviewed by Saam Barati. 7 8 * bytecode/SpeculatedType.h: 9 (JSC::isUntypedSpeculationForBitOps): 10 * dfg/DFGAbstractInterpreterInlines.h: 11 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 12 * dfg/DFGNode.h: 13 (JSC::DFG::Node::shouldSpeculateUntypedForBitOps): 14 - Added check for types not supported by ValueToInt32, and therefore should be 15 treated as untyped for bitops. 16 17 * dfg/DFGClobberize.h: 18 (JSC::DFG::clobberize): 19 * dfg/DFGFixupPhase.cpp: 20 (JSC::DFG::FixupPhase::fixupNode): 21 - Handled untyped operands. 22 23 * dfg/DFGOperations.cpp: 24 * dfg/DFGOperations.h: 25 - Added DFG slow path functions for bitops. 26 27 * dfg/DFGSpeculativeJIT.cpp: 28 (JSC::DFG::SpeculativeJIT::emitUntypedBitOp): 29 (JSC::DFG::SpeculativeJIT::compileBitwiseOp): 30 (JSC::DFG::SpeculativeJIT::emitUntypedRightShiftBitOp): 31 (JSC::DFG::SpeculativeJIT::compileShiftOp): 32 * dfg/DFGSpeculativeJIT.h: 33 - Added DFG backend support untyped operands for bitops. 34 35 * dfg/DFGStrengthReductionPhase.cpp: 36 (JSC::DFG::StrengthReductionPhase::handleNode): 37 - Limit bitops strength reduction only to when we don't have untyped operands. 38 This is because values that are not int32s need to be converted to int32. 39 Without untyped operands, the ValueToInt32 node takes care of this. 40 With untyped operands, we cannot use ValueToInt32, and need to do the conversion 41 in the code emitted for the bitop node itself. For example: 42 43 5.5 | 0; // yields 5 because ValueToInt32 converts the 5.5 to a 5. 44 "abc" | 0; // would yield "abc" instead of the expected 0 if we let 45 // strength reduction do its thing. 46 47 * ftl/FTLCompileBinaryOp.cpp: 48 (JSC::FTL::generateBinaryBitOpFastPath): 49 (JSC::FTL::generateRightShiftFastPath): 50 (JSC::FTL::generateBinaryOpFastPath): 51 52 * ftl/FTLInlineCacheDescriptor.h: 53 (JSC::FTL::BitAndDescriptor::BitAndDescriptor): 54 (JSC::FTL::BitAndDescriptor::icSize): 55 (JSC::FTL::BitAndDescriptor::nodeType): 56 (JSC::FTL::BitAndDescriptor::opName): 57 (JSC::FTL::BitAndDescriptor::slowPathFunction): 58 (JSC::FTL::BitAndDescriptor::nonNumberSlowPathFunction): 59 (JSC::FTL::BitOrDescriptor::BitOrDescriptor): 60 (JSC::FTL::BitOrDescriptor::icSize): 61 (JSC::FTL::BitOrDescriptor::nodeType): 62 (JSC::FTL::BitOrDescriptor::opName): 63 (JSC::FTL::BitOrDescriptor::slowPathFunction): 64 (JSC::FTL::BitOrDescriptor::nonNumberSlowPathFunction): 65 (JSC::FTL::BitXorDescriptor::BitXorDescriptor): 66 (JSC::FTL::BitXorDescriptor::icSize): 67 (JSC::FTL::BitXorDescriptor::nodeType): 68 (JSC::FTL::BitXorDescriptor::opName): 69 (JSC::FTL::BitXorDescriptor::slowPathFunction): 70 (JSC::FTL::BitXorDescriptor::nonNumberSlowPathFunction): 71 (JSC::FTL::BitLShiftDescriptor::BitLShiftDescriptor): 72 (JSC::FTL::BitLShiftDescriptor::icSize): 73 (JSC::FTL::BitLShiftDescriptor::nodeType): 74 (JSC::FTL::BitLShiftDescriptor::opName): 75 (JSC::FTL::BitLShiftDescriptor::slowPathFunction): 76 (JSC::FTL::BitLShiftDescriptor::nonNumberSlowPathFunction): 77 (JSC::FTL::BitRShiftDescriptor::BitRShiftDescriptor): 78 (JSC::FTL::BitRShiftDescriptor::icSize): 79 (JSC::FTL::BitRShiftDescriptor::nodeType): 80 (JSC::FTL::BitRShiftDescriptor::opName): 81 (JSC::FTL::BitRShiftDescriptor::slowPathFunction): 82 (JSC::FTL::BitRShiftDescriptor::nonNumberSlowPathFunction): 83 (JSC::FTL::BitURShiftDescriptor::BitURShiftDescriptor): 84 (JSC::FTL::BitURShiftDescriptor::icSize): 85 (JSC::FTL::BitURShiftDescriptor::nodeType): 86 (JSC::FTL::BitURShiftDescriptor::opName): 87 (JSC::FTL::BitURShiftDescriptor::slowPathFunction): 88 (JSC::FTL::BitURShiftDescriptor::nonNumberSlowPathFunction): 89 - Added support for bitop ICs. 90 91 * ftl/FTLInlineCacheSize.cpp: 92 (JSC::FTL::sizeOfBitAnd): 93 (JSC::FTL::sizeOfBitOr): 94 (JSC::FTL::sizeOfBitXor): 95 (JSC::FTL::sizeOfBitLShift): 96 (JSC::FTL::sizeOfBitRShift): 97 (JSC::FTL::sizeOfBitURShift): 98 * ftl/FTLInlineCacheSize.h: 99 - Added new bitop IC sizes. These are just estimates for now that work adequately, 100 and are shown to not impact performance on benchmarks. We will re-tune these 101 sizes values later in another patch once all snippet ICs have been added. 102 103 * ftl/FTLLowerDFGToLLVM.cpp: 104 (JSC::FTL::DFG::LowerDFGToLLVM::compileBitAnd): 105 (JSC::FTL::DFG::LowerDFGToLLVM::compileBitOr): 106 (JSC::FTL::DFG::LowerDFGToLLVM::compileBitXor): 107 (JSC::FTL::DFG::LowerDFGToLLVM::compileBitRShift): 108 (JSC::FTL::DFG::LowerDFGToLLVM::compileBitLShift): 109 (JSC::FTL::DFG::LowerDFGToLLVM::compileBitURShift): 110 - Added support for bitop ICs. 111 112 * jit/JITLeftShiftGenerator.cpp: 113 (JSC::JITLeftShiftGenerator::generateFastPath): 114 * jit/JITLeftShiftGenerator.h: 115 (JSC::JITLeftShiftGenerator::JITLeftShiftGenerator): 116 * jit/JITRightShiftGenerator.cpp: 117 (JSC::JITRightShiftGenerator::generateFastPath): 118 - The shift MASM operatons need to ensure that the shiftAmount is not in the same 119 register as the destination register. With the baselineJIT and DFG, this is 120 ensured in how we allocate these registers, and hence, the bug does not manifest. 121 With the FTL, these registers are not guaranteed to be unique. Hence, we need 122 to fix the shift op snippet code to compensate for this. 123 1 124 2015-12-15 Caitlin Potter <caitp@igalia.com> 2 125 … … 1606 1729 * runtime/CommonIdentifiers.h: 1607 1730 1608 >>>>>>> .r1939401609 1731 2015-12-08 Filip Pizlo <fpizlo@apple.com> 1610 1732 -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h
r192034 r194113 391 391 } 392 392 393 inline bool isUntypedSpeculationForBitOps(SpeculatedType value) 394 { 395 return !(value & (SpecFullNumber | SpecBoolean | SpecOther)); 396 } 397 393 398 void dumpSpeculation(PrintStream&, SpeculatedType); 394 399 void dumpSpeculationAbbreviated(PrintStream&, SpeculatedType); -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r194087 r194113 234 234 case BitLShift: 235 235 case BitURShift: { 236 if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { 237 clobberWorld(node->origin.semantic, clobberLimit); 238 forNode(node).setType(m_graph, SpecInt32); 239 break; 240 } 241 236 242 JSValue left = forNode(node->child1()).value(); 237 243 JSValue right = forNode(node->child2()).value(); -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r194087 r194113 122 122 return; 123 123 124 case BitAnd:125 case BitOr:126 case BitXor:127 case BitLShift:128 case BitRShift:129 case BitURShift:130 124 case ArithIMul: 131 125 case ArithAbs: … … 165 159 return; 166 160 161 case BitAnd: 162 case BitOr: 163 case BitXor: 164 case BitLShift: 165 case BitRShift: 166 case BitURShift: 167 if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { 168 read(World); 169 write(Heap); 170 return; 171 } 172 def(PureValue(node)); 173 return; 174 167 175 case ArithRandom: 168 176 read(MathDotRandomState); -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r194087 r194113 106 106 case BitLShift: 107 107 case BitURShift: { 108 if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node()) 109 && m_graph.hasExitSite(node->origin.semantic, BadType)) { 110 fixEdge<UntypedUse>(node->child1()); 111 fixEdge<UntypedUse>(node->child2()); 112 break; 113 } 108 114 fixIntConvertingEdge(node->child1()); 109 115 fixIntConvertingEdge(node->child2()); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r194036 r194113 2034 2034 } 2035 2035 2036 bool shouldSpeculateUntypedForBitOps() 2037 { 2038 return isUntypedSpeculationForBitOps(prediction()); 2039 } 2040 2041 static bool shouldSpeculateUntypedForBitOps(Node* op1, Node* op2) 2042 { 2043 return op1->shouldSpeculateUntypedForBitOps() || op2->shouldSpeculateUntypedForBitOps(); 2044 } 2045 2036 2046 static bool shouldSpeculateBoolean(Node* op1, Node* op2) 2037 2047 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r194087 r194113 174 174 } 175 175 176 EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 177 { 178 VM* vm = &exec->vm(); 179 NativeCallFrameTracer tracer(vm, exec); 180 181 JSValue op1 = JSValue::decode(encodedOp1); 182 JSValue op2 = JSValue::decode(encodedOp2); 183 184 int32_t a = op1.toInt32(exec); 185 int32_t b = op2.toInt32(exec); 186 return JSValue::encode(jsNumber(a & b)); 187 } 188 189 EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 190 { 191 VM* vm = &exec->vm(); 192 NativeCallFrameTracer tracer(vm, exec); 193 194 JSValue op1 = JSValue::decode(encodedOp1); 195 JSValue op2 = JSValue::decode(encodedOp2); 196 197 int32_t a = op1.toInt32(exec); 198 int32_t b = op2.toInt32(exec); 199 return JSValue::encode(jsNumber(a | b)); 200 } 201 202 EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 203 { 204 VM* vm = &exec->vm(); 205 NativeCallFrameTracer tracer(vm, exec); 206 207 JSValue op1 = JSValue::decode(encodedOp1); 208 JSValue op2 = JSValue::decode(encodedOp2); 209 210 int32_t a = op1.toInt32(exec); 211 int32_t b = op2.toInt32(exec); 212 return JSValue::encode(jsNumber(a ^ b)); 213 } 214 215 EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 216 { 217 VM* vm = &exec->vm(); 218 NativeCallFrameTracer tracer(vm, exec); 219 220 JSValue op1 = JSValue::decode(encodedOp1); 221 JSValue op2 = JSValue::decode(encodedOp2); 222 223 int32_t a = op1.toInt32(exec); 224 uint32_t b = op2.toUInt32(exec); 225 return JSValue::encode(jsNumber(a << (b & 0x1f))); 226 } 227 228 EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 229 { 230 VM* vm = &exec->vm(); 231 NativeCallFrameTracer tracer(vm, exec); 232 233 JSValue op1 = JSValue::decode(encodedOp1); 234 JSValue op2 = JSValue::decode(encodedOp2); 235 236 int32_t a = op1.toInt32(exec); 237 uint32_t b = op2.toUInt32(exec); 238 return JSValue::encode(jsNumber(a >> (b & 0x1f))); 239 } 240 241 EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 242 { 243 VM* vm = &exec->vm(); 244 NativeCallFrameTracer tracer(vm, exec); 245 246 JSValue op1 = JSValue::decode(encodedOp1); 247 JSValue op2 = JSValue::decode(encodedOp2); 248 249 uint32_t a = op1.toUInt32(exec); 250 uint32_t b = op2.toUInt32(exec); 251 return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f)))); 252 } 253 176 254 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 177 255 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r194087 r194113 44 44 EncodedJSValue JIT_OPERATION operationToThis(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL; 45 45 EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL; 46 EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 47 EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 48 EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 49 EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 50 EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 51 EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 46 52 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 47 53 EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r194042 r194113 40 40 #include "DirectArguments.h" 41 41 #include "JITAddGenerator.h" 42 #include "JITBitAndGenerator.h" 43 #include "JITBitOrGenerator.h" 44 #include "JITBitXorGenerator.h" 42 45 #include "JITDivGenerator.h" 46 #include "JITLeftShiftGenerator.h" 43 47 #include "JITMulGenerator.h" 48 #include "JITRightShiftGenerator.h" 44 49 #include "JITSubGenerator.h" 45 50 #include "JSArrowFunction.h" … … 2787 2792 } 2788 2793 2794 template<typename SnippetGenerator, J_JITOperation_EJJ snippetSlowPathFunction> 2795 void SpeculativeJIT::emitUntypedBitOp(Node* node) 2796 { 2797 Edge& leftChild = node->child1(); 2798 Edge& rightChild = node->child2(); 2799 2800 if (isKnownNotNumber(leftChild.node()) || isKnownNotNumber(rightChild.node())) { 2801 JSValueOperand left(this, leftChild); 2802 JSValueOperand right(this, rightChild); 2803 JSValueRegs leftRegs = left.jsValueRegs(); 2804 JSValueRegs rightRegs = right.jsValueRegs(); 2805 #if USE(JSVALUE64) 2806 GPRTemporary result(this); 2807 JSValueRegs resultRegs = JSValueRegs(result.gpr()); 2808 #else 2809 GPRTemporary resultTag(this); 2810 GPRTemporary resultPayload(this); 2811 JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr()); 2812 #endif 2813 flushRegisters(); 2814 callOperation(snippetSlowPathFunction, resultRegs, leftRegs, rightRegs); 2815 m_jit.exceptionCheck(); 2816 2817 jsValueResult(resultRegs, node); 2818 return; 2819 } 2820 2821 Optional<JSValueOperand> left; 2822 Optional<JSValueOperand> right; 2823 2824 JSValueRegs leftRegs; 2825 JSValueRegs rightRegs; 2826 2827 #if USE(JSVALUE64) 2828 GPRTemporary result(this); 2829 JSValueRegs resultRegs = JSValueRegs(result.gpr()); 2830 GPRTemporary scratch(this); 2831 GPRReg scratchGPR = scratch.gpr(); 2832 #else 2833 GPRTemporary resultTag(this); 2834 GPRTemporary resultPayload(this); 2835 JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr()); 2836 GPRReg scratchGPR = resultTag.gpr(); 2837 #endif 2838 2839 SnippetOperand leftOperand; 2840 SnippetOperand rightOperand; 2841 2842 // The snippet generator does not support both operands being constant. If the left 2843 // operand is already const, we'll ignore the right operand's constness. 2844 if (leftChild->isInt32Constant()) 2845 leftOperand.setConstInt32(leftChild->asInt32()); 2846 else if (rightChild->isInt32Constant()) 2847 rightOperand.setConstInt32(rightChild->asInt32()); 2848 2849 RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst()); 2850 2851 if (!leftOperand.isConst()) { 2852 left = JSValueOperand(this, leftChild); 2853 leftRegs = left->jsValueRegs(); 2854 } 2855 if (!rightOperand.isConst()) { 2856 right = JSValueOperand(this, rightChild); 2857 rightRegs = right->jsValueRegs(); 2858 } 2859 2860 SnippetGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, scratchGPR); 2861 gen.generateFastPath(m_jit); 2862 2863 ASSERT(gen.didEmitFastPath()); 2864 gen.endJumpList().append(m_jit.jump()); 2865 2866 gen.slowPathJumpList().link(&m_jit); 2867 silentSpillAllRegisters(resultRegs); 2868 2869 if (leftOperand.isConst()) { 2870 leftRegs = resultRegs; 2871 m_jit.moveValue(leftChild->asJSValue(), leftRegs); 2872 } else if (rightOperand.isConst()) { 2873 rightRegs = resultRegs; 2874 m_jit.moveValue(rightChild->asJSValue(), rightRegs); 2875 } 2876 2877 callOperation(snippetSlowPathFunction, resultRegs, leftRegs, rightRegs); 2878 2879 silentFillAllRegisters(resultRegs); 2880 m_jit.exceptionCheck(); 2881 2882 gen.endJumpList().link(&m_jit); 2883 jsValueResult(resultRegs, node); 2884 } 2885 2789 2886 void SpeculativeJIT::compileBitwiseOp(Node* node) 2790 2887 { … … 2792 2889 Edge& leftChild = node->child1(); 2793 2890 Edge& rightChild = node->child2(); 2891 2892 if (leftChild.useKind() == UntypedUse || rightChild.useKind() == UntypedUse) { 2893 switch (op) { 2894 case BitAnd: 2895 emitUntypedBitOp<JITBitAndGenerator, operationValueBitAnd>(node); 2896 return; 2897 case BitOr: 2898 emitUntypedBitOp<JITBitOrGenerator, operationValueBitOr>(node); 2899 return; 2900 case BitXor: 2901 emitUntypedBitOp<JITBitXorGenerator, operationValueBitXor>(node); 2902 return; 2903 default: 2904 RELEASE_ASSERT_NOT_REACHED(); 2905 } 2906 } 2794 2907 2795 2908 if (leftChild->isInt32Constant()) { … … 2822 2935 } 2823 2936 2937 void SpeculativeJIT::emitUntypedRightShiftBitOp(Node* node) 2938 { 2939 J_JITOperation_EJJ snippetSlowPathFunction = node->op() == BitRShift 2940 ? operationValueBitRShift : operationValueBitURShift; 2941 JITRightShiftGenerator::ShiftType shiftType = node->op() == BitRShift 2942 ? JITRightShiftGenerator::SignedShift : JITRightShiftGenerator::UnsignedShift; 2943 2944 Edge& leftChild = node->child1(); 2945 Edge& rightChild = node->child2(); 2946 2947 if (isKnownNotNumber(leftChild.node()) || isKnownNotNumber(rightChild.node())) { 2948 JSValueOperand left(this, leftChild); 2949 JSValueOperand right(this, rightChild); 2950 JSValueRegs leftRegs = left.jsValueRegs(); 2951 JSValueRegs rightRegs = right.jsValueRegs(); 2952 #if USE(JSVALUE64) 2953 GPRTemporary result(this); 2954 JSValueRegs resultRegs = JSValueRegs(result.gpr()); 2955 #else 2956 GPRTemporary resultTag(this); 2957 GPRTemporary resultPayload(this); 2958 JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr()); 2959 #endif 2960 flushRegisters(); 2961 callOperation(snippetSlowPathFunction, resultRegs, leftRegs, rightRegs); 2962 m_jit.exceptionCheck(); 2963 2964 jsValueResult(resultRegs, node); 2965 return; 2966 } 2967 2968 Optional<JSValueOperand> left; 2969 Optional<JSValueOperand> right; 2970 2971 JSValueRegs leftRegs; 2972 JSValueRegs rightRegs; 2973 2974 FPRTemporary leftNumber(this); 2975 FPRReg leftFPR = leftNumber.fpr(); 2976 2977 #if USE(JSVALUE64) 2978 GPRTemporary result(this); 2979 JSValueRegs resultRegs = JSValueRegs(result.gpr()); 2980 GPRTemporary scratch(this); 2981 GPRReg scratchGPR = scratch.gpr(); 2982 FPRReg scratchFPR = InvalidFPRReg; 2983 #else 2984 GPRTemporary resultTag(this); 2985 GPRTemporary resultPayload(this); 2986 JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr()); 2987 GPRReg scratchGPR = resultTag.gpr(); 2988 FPRTemporary fprScratch(this); 2989 FPRReg scratchFPR = fprScratch.fpr(); 2990 #endif 2991 2992 SnippetOperand leftOperand; 2993 SnippetOperand rightOperand; 2994 2995 // The snippet generator does not support both operands being constant. If the left 2996 // operand is already const, we'll ignore the right operand's constness. 2997 if (leftChild->isInt32Constant()) 2998 leftOperand.setConstInt32(leftChild->asInt32()); 2999 else if (rightChild->isInt32Constant()) 3000 rightOperand.setConstInt32(rightChild->asInt32()); 3001 3002 RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst()); 3003 3004 if (!leftOperand.isConst()) { 3005 left = JSValueOperand(this, leftChild); 3006 leftRegs = left->jsValueRegs(); 3007 } 3008 if (!rightOperand.isConst()) { 3009 right = JSValueOperand(this, rightChild); 3010 rightRegs = right->jsValueRegs(); 3011 } 3012 3013 JITRightShiftGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, 3014 leftFPR, scratchGPR, scratchFPR, shiftType); 3015 gen.generateFastPath(m_jit); 3016 3017 ASSERT(gen.didEmitFastPath()); 3018 gen.endJumpList().append(m_jit.jump()); 3019 3020 gen.slowPathJumpList().link(&m_jit); 3021 silentSpillAllRegisters(resultRegs); 3022 3023 if (leftOperand.isConst()) { 3024 leftRegs = resultRegs; 3025 m_jit.moveValue(leftChild->asJSValue(), leftRegs); 3026 } else if (rightOperand.isConst()) { 3027 rightRegs = resultRegs; 3028 m_jit.moveValue(rightChild->asJSValue(), rightRegs); 3029 } 3030 3031 callOperation(snippetSlowPathFunction, resultRegs, leftRegs, rightRegs); 3032 3033 silentFillAllRegisters(resultRegs); 3034 m_jit.exceptionCheck(); 3035 3036 gen.endJumpList().link(&m_jit); 3037 jsValueResult(resultRegs, node); 3038 return; 3039 } 3040 2824 3041 void SpeculativeJIT::compileShiftOp(Node* node) 2825 3042 { … … 2827 3044 Edge& leftChild = node->child1(); 2828 3045 Edge& rightChild = node->child2(); 3046 3047 if (leftChild.useKind() == UntypedUse || rightChild.useKind() == UntypedUse) { 3048 switch (op) { 3049 case BitLShift: 3050 emitUntypedBitOp<JITLeftShiftGenerator, operationValueBitLShift>(node); 3051 return; 3052 case BitRShift: 3053 case BitURShift: 3054 emitUntypedRightShiftBitOp(node); 3055 return; 3056 default: 3057 RELEASE_ASSERT_NOT_REACHED(); 3058 } 3059 } 2829 3060 2830 3061 if (rightChild->isInt32Constant()) { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r194087 r194113 2218 2218 void compileUInt32ToNumber(Node*); 2219 2219 void compileDoubleAsInt32(Node*); 2220 2221 template<typename SnippetGenerator, J_JITOperation_EJJ slowPathFunction> 2222 void emitUntypedBitOp(Node*); 2220 2223 void compileBitwiseOp(Node*); 2224 2225 void emitUntypedRightShiftBitOp(Node*); 2221 2226 void compileShiftOp(Node*); 2227 2222 2228 void compileValueAdd(Node*); 2223 2229 void compileArithAdd(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
r188519 r194113 75 75 handleCommutativity(); 76 76 77 if (m_node->child 2()->isInt32Constant() && !m_node->child2()->asInt32()) {77 if (m_node->child1().useKind() != UntypedUse && m_node->child2()->isInt32Constant() && !m_node->child2()->asInt32()) { 78 78 convertToIdentityOverChild1(); 79 79 break; … … 89 89 case BitRShift: 90 90 case BitURShift: 91 if (m_node->child 2()->isInt32Constant() && !(m_node->child2()->asInt32() & 0x1f)) {91 if (m_node->child1().useKind() != UntypedUse && m_node->child2()->isInt32Constant() && !(m_node->child2()->asInt32() & 0x1f)) { 92 92 convertToIdentityOverChild1(); 93 93 break; -
trunk/Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp
r193985 r194113 33 33 #include "GPRInfo.h" 34 34 #include "JITAddGenerator.h" 35 #include "JITBitAndGenerator.h" 36 #include "JITBitOrGenerator.h" 37 #include "JITBitXorGenerator.h" 35 38 #include "JITDivGenerator.h" 39 #include "JITLeftShiftGenerator.h" 36 40 #include "JITMulGenerator.h" 41 #include "JITRightShiftGenerator.h" 37 42 #include "JITSubGenerator.h" 38 43 #include "ScratchRegisterAllocator.h" … … 160 165 }; 161 166 167 template<typename SnippetGenerator> 168 void generateBinaryBitOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit, 169 GPRReg result, GPRReg left, GPRReg right, RegisterSet usedRegisters, 170 CCallHelpers::Jump& done, CCallHelpers::Jump& slowPathStart) 171 { 172 ScratchRegisterAllocator allocator(usedRegisters); 173 174 BinarySnippetRegisterContext context(allocator, result, left, right); 175 176 GPRReg scratchGPR = allocator.allocateScratchGPR(); 177 178 SnippetGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result), 179 JSValueRegs(left), JSValueRegs(right), scratchGPR); 180 181 unsigned numberOfBytesUsedToPreserveReusedRegisters = 182 allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 183 184 context.initializeRegisters(jit); 185 gen.generateFastPath(jit); 186 187 ASSERT(gen.didEmitFastPath()); 188 gen.endJumpList().link(&jit); 189 190 context.restoreRegisters(jit); 191 allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, 192 ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 193 done = jit.jump(); 194 195 gen.slowPathJumpList().link(&jit); 196 context.restoreRegisters(jit); 197 allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, 198 ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 199 slowPathStart = jit.jump(); 200 } 201 202 static void generateRightShiftFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit, 203 GPRReg result, GPRReg left, GPRReg right, RegisterSet usedRegisters, 204 CCallHelpers::Jump& done, CCallHelpers::Jump& slowPathStart, 205 JITRightShiftGenerator::ShiftType shiftType) 206 { 207 ScratchRegisterAllocator allocator(usedRegisters); 208 209 BinarySnippetRegisterContext context(allocator, result, left, right); 210 211 FPRReg leftFPR = allocator.allocateScratchFPR(); 212 GPRReg scratchGPR = allocator.allocateScratchGPR(); 213 214 JITRightShiftGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result), 215 JSValueRegs(left), JSValueRegs(right), leftFPR, scratchGPR, InvalidFPRReg, shiftType); 216 217 unsigned numberOfBytesUsedToPreserveReusedRegisters = 218 allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 219 220 context.initializeRegisters(jit); 221 gen.generateFastPath(jit); 222 223 ASSERT(gen.didEmitFastPath()); 224 gen.endJumpList().link(&jit); 225 context.restoreRegisters(jit); 226 allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, 227 ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 228 done = jit.jump(); 229 230 gen.slowPathJumpList().link(&jit); 231 context.restoreRegisters(jit); 232 allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, 233 ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 234 slowPathStart = jit.jump(); 235 } 236 162 237 template<typename BinaryArithOpGenerator, ScratchFPRUsage scratchFPRUsage = DontNeedScratchFPR> 163 238 void generateBinaryArithOpFastPath(BinaryOpDescriptor& ic, CCallHelpers& jit, … … 179 254 JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR); 180 255 181 autonumberOfBytesUsedToPreserveReusedRegisters =256 unsigned numberOfBytesUsedToPreserveReusedRegisters = 182 257 allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 183 258 … … 189 264 context.restoreRegisters(jit); 190 265 allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, 191 ScratchRegisterAllocator::ExtraStackSpace:: SpaceForCCall);266 ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 192 267 done = jit.jump(); 193 268 … … 195 270 context.restoreRegisters(jit); 196 271 allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, 197 ScratchRegisterAllocator::ExtraStackSpace:: SpaceForCCall);272 ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 198 273 slowPathStart = jit.jump(); 199 274 } … … 204 279 { 205 280 switch (ic.nodeType()) { 281 case BitAnd: 282 generateBinaryBitOpFastPath<JITBitAndGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart); 283 break; 284 case BitOr: 285 generateBinaryBitOpFastPath<JITBitOrGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart); 286 break; 287 case BitXor: 288 generateBinaryBitOpFastPath<JITBitXorGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart); 289 break; 290 case BitLShift: 291 generateBinaryBitOpFastPath<JITLeftShiftGenerator>(ic, jit, result, left, right, usedRegisters, done, slowPathStart); 292 break; 293 case BitRShift: 294 generateRightShiftFastPath(ic, jit, result, left, right, usedRegisters, done, slowPathStart, JITRightShiftGenerator::SignedShift); 295 break; 296 case BitURShift: 297 generateRightShiftFastPath(ic, jit, result, left, right, usedRegisters, done, slowPathStart, JITRightShiftGenerator::UnsignedShift); 298 break; 206 299 case ArithDiv: 207 300 generateBinaryArithOpFastPath<JITDivGenerator, NeedScratchFPR>(ic, jit, result, left, right, usedRegisters, done, slowPathStart); -
trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h
r193985 r194113 165 165 }; 166 166 167 class BitAndDescriptor : public BinaryOpDescriptor { 168 public: 169 BitAndDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand) 170 : BinaryOpDescriptor(nodeType(), stackmapID, codeOrigin, icSize(), opName(), slowPathFunction(), leftOperand, rightOperand) 171 { } 172 173 static size_t icSize() { return sizeOfBitAnd(); } 174 static unsigned nodeType() { return DFG::BitAnd; } 175 static const char* opName() { return "BitAnd"; } 176 static J_JITOperation_EJJ slowPathFunction() { return DFG::operationValueBitAnd; } 177 static J_JITOperation_EJJ nonNumberSlowPathFunction() { return slowPathFunction(); } 178 }; 179 180 class BitOrDescriptor : public BinaryOpDescriptor { 181 public: 182 BitOrDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand) 183 : BinaryOpDescriptor(nodeType(), stackmapID, codeOrigin, icSize(), opName(), slowPathFunction(), leftOperand, rightOperand) 184 { } 185 186 static size_t icSize() { return sizeOfBitOr(); } 187 static unsigned nodeType() { return DFG::BitOr; } 188 static const char* opName() { return "BitOr"; } 189 static J_JITOperation_EJJ slowPathFunction() { return DFG::operationValueBitOr; } 190 static J_JITOperation_EJJ nonNumberSlowPathFunction() { return slowPathFunction(); } 191 }; 192 193 class BitXorDescriptor : public BinaryOpDescriptor { 194 public: 195 BitXorDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand) 196 : BinaryOpDescriptor(nodeType(), stackmapID, codeOrigin, icSize(), opName(), slowPathFunction(), leftOperand, rightOperand) 197 { } 198 199 static size_t icSize() { return sizeOfBitXor(); } 200 static unsigned nodeType() { return DFG::BitXor; } 201 static const char* opName() { return "BitXor"; } 202 static J_JITOperation_EJJ slowPathFunction() { return DFG::operationValueBitXor; } 203 static J_JITOperation_EJJ nonNumberSlowPathFunction() { return slowPathFunction(); } 204 }; 205 206 class BitLShiftDescriptor : public BinaryOpDescriptor { 207 public: 208 BitLShiftDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand) 209 : BinaryOpDescriptor(nodeType(), stackmapID, codeOrigin, icSize(), opName(), slowPathFunction(), leftOperand, rightOperand) 210 { } 211 212 static size_t icSize() { return sizeOfBitLShift(); } 213 static unsigned nodeType() { return DFG::BitLShift; } 214 static const char* opName() { return "BitLShift"; } 215 static J_JITOperation_EJJ slowPathFunction() { return DFG::operationValueBitLShift; } 216 static J_JITOperation_EJJ nonNumberSlowPathFunction() { return slowPathFunction(); } 217 }; 218 219 class BitRShiftDescriptor : public BinaryOpDescriptor { 220 public: 221 BitRShiftDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand) 222 : BinaryOpDescriptor(nodeType(), stackmapID, codeOrigin, icSize(), opName(), slowPathFunction(), leftOperand, rightOperand) 223 { } 224 225 static size_t icSize() { return sizeOfBitRShift(); } 226 static unsigned nodeType() { return DFG::BitRShift; } 227 static const char* opName() { return "BitRShift"; } 228 static J_JITOperation_EJJ slowPathFunction() { return DFG::operationValueBitRShift; } 229 static J_JITOperation_EJJ nonNumberSlowPathFunction() { return slowPathFunction(); } 230 }; 231 232 class BitURShiftDescriptor : public BinaryOpDescriptor { 233 public: 234 BitURShiftDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const SnippetOperand& leftOperand, const SnippetOperand& rightOperand) 235 : BinaryOpDescriptor(nodeType(), stackmapID, codeOrigin, icSize(), opName(), slowPathFunction(), leftOperand, rightOperand) 236 { } 237 238 static size_t icSize() { return sizeOfBitURShift(); } 239 static unsigned nodeType() { return DFG::BitURShift; } 240 static const char* opName() { return "BitURShift"; } 241 static J_JITOperation_EJJ slowPathFunction() { return DFG::operationValueBitURShift; } 242 static J_JITOperation_EJJ nonNumberSlowPathFunction() { return slowPathFunction(); } 243 }; 244 167 245 class ArithDivDescriptor : public BinaryOpDescriptor { 168 246 public: -
trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp
r193781 r194113 126 126 #else 127 127 return 5; 128 #endif 129 } 130 131 size_t sizeOfBitAnd() 132 { 133 #if CPU(ARM64) 134 #ifdef NDEBUG 135 return 180; // ARM64 release. 136 #else 137 return 276; // ARM64 debug. 138 #endif 139 #else // CPU(X86_64) 140 #ifdef NDEBUG 141 return 199; // X86_64 release. 142 #else 143 return 286; // X86_64 debug. 144 #endif 145 #endif 146 } 147 148 size_t sizeOfBitOr() 149 { 150 #if CPU(ARM64) 151 #ifdef NDEBUG 152 return 180; // ARM64 release. 153 #else 154 return 276; // ARM64 debug. 155 #endif 156 #else // CPU(X86_64) 157 #ifdef NDEBUG 158 return 199; // X86_64 release. 159 #else 160 return 286; // X86_64 debug. 161 #endif 162 #endif 163 } 164 165 size_t sizeOfBitXor() 166 { 167 #if CPU(ARM64) 168 #ifdef NDEBUG 169 return 180; // ARM64 release. 170 #else 171 return 276; // ARM64 debug. 172 #endif 173 #else // CPU(X86_64) 174 #ifdef NDEBUG 175 return 199; // X86_64 release. 176 #else 177 return 286; // X86_64 debug. 178 #endif 179 #endif 180 } 181 182 size_t sizeOfBitLShift() 183 { 184 #if CPU(ARM64) 185 #ifdef NDEBUG 186 return 180; // ARM64 release. 187 #else 188 return 276; // ARM64 debug. 189 #endif 190 #else // CPU(X86_64) 191 #ifdef NDEBUG 192 return 199; // X86_64 release. 193 #else 194 return 286; // X86_64 debug. 195 #endif 196 #endif 197 } 198 199 size_t sizeOfBitRShift() 200 { 201 #if CPU(ARM64) 202 #ifdef NDEBUG 203 return 180; // ARM64 release. 204 #else 205 return 276; // ARM64 debug. 206 #endif 207 #else // CPU(X86_64) 208 #ifdef NDEBUG 209 return 199; // X86_64 release. 210 #else 211 return 286; // X86_64 debug. 212 #endif 213 #endif 214 } 215 216 size_t sizeOfBitURShift() 217 { 218 #if CPU(ARM64) 219 #ifdef NDEBUG 220 return 180; // ARM64 release. 221 #else 222 return 276; // ARM64 debug. 223 #endif 224 #else // CPU(X86_64) 225 #ifdef NDEBUG 226 return 199; // X86_64 release. 227 #else 228 return 286; // X86_64 debug. 229 #endif 128 230 #endif 129 231 } -
trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h
r193781 r194113 47 47 size_t sizeOfConstructForwardVarargs(); 48 48 size_t sizeOfIn(); 49 size_t sizeOfBitAnd(); 50 size_t sizeOfBitOr(); 51 size_t sizeOfBitXor(); 52 size_t sizeOfBitLShift(); 53 size_t sizeOfBitRShift(); 54 size_t sizeOfBitURShift(); 49 55 size_t sizeOfArithDiv(); 50 56 size_t sizeOfArithMul(); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r194092 r194113 2264 2264 void compileBitAnd() 2265 2265 { 2266 if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) { 2267 compileUntypedBinaryOp<BitAndDescriptor>(); 2268 return; 2269 } 2266 2270 setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); 2267 2271 } … … 2269 2273 void compileBitOr() 2270 2274 { 2275 if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) { 2276 compileUntypedBinaryOp<BitOrDescriptor>(); 2277 return; 2278 } 2271 2279 setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); 2272 2280 } … … 2274 2282 void compileBitXor() 2275 2283 { 2284 if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) { 2285 compileUntypedBinaryOp<BitXorDescriptor>(); 2286 return; 2287 } 2276 2288 setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); 2277 2289 } … … 2279 2291 void compileBitRShift() 2280 2292 { 2293 if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) { 2294 compileUntypedBinaryOp<BitRShiftDescriptor>(); 2295 return; 2296 } 2281 2297 setInt32(m_out.aShr( 2282 2298 lowInt32(m_node->child1()), … … 2286 2302 void compileBitLShift() 2287 2303 { 2304 if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) { 2305 compileUntypedBinaryOp<BitLShiftDescriptor>(); 2306 return; 2307 } 2288 2308 setInt32(m_out.shl( 2289 2309 lowInt32(m_node->child1()), … … 2293 2313 void compileBitURShift() 2294 2314 { 2315 if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) { 2316 compileUntypedBinaryOp<BitURShiftDescriptor>(); 2317 return; 2318 } 2295 2319 setInt32(m_out.lShr( 2296 2320 lowInt32(m_node->child1()), -
trunk/Source/JavaScriptCore/jit/JITLeftShiftGenerator.cpp
r193788 r194113 33 33 void JITLeftShiftGenerator::generateFastPath(CCallHelpers& jit) 34 34 { 35 ASSERT(m_scratchGPR != InvalidGPRReg); 36 ASSERT(m_scratchGPR != m_left.payloadGPR()); 37 ASSERT(m_scratchGPR != m_right.payloadGPR()); 38 #if USE(JSVALUE32_64) 39 ASSERT(m_scratchGPR != m_left.tagGPR()); 40 ASSERT(m_scratchGPR != m_right.tagGPR()); 41 #endif 42 35 43 ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32()); 36 44 … … 48 56 m_slowPathJumpList.append(jit.branchIfNotInt32(m_right)); 49 57 58 GPRReg rightOperandGPR = m_right.payloadGPR(); 59 if (rightOperandGPR == m_result.payloadGPR()) { 60 jit.move(rightOperandGPR, m_scratchGPR); 61 rightOperandGPR = m_scratchGPR; 62 } 63 50 64 if (m_leftOperand.isConstInt32()) { 51 65 #if USE(JSVALUE32_64) … … 58 72 } 59 73 60 jit.lshift32( m_right.payloadGPR(), m_result.payloadGPR());74 jit.lshift32(rightOperandGPR, m_result.payloadGPR()); 61 75 } 62 76 -
trunk/Source/JavaScriptCore/jit/JITLeftShiftGenerator.h
r193788 r194113 36 36 public: 37 37 JITLeftShiftGenerator(const SnippetOperand& leftOperand, const SnippetOperand& rightOperand, 38 JSValueRegs result, JSValueRegs left, JSValueRegs right, GPRReg unused = InvalidGPRReg)39 : JITBitBinaryOpGenerator(leftOperand, rightOperand, result, left, right, unused)38 JSValueRegs result, JSValueRegs left, JSValueRegs right, GPRReg scratchGPR) 39 : JITBitBinaryOpGenerator(leftOperand, rightOperand, result, left, right, scratchGPR) 40 40 { } 41 41 -
trunk/Source/JavaScriptCore/jit/JITRightShiftGenerator.cpp
r194042 r194113 88 88 m_slowPathJumpList.append(jit.branchIfNotInt32(m_right)); 89 89 90 GPRReg rightOperandGPR = m_right.payloadGPR(); 91 if (rightOperandGPR == m_result.payloadGPR()) 92 rightOperandGPR = m_scratchGPR; 93 90 94 CCallHelpers::Jump leftNotInt; 91 95 if (m_leftOperand.isConstInt32()) { 96 jit.move(m_right.payloadGPR(), rightOperandGPR); 92 97 #if USE(JSVALUE32_64) 93 98 jit.move(m_right.tagGPR(), m_result.tagGPR()); … … 96 101 } else { 97 102 leftNotInt = jit.branchIfNotInt32(m_left); 103 jit.move(m_right.payloadGPR(), rightOperandGPR); 98 104 jit.moveValueRegs(m_left, m_result); 99 105 } 100 106 101 107 if (m_shiftType == SignedShift) 102 jit.rshift32( m_right.payloadGPR(), m_result.payloadGPR());108 jit.rshift32(rightOperandGPR, m_result.payloadGPR()); 103 109 else 104 jit.urshift32( m_right.payloadGPR(), m_result.payloadGPR());110 jit.urshift32(rightOperandGPR, m_result.payloadGPR()); 105 111 #if USE(JSVALUE64) 106 112 jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
Note:
See TracChangeset
for help on using the changeset viewer.