Changeset 91226 in webkit
- Timestamp:
- Jul 18, 2011 5:36:37 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r91225 r91226 1 2011-07-18 Filip Pizlo <fpizlo@apple.com> 2 3 DFG JIT does not optimize strict equality as effectively as the old JIT does. 4 https://bugs.webkit.org/show_bug.cgi?id=64759 5 6 Reviewed by Gavin Barraclough. 7 8 This adds a more complete set of strict equality optimizations. If either 9 operand is known numeric, then the code reverts to the old style of optimizing 10 (first try integer comparison). Otherwise it uses the old JIT's trick of 11 first simultaneously checking if both operands are either numbers or cells; 12 if not then a fast path is taken. 13 14 * dfg/DFGJITCodeGenerator.cpp: 15 (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeStrictEq): 16 (JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeStrictEq): 17 (JSC::DFG::JITCodeGenerator::nonSpeculativeStrictEq): 18 * dfg/DFGJITCodeGenerator.h: 19 * dfg/DFGNonSpeculativeJIT.cpp: 20 (JSC::DFG::NonSpeculativeJIT::compile): 21 * dfg/DFGOperations.cpp: 22 * dfg/DFGOperations.h: 23 * dfg/DFGSpeculativeJIT.cpp: 24 (JSC::DFG::SpeculativeJIT::compile): 25 1 26 2011-07-18 Gavin Barraclough <barraclough@apple.com> 2 27 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
r91208 r91226 765 765 } 766 766 767 void JITCodeGenerator::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert) 768 { 769 Node& branchNode = m_jit.graph()[branchNodeIndex]; 770 BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset()); 771 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset()); 772 773 // The branch instruction will branch to the taken block. 774 // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through. 775 if (taken == (m_block + 1)) { 776 invert = !invert; 777 BlockIndex tmp = taken; 778 taken = notTaken; 779 notTaken = tmp; 780 } 781 782 JSValueOperand arg1(this, node.child1()); 783 JSValueOperand arg2(this, node.child2()); 784 GPRReg arg1GPR = arg1.gpr(); 785 GPRReg arg2GPR = arg2.gpr(); 786 787 GPRTemporary result(this); 788 GPRReg resultGPR = result.gpr(); 789 790 if (isKnownCell(node.child1()) && isKnownCell(node.child2())) { 791 // see if we get lucky: if the arguments are cells and they reference the same 792 // cell, then they must be strictly equal. 793 addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken); 794 795 silentSpillAllRegisters(resultGPR); 796 setupStubArguments(arg1GPR, arg2GPR); 797 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 798 appendCallWithExceptionCheck(operationCompareStrictEqCell); 799 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 800 silentFillAllRegisters(resultGPR); 801 802 addBranch(m_jit.branchTest8(invert ? JITCompiler::NonZero : JITCompiler::Zero, resultGPR), taken); 803 } else { 804 m_jit.orPtr(arg1GPR, arg2GPR, resultGPR); 805 806 JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister); 807 808 JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister); 809 810 addBranch(m_jit.branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR), taken); 811 addBranch(m_jit.jump(), notTaken); 812 813 twoCellsCase.link(&m_jit); 814 addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken); 815 816 numberCase.link(&m_jit); 817 818 silentSpillAllRegisters(resultGPR); 819 setupStubArguments(arg1GPR, arg2GPR); 820 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 821 appendCallWithExceptionCheck(operationCompareStrictEq); 822 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 823 silentFillAllRegisters(resultGPR); 824 825 addBranch(m_jit.branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, resultGPR), taken); 826 } 827 828 if (notTaken != (m_block + 1)) 829 addBranch(m_jit.jump(), notTaken); 830 } 831 832 void JITCodeGenerator::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert) 833 { 834 JSValueOperand arg1(this, node.child1()); 835 JSValueOperand arg2(this, node.child2()); 836 GPRReg arg1GPR = arg1.gpr(); 837 GPRReg arg2GPR = arg2.gpr(); 838 839 GPRTemporary result(this); 840 GPRReg resultGPR = result.gpr(); 841 842 if (isKnownCell(node.child1()) && isKnownCell(node.child2())) { 843 // see if we get lucky: if the arguments are cells and they reference the same 844 // cell, then they must be strictly equal. 845 JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR); 846 847 m_jit.move(JITCompiler::TrustedImmPtr(JSValue::encode(jsBoolean(!invert))), resultGPR); 848 849 JITCompiler::Jump done = m_jit.jump(); 850 851 notEqualCase.link(&m_jit); 852 853 silentSpillAllRegisters(resultGPR); 854 setupStubArguments(arg1GPR, arg2GPR); 855 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 856 appendCallWithExceptionCheck(operationCompareStrictEqCell); 857 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 858 silentFillAllRegisters(resultGPR); 859 860 m_jit.andPtr(JITCompiler::TrustedImm32(1), resultGPR); 861 m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR); 862 863 done.link(&m_jit); 864 } else { 865 m_jit.orPtr(arg1GPR, arg2GPR, resultGPR); 866 867 JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister); 868 869 JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister); 870 871 m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR); 872 873 JITCompiler::Jump done1 = m_jit.jump(); 874 875 twoCellsCase.link(&m_jit); 876 JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR); 877 878 m_jit.move(JITCompiler::TrustedImmPtr(JSValue::encode(jsBoolean(!invert))), resultGPR); 879 880 JITCompiler::Jump done2 = m_jit.jump(); 881 882 numberCase.link(&m_jit); 883 notEqualCase.link(&m_jit); 884 885 silentSpillAllRegisters(resultGPR); 886 setupStubArguments(arg1GPR, arg2GPR); 887 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 888 appendCallWithExceptionCheck(operationCompareStrictEq); 889 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 890 silentFillAllRegisters(resultGPR); 891 892 m_jit.andPtr(JITCompiler::TrustedImm32(1), resultGPR); 893 894 done1.link(&m_jit); 895 896 m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR); 897 898 done2.link(&m_jit); 899 } 900 901 jsValueResult(resultGPR, m_compileIndex); 902 } 903 904 bool JITCodeGenerator::nonSpeculativeStrictEq(Node& node, bool invert) 905 { 906 if (!invert && (isKnownNumeric(node.child1()) || isKnownNumeric(node.child2()))) 907 return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq); 908 909 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 910 if (branchNodeIndex != NoNode) { 911 ASSERT(node.adjustedRefCount() == 1); 912 913 nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert); 914 915 use(node.child1()); 916 use(node.child2()); 917 m_compileIndex = branchNodeIndex; 918 919 return true; 920 } 921 922 nonSpeculativeNonPeepholeStrictEq(node, invert); 923 924 return false; 925 } 926 767 927 void JITCodeGenerator::emitBranch(Node& node) 768 928 { -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r91208 r91226 572 572 bool nonSpeculativeCompare(Node&, MacroAssembler::RelationalCondition, Z_DFGOperation_EJJ helperFunction); 573 573 574 void nonSpeculativePeepholeStrictEq(Node&, NodeIndex branchNodeIndex, bool invert = false); 575 void nonSpeculativeNonPeepholeStrictEq(Node&, bool invert = false); 576 bool nonSpeculativeStrictEq(Node&, bool invert = false); 577 574 578 void emitBranch(Node&); 575 579 -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
r91208 r91226 689 689 690 690 case CompareStrictEq: 691 if (nonSpeculative Compare(node, MacroAssembler::Equal, operationCompareStrictEq))691 if (nonSpeculativeStrictEq(node)) 692 692 return; 693 693 break; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r91168 r91226 425 425 } 426 426 427 bool operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 428 { 429 JSValue op1 = JSValue::decode(encodedOp1); 430 JSValue op2 = JSValue::decode(encodedOp2); 431 432 ASSERT(op1.isCell()); 433 ASSERT(op2.isCell()); 434 435 return JSValue::strictEqualSlowCaseInline(exec, op1, op2); 436 } 437 427 438 bool operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 428 439 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r90950 r91226 83 83 bool operationCompareGreaterEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 84 84 bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 85 bool operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 85 86 bool operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 86 87 void* operationVirtualCall(ExecState*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r91208 r91226 783 783 784 784 case CompareStrictEq: 785 if ( compare(node, JITCompiler::Equal, operationCompareStrictEq))785 if (nonSpeculativeStrictEq(node)) 786 786 return; 787 787 break;
Note: See TracChangeset
for help on using the changeset viewer.