Changeset 90371 in webkit
- Timestamp:
- Jul 4, 2011 12:26:05 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r90352 r90371 1 2011-07-04 Gavin Barraclough <barraclough@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=63881 4 Need separate bytecodes for handling >, >= comparisons. 5 6 Reviewed by Oliver Hunt. 7 8 This clears the way to fix Bug#63880. We currently handle greater-than comparisons 9 as being using the corresponding op_less, etc opcodes. This is incorrect with 10 respect to evaluation ordering of the implicit conversions performed on operands - 11 we should be calling ToPrimitive on the LHS and RHS operands to the greater than, 12 but instead convert RHS then LHS. 13 14 This patch adds opcodes for greater-than comparisons mirroring existing ones used 15 for less-than. 16 17 * bytecode/CodeBlock.cpp: 18 (JSC::CodeBlock::dump): 19 * bytecode/Opcode.h: 20 * bytecompiler/BytecodeGenerator.cpp: 21 (JSC::BytecodeGenerator::emitJumpIfTrue): 22 (JSC::BytecodeGenerator::emitJumpIfFalse): 23 * bytecompiler/NodesCodegen.cpp: 24 * dfg/DFGByteCodeParser.cpp: 25 (JSC::DFG::ByteCodeParser::parseBlock): 26 * dfg/DFGNode.h: 27 * dfg/DFGNonSpeculativeJIT.cpp: 28 (JSC::DFG::NonSpeculativeJIT::compare): 29 (JSC::DFG::NonSpeculativeJIT::compile): 30 * dfg/DFGNonSpeculativeJIT.h: 31 * dfg/DFGOperations.cpp: 32 * dfg/DFGOperations.h: 33 * dfg/DFGSpeculativeJIT.cpp: 34 (JSC::DFG::SpeculativeJIT::compare): 35 (JSC::DFG::SpeculativeJIT::compile): 36 * dfg/DFGSpeculativeJIT.h: 37 * interpreter/Interpreter.cpp: 38 (JSC::Interpreter::privateExecute): 39 * jit/JIT.cpp: 40 (JSC::JIT::privateCompileMainPass): 41 (JSC::JIT::privateCompileSlowCases): 42 * jit/JIT.h: 43 (JSC::JIT::emit_op_loop_if_greater): 44 (JSC::JIT::emitSlow_op_loop_if_greater): 45 (JSC::JIT::emit_op_loop_if_greatereq): 46 (JSC::JIT::emitSlow_op_loop_if_greatereq): 47 * jit/JITArithmetic.cpp: 48 (JSC::JIT::emit_op_jgreater): 49 (JSC::JIT::emit_op_jgreatereq): 50 (JSC::JIT::emit_op_jngreater): 51 (JSC::JIT::emit_op_jngreatereq): 52 (JSC::JIT::emitSlow_op_jgreater): 53 (JSC::JIT::emitSlow_op_jgreatereq): 54 (JSC::JIT::emitSlow_op_jngreater): 55 (JSC::JIT::emitSlow_op_jngreatereq): 56 (JSC::JIT::emit_compareAndJumpSlow): 57 * jit/JITArithmetic32_64.cpp: 58 (JSC::JIT::emitBinaryDoubleOp): 59 * jit/JITStubs.cpp: 60 (JSC::DEFINE_STUB_FUNCTION): 61 * jit/JITStubs.h: 62 * parser/NodeConstructors.h: 63 (JSC::GreaterNode::GreaterNode): 64 (JSC::GreaterEqNode::GreaterEqNode): 65 * parser/Nodes.h: 66 1 67 2011-07-03 Gavin Barraclough <barraclough@apple.com> 2 68 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r89885 r90371 587 587 break; 588 588 } 589 case op_greater: { 590 printBinaryOp(exec, location, it, "greater"); 591 break; 592 } 593 case op_greatereq: { 594 printBinaryOp(exec, location, it, "greatereq"); 595 break; 596 } 589 597 case op_pre_inc: { 590 598 int r0 = (++it)->u.operand; … … 996 1004 break; 997 1005 } 1006 case op_jless: { 1007 int r0 = (++it)->u.operand; 1008 int r1 = (++it)->u.operand; 1009 int offset = (++it)->u.operand; 1010 printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1011 break; 1012 } 1013 case op_jlesseq: { 1014 int r0 = (++it)->u.operand; 1015 int r1 = (++it)->u.operand; 1016 int offset = (++it)->u.operand; 1017 printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1018 break; 1019 } 1020 case op_jgreater: { 1021 int r0 = (++it)->u.operand; 1022 int r1 = (++it)->u.operand; 1023 int offset = (++it)->u.operand; 1024 printf("[%4d] jgreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1025 break; 1026 } 1027 case op_jgreatereq: { 1028 int r0 = (++it)->u.operand; 1029 int r1 = (++it)->u.operand; 1030 int offset = (++it)->u.operand; 1031 printf("[%4d] jgreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1032 break; 1033 } 998 1034 case op_jnless: { 999 1035 int r0 = (++it)->u.operand; … … 1010 1046 break; 1011 1047 } 1048 case op_jngreater: { 1049 int r0 = (++it)->u.operand; 1050 int r1 = (++it)->u.operand; 1051 int offset = (++it)->u.operand; 1052 printf("[%4d] jngreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1053 break; 1054 } 1055 case op_jngreatereq: { 1056 int r0 = (++it)->u.operand; 1057 int r1 = (++it)->u.operand; 1058 int offset = (++it)->u.operand; 1059 printf("[%4d] jngreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1060 break; 1061 } 1012 1062 case op_loop_if_less: { 1013 1063 int r0 = (++it)->u.operand; … … 1017 1067 break; 1018 1068 } 1019 case op_jless: {1020 int r0 = (++it)->u.operand;1021 int r1 = (++it)->u.operand;1022 int offset = (++it)->u.operand;1023 printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);1024 break;1025 }1026 case op_jlesseq: {1027 int r0 = (++it)->u.operand;1028 int r1 = (++it)->u.operand;1029 int offset = (++it)->u.operand;1030 printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);1031 break;1032 }1033 1069 case op_loop_if_lesseq: { 1034 1070 int r0 = (++it)->u.operand; … … 1036 1072 int offset = (++it)->u.operand; 1037 1073 printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1074 break; 1075 } 1076 case op_loop_if_greater: { 1077 int r0 = (++it)->u.operand; 1078 int r1 = (++it)->u.operand; 1079 int offset = (++it)->u.operand; 1080 printf("[%4d] loop_if_greater\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1081 break; 1082 } 1083 case op_loop_if_greatereq: { 1084 int r0 = (++it)->u.operand; 1085 int r1 = (++it)->u.operand; 1086 int offset = (++it)->u.operand; 1087 printf("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); 1038 1088 break; 1039 1089 } -
trunk/Source/JavaScriptCore/bytecode/Opcode.h
r88873 r90371 63 63 macro(op_less, 4) \ 64 64 macro(op_lesseq, 4) \ 65 macro(op_greater, 4) \ 66 macro(op_greatereq, 4) \ 65 67 \ 66 68 macro(op_pre_inc, 2) \ … … 146 148 macro(op_jneq_null, 3) \ 147 149 macro(op_jneq_ptr, 4) \ 150 macro(op_jless, 4) \ 151 macro(op_jlesseq, 4) \ 152 macro(op_jgreater, 4) \ 153 macro(op_jgreatereq, 4) \ 148 154 macro(op_jnless, 4) \ 149 155 macro(op_jnlesseq, 4) \ 150 macro(op_j less, 4) \151 macro(op_j lesseq, 4) \156 macro(op_jngreater, 4) \ 157 macro(op_jngreatereq, 4) \ 152 158 macro(op_jmp_scopes, 3) \ 153 159 macro(op_loop, 2) \ … … 156 162 macro(op_loop_if_less, 4) \ 157 163 macro(op_loop_if_lesseq, 4) \ 164 macro(op_loop_if_greater, 4) \ 165 macro(op_loop_if_greatereq, 4) \ 158 166 macro(op_switch_imm, 4) \ 159 167 macro(op_switch_char, 4) \ -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r89954 r90371 734 734 return target; 735 735 } 736 } else if (m_lastOpcodeID == op_greater) { 737 int dstIndex; 738 int src1Index; 739 int src2Index; 740 741 retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 742 743 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 744 rewindBinaryOp(); 745 746 size_t begin = instructions().size(); 747 emitOpcode(target->isForward() ? op_jgreater : op_loop_if_greater); 748 instructions().append(src1Index); 749 instructions().append(src2Index); 750 instructions().append(target->bind(begin, instructions().size())); 751 return target; 752 } 753 } else if (m_lastOpcodeID == op_greatereq) { 754 int dstIndex; 755 int src1Index; 756 int src2Index; 757 758 retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 759 760 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 761 rewindBinaryOp(); 762 763 size_t begin = instructions().size(); 764 emitOpcode(target->isForward() ? op_jgreatereq : op_loop_if_greatereq); 765 instructions().append(src1Index); 766 instructions().append(src2Index); 767 instructions().append(target->bind(begin, instructions().size())); 768 return target; 769 } 736 770 } else if (m_lastOpcodeID == op_eq_null && target->isForward()) { 737 771 int dstIndex; … … 805 839 size_t begin = instructions().size(); 806 840 emitOpcode(op_jnlesseq); 841 instructions().append(src1Index); 842 instructions().append(src2Index); 843 instructions().append(target->bind(begin, instructions().size())); 844 return target; 845 } 846 } else if (m_lastOpcodeID == op_greater && target->isForward()) { 847 int dstIndex; 848 int src1Index; 849 int src2Index; 850 851 retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 852 853 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 854 rewindBinaryOp(); 855 856 size_t begin = instructions().size(); 857 emitOpcode(op_jngreater); 858 instructions().append(src1Index); 859 instructions().append(src2Index); 860 instructions().append(target->bind(begin, instructions().size())); 861 return target; 862 } 863 } else if (m_lastOpcodeID == op_greatereq && target->isForward()) { 864 int dstIndex; 865 int src1Index; 866 int src2Index; 867 868 retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 869 870 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 871 rewindBinaryOp(); 872 873 size_t begin = instructions().size(); 874 emitOpcode(op_jngreatereq); 807 875 instructions().append(src1Index); 808 876 instructions().append(src2Index); -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r89392 r90371 986 986 } 987 987 988 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)989 {990 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));991 RegisterID* src2 = generator.emitNode(m_expr2);992 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));993 }994 995 988 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 996 989 { -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r90324 r90371 737 737 } 738 738 739 case op_greater: { 740 ARITHMETIC_OP(); 741 NodeIndex op1 = get(currentInstruction[2].u.operand); 742 NodeIndex op2 = get(currentInstruction[3].u.operand); 743 set(currentInstruction[1].u.operand, addToGraph(CompareGreater, op1, op2)); 744 NEXT_OPCODE(op_greater); 745 } 746 747 case op_greatereq: { 748 ARITHMETIC_OP(); 749 NodeIndex op1 = get(currentInstruction[2].u.operand); 750 NodeIndex op2 = get(currentInstruction[3].u.operand); 751 set(currentInstruction[1].u.operand, addToGraph(CompareGreaterEq, op1, op2)); 752 NEXT_OPCODE(op_greatereq); 753 } 754 739 755 case op_eq: { 740 756 ARITHMETIC_OP(); … … 912 928 } 913 929 930 case op_jless: { 931 unsigned relativeOffset = currentInstruction[3].u.operand; 932 NodeIndex op1 = get(currentInstruction[1].u.operand); 933 NodeIndex op2 = get(currentInstruction[2].u.operand); 934 NodeIndex condition = addToGraph(CompareLess, op1, op2); 935 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jless)), condition); 936 LAST_OPCODE(op_jless); 937 } 938 939 case op_jlesseq: { 940 unsigned relativeOffset = currentInstruction[3].u.operand; 941 NodeIndex op1 = get(currentInstruction[1].u.operand); 942 NodeIndex op2 = get(currentInstruction[2].u.operand); 943 NodeIndex condition = addToGraph(CompareLessEq, op1, op2); 944 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jlesseq)), condition); 945 LAST_OPCODE(op_jlesseq); 946 } 947 948 case op_jgreater: { 949 unsigned relativeOffset = currentInstruction[3].u.operand; 950 NodeIndex op1 = get(currentInstruction[1].u.operand); 951 NodeIndex op2 = get(currentInstruction[2].u.operand); 952 NodeIndex condition = addToGraph(CompareGreater, op1, op2); 953 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jgreater)), condition); 954 LAST_OPCODE(op_jgreater); 955 } 956 957 case op_jgreatereq: { 958 unsigned relativeOffset = currentInstruction[3].u.operand; 959 NodeIndex op1 = get(currentInstruction[1].u.operand); 960 NodeIndex op2 = get(currentInstruction[2].u.operand); 961 NodeIndex condition = addToGraph(CompareGreaterEq, op1, op2); 962 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jgreatereq)), condition); 963 LAST_OPCODE(op_jgreatereq); 964 } 965 914 966 case op_jnless: { 915 967 unsigned relativeOffset = currentInstruction[3].u.operand; … … 930 982 } 931 983 932 case op_j less: {984 case op_jngreater: { 933 985 unsigned relativeOffset = currentInstruction[3].u.operand; 934 986 NodeIndex op1 = get(currentInstruction[1].u.operand); 935 987 NodeIndex op2 = get(currentInstruction[2].u.operand); 936 NodeIndex condition = addToGraph(Compare Less, op1, op2);937 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jless)), condition);938 LAST_OPCODE(op_j less);939 } 940 941 case op_j lesseq: {988 NodeIndex condition = addToGraph(CompareGreater, op1, op2); 989 addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jngreater)), OpInfo(m_currentIndex + relativeOffset), condition); 990 LAST_OPCODE(op_jngreater); 991 } 992 993 case op_jngreatereq: { 942 994 unsigned relativeOffset = currentInstruction[3].u.operand; 943 995 NodeIndex op1 = get(currentInstruction[1].u.operand); 944 996 NodeIndex op2 = get(currentInstruction[2].u.operand); 945 NodeIndex condition = addToGraph(Compare LessEq, op1, op2);946 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jlesseq)), condition);947 LAST_OPCODE(op_j lesseq);997 NodeIndex condition = addToGraph(CompareGreaterEq, op1, op2); 998 addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jngreatereq)), OpInfo(m_currentIndex + relativeOffset), condition); 999 LAST_OPCODE(op_jngreatereq); 948 1000 } 949 1001 … … 964 1016 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_lesseq)), condition); 965 1017 LAST_OPCODE(op_loop_if_lesseq); 1018 } 1019 1020 case op_loop_if_greater: { 1021 unsigned relativeOffset = currentInstruction[3].u.operand; 1022 NodeIndex op1 = get(currentInstruction[1].u.operand); 1023 NodeIndex op2 = get(currentInstruction[2].u.operand); 1024 NodeIndex condition = addToGraph(CompareGreater, op1, op2); 1025 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_greater)), condition); 1026 LAST_OPCODE(op_loop_if_greater); 1027 } 1028 1029 case op_loop_if_greatereq: { 1030 unsigned relativeOffset = currentInstruction[3].u.operand; 1031 NodeIndex op1 = get(currentInstruction[1].u.operand); 1032 NodeIndex op2 = get(currentInstruction[2].u.operand); 1033 NodeIndex condition = addToGraph(CompareGreaterEq, op1, op2); 1034 addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_greatereq)), condition); 1035 LAST_OPCODE(op_loop_if_greatereq); 966 1036 } 967 1037 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r90324 r90371 134 134 macro(CompareLess, NodeResultJS | NodeMustGenerate) \ 135 135 macro(CompareLessEq, NodeResultJS | NodeMustGenerate) \ 136 macro(CompareGreater, NodeResultJS | NodeMustGenerate) \ 137 macro(CompareGreaterEq, NodeResultJS | NodeMustGenerate) \ 136 138 macro(CompareEq, NodeResultJS | NodeMustGenerate) \ 137 139 macro(CompareStrictEq, NodeResultJS) \ -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
r90324 r90371 343 343 } 344 344 345 void NonSpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition cond, const Z_DFGOperation_EJJ&helperFunction)345 void NonSpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction) 346 346 { 347 347 // FIXME: should do some peephole to fuse compare/branch … … 741 741 break; 742 742 743 case CompareGreater: 744 compare(node, MacroAssembler::GreaterThan, operationCompareGreater); 745 break; 746 747 case CompareGreaterEq: 748 compare(node, MacroAssembler::GreaterThanOrEqual, operationCompareGreaterEq); 749 break; 750 743 751 case CompareEq: 744 752 compare(node, MacroAssembler::Equal, operationCompareEq); -
trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.h
r89772 r90371 103 103 void knownConstantArithOp(NodeType op, NodeIndex regChild, NodeIndex immChild, bool commute); 104 104 void basicArithOp(NodeType op, Node&); 105 void compare(Node&, MacroAssembler::RelationalCondition, const Z_DFGOperation_EJJ&);106 105 void compare(Node&, MacroAssembler::RelationalCondition, Z_DFGOperation_EJJ); 106 107 107 EntryLocationVector m_entryLocations; 108 108 }; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r90324 r90371 378 378 } 379 379 380 bool operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 381 { 382 return jsLess(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1)); // FIXME: Bug#63880 383 } 384 385 bool operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 386 { 387 return jsLessEq(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1)); // FIXME: Bug#63880 388 } 389 380 390 bool operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) 381 391 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r90324 r90371 77 77 bool operationCompareLess(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 78 78 bool operationCompareLessEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 79 bool operationCompareGreater(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 80 bool operationCompareGreaterEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 79 81 bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 80 82 bool operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r90324 r90371 414 414 } 415 415 416 // Returns true if the compare is fused with a subsequent branch. 417 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, Z_DFGOperation_EJJ operation) 418 { 419 // Fused compare & branch. 420 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 421 if (branchNodeIndex != NoNode) { 422 // detectPeepHoleBranch currently only permits the branch to be the very next node, 423 // so can be no intervening nodes to also reference the compare. 424 ASSERT(node.adjustedRefCount() == 1); 425 426 if (shouldSpeculateInteger(node.child1, node.child2)) 427 compilePeepHoleIntegerBranch(node, branchNodeIndex, condition); 428 else 429 compilePeepHoleCall(node, branchNodeIndex, operation); 430 431 use(node.child1); 432 use(node.child2); 433 m_compileIndex = branchNodeIndex; 434 return true; 435 } 436 437 // Normal case, not fused to branch. 438 SpeculateIntegerOperand op1(this, node.child1); 439 SpeculateIntegerOperand op2(this, node.child2); 440 GPRTemporary result(this, op1, op2); 441 442 m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr()); 443 444 // If we add a DataFormatBool, we should use it here. 445 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 446 jsValueResult(result.gpr(), m_compileIndex); 447 return false; 448 } 449 416 450 void SpeculativeJIT::compile(Node& node) 417 451 { … … 739 773 } 740 774 741 case CompareLess: { 742 // Fused compare & branch. 743 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 744 if (branchNodeIndex != NoNode) { 745 // detectPeepHoleBranch currently only permits the branch to be the very next node, 746 // so can be no intervening nodes to also reference the compare. 747 ASSERT(node.adjustedRefCount() == 1); 748 749 if (shouldSpeculateInteger(node.child1, node.child2)) 750 compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThan); 751 else 752 compilePeepHoleCall(node, branchNodeIndex, operationCompareLess); 753 754 use(node.child1); 755 use(node.child2); 756 m_compileIndex = branchNodeIndex; 775 case CompareLess: 776 if (compare(node, JITCompiler::LessThan, operationCompareLess)) 757 777 return; 758 } 759 760 // Normal case, not fused to branch. 761 SpeculateIntegerOperand op1(this, node.child1); 762 SpeculateIntegerOperand op2(this, node.child2); 763 GPRTemporary result(this, op1, op2); 764 765 m_jit.compare32(JITCompiler::LessThan, op1.gpr(), op2.gpr(), result.gpr()); 766 767 // If we add a DataFormatBool, we should use it here. 768 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 769 jsValueResult(result.gpr(), m_compileIndex); 770 break; 771 } 772 773 case CompareLessEq: { 774 // Fused compare & branch. 775 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 776 if (branchNodeIndex != NoNode) { 777 // detectPeepHoleBranch currently only permits the branch to be the very next node, 778 // so can be no intervening nodes to also reference the compare. 779 ASSERT(node.adjustedRefCount() == 1); 780 781 if (shouldSpeculateInteger(node.child1, node.child2)) 782 compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThanOrEqual); 783 else 784 compilePeepHoleCall(node, branchNodeIndex, operationCompareLessEq); 785 786 use(node.child1); 787 use(node.child2); 788 m_compileIndex = branchNodeIndex; 778 break; 779 780 case CompareLessEq: 781 if (compare(node, JITCompiler::LessThanOrEqual, operationCompareLessEq)) 789 782 return; 790 } 791 792 // Normal case, not fused to branch. 793 SpeculateIntegerOperand op1(this, node.child1); 794 SpeculateIntegerOperand op2(this, node.child2); 795 GPRTemporary result(this, op1, op2); 796 797 m_jit.compare32(JITCompiler::LessThanOrEqual, op1.gpr(), op2.gpr(), result.gpr()); 798 799 // If we add a DataFormatBool, we should use it here. 800 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 801 jsValueResult(result.gpr(), m_compileIndex); 802 break; 803 } 804 805 case CompareEq: { 806 // Fused compare & branch. 807 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 808 if (branchNodeIndex != NoNode) { 809 // detectPeepHoleBranch currently only permits the branch to be the very next node, 810 // so can be no intervening nodes to also reference the compare. 811 ASSERT(node.adjustedRefCount() == 1); 812 813 if (shouldSpeculateInteger(node.child1, node.child2)) 814 compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::Equal); 815 else 816 compilePeepHoleCall(node, branchNodeIndex, operationCompareEq); 817 818 use(node.child1); 819 use(node.child2); 820 m_compileIndex = branchNodeIndex; 783 break; 784 785 case CompareGreater: 786 if (compare(node, JITCompiler::GreaterThan, operationCompareGreater)) 821 787 return; 822 } 823 824 SpeculateIntegerOperand op1(this, node.child1); 825 SpeculateIntegerOperand op2(this, node.child2); 826 GPRTemporary result(this, op1, op2); 827 828 m_jit.compare32(JITCompiler::Equal, op1.gpr(), op2.gpr(), result.gpr()); 829 830 // If we add a DataFormatBool, we should use it here. 831 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 832 jsValueResult(result.gpr(), m_compileIndex); 833 break; 834 } 788 break; 789 790 case CompareGreaterEq: 791 if (compare(node, JITCompiler::GreaterThanOrEqual, operationCompareGreaterEq)) 792 return; 793 break; 794 795 case CompareEq: 796 if (compare(node, JITCompiler::Equal, operationCompareEq)) 797 return; 798 break; 835 799 836 800 case CompareStrictEq: { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r90065 r90371 185 185 } 186 186 187 bool compare(Node&, MacroAssembler::RelationalCondition, Z_DFGOperation_EJJ); 187 188 void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition); 188 189 void compilePeepHoleCall(Node&, NodeIndex branchNodeIndex, Z_DFGOperation_EJJ); -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r89973 r90371 1797 1797 NEXT_INSTRUCTION(); 1798 1798 } 1799 DEFINE_OPCODE(op_greater) { 1800 /* greater dst(r) src1(r) src2(r) 1801 1802 Checks whether register src1 is greater than register src2, as 1803 with the ECMAScript '>' operator, and puts the result as 1804 a boolean in register dst. 1805 */ 1806 int dst = vPC[1].u.operand; 1807 JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1808 JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1809 JSValue result = jsBoolean(jsLess(callFrame, src2, src1)); // FIXME: Bug#63880 1810 CHECK_FOR_EXCEPTION(); 1811 callFrame->uncheckedR(dst) = result; 1812 1813 vPC += OPCODE_LENGTH(op_greater); 1814 NEXT_INSTRUCTION(); 1815 } 1816 DEFINE_OPCODE(op_greatereq) { 1817 /* greatereq dst(r) src1(r) src2(r) 1818 1819 Checks whether register src1 is greater than or equal to 1820 register src2, as with the ECMAScript '>=' operator, and 1821 puts the result as a boolean in register dst. 1822 */ 1823 int dst = vPC[1].u.operand; 1824 JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1825 JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1826 JSValue result = jsBoolean(jsLessEq(callFrame, src2, src1)); // FIXME: Bug#63880 1827 CHECK_FOR_EXCEPTION(); 1828 callFrame->uncheckedR(dst) = result; 1829 1830 vPC += OPCODE_LENGTH(op_greatereq); 1831 NEXT_INSTRUCTION(); 1832 } 1799 1833 DEFINE_OPCODE(op_pre_inc) { 1800 1834 /* pre_inc srcDst(r) … … 3694 3728 NEXT_INSTRUCTION(); 3695 3729 } 3696 DEFINE_OPCODE(op_ jnless) {3697 /* jnlesssrc1(r) src2(r) target(offset)3698 3699 Checks whether register src1 is lessthan register src2, as3700 with the ECMAScript ' <' operator, and then jumps to offset3730 DEFINE_OPCODE(op_loop_if_greater) { 3731 /* loop_if_greater src1(r) src2(r) target(offset) 3732 3733 Checks whether register src1 is greater than register src2, as 3734 with the ECMAScript '>' operator, and then jumps to offset 3701 3735 target from the current instruction, if and only if the 3702 result of the comparison is false. 3703 */ 3736 result of the comparison is true. 3737 3738 Additionally this loop instruction may terminate JS execution is 3739 the JS timeout is reached. 3740 */ 3704 3741 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3705 3742 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3706 3743 int target = vPC[3].u.operand; 3707 3708 bool result = jsLess(callFrame, src 1, src2);3744 3745 bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880 3709 3746 CHECK_FOR_EXCEPTION(); 3710 3747 3711 if ( !result) {3748 if (result) { 3712 3749 vPC += target; 3750 CHECK_FOR_TIMEOUT(); 3713 3751 NEXT_INSTRUCTION(); 3714 3752 } 3715 3716 vPC += OPCODE_LENGTH(op_jnless); 3753 3754 vPC += OPCODE_LENGTH(op_loop_if_greater); 3755 NEXT_INSTRUCTION(); 3756 } 3757 DEFINE_OPCODE(op_loop_if_greatereq) { 3758 /* loop_if_greatereq src1(r) src2(r) target(offset) 3759 3760 Checks whether register src1 is greater than or equal to register 3761 src2, as with the ECMAScript '>=' operator, and then jumps to 3762 offset target from the current instruction, if and only if the 3763 result of the comparison is true. 3764 3765 Additionally this loop instruction may terminate JS execution is 3766 the JS timeout is reached. 3767 */ 3768 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3769 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3770 int target = vPC[3].u.operand; 3771 3772 bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880 3773 CHECK_FOR_EXCEPTION(); 3774 3775 if (result) { 3776 vPC += target; 3777 CHECK_FOR_TIMEOUT(); 3778 NEXT_INSTRUCTION(); 3779 } 3780 3781 vPC += OPCODE_LENGTH(op_loop_if_greatereq); 3717 3782 NEXT_INSTRUCTION(); 3718 3783 } … … 3738 3803 3739 3804 vPC += OPCODE_LENGTH(op_jless); 3740 NEXT_INSTRUCTION();3741 }3742 DEFINE_OPCODE(op_jnlesseq) {3743 /* jnlesseq src1(r) src2(r) target(offset)3744 3745 Checks whether register src1 is less than or equal to3746 register src2, as with the ECMAScript '<=' operator,3747 and then jumps to offset target from the current instruction,3748 if and only if theresult of the comparison is false.3749 */3750 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();3751 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();3752 int target = vPC[3].u.operand;3753 3754 bool result = jsLessEq(callFrame, src1, src2);3755 CHECK_FOR_EXCEPTION();3756 3757 if (!result) {3758 vPC += target;3759 NEXT_INSTRUCTION();3760 }3761 3762 vPC += OPCODE_LENGTH(op_jnlesseq);3763 3805 NEXT_INSTRUCTION(); 3764 3806 } … … 3784 3826 3785 3827 vPC += OPCODE_LENGTH(op_jlesseq); 3828 NEXT_INSTRUCTION(); 3829 } 3830 DEFINE_OPCODE(op_jgreater) { 3831 /* jgreater src1(r) src2(r) target(offset) 3832 3833 Checks whether register src1 is greater than register src2, as 3834 with the ECMAScript '>' operator, and then jumps to offset 3835 target from the current instruction, if and only if the 3836 result of the comparison is true. 3837 */ 3838 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3839 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3840 int target = vPC[3].u.operand; 3841 3842 bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880 3843 CHECK_FOR_EXCEPTION(); 3844 3845 if (result) { 3846 vPC += target; 3847 NEXT_INSTRUCTION(); 3848 } 3849 3850 vPC += OPCODE_LENGTH(op_jgreater); 3851 NEXT_INSTRUCTION(); 3852 } 3853 DEFINE_OPCODE(op_jgreatereq) { 3854 /* jgreatereq src1(r) src2(r) target(offset) 3855 3856 Checks whether register src1 is greater than or equal to 3857 register src2, as with the ECMAScript '>=' operator, 3858 and then jumps to offset target from the current instruction, 3859 if and only if the result of the comparison is true. 3860 */ 3861 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3862 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3863 int target = vPC[3].u.operand; 3864 3865 bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880 3866 CHECK_FOR_EXCEPTION(); 3867 3868 if (result) { 3869 vPC += target; 3870 NEXT_INSTRUCTION(); 3871 } 3872 3873 vPC += OPCODE_LENGTH(op_jgreatereq); 3874 NEXT_INSTRUCTION(); 3875 } 3876 DEFINE_OPCODE(op_jnless) { 3877 /* jnless src1(r) src2(r) target(offset) 3878 3879 Checks whether register src1 is less than register src2, as 3880 with the ECMAScript '<' operator, and then jumps to offset 3881 target from the current instruction, if and only if the 3882 result of the comparison is false. 3883 */ 3884 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3885 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3886 int target = vPC[3].u.operand; 3887 3888 bool result = jsLess(callFrame, src1, src2); 3889 CHECK_FOR_EXCEPTION(); 3890 3891 if (!result) { 3892 vPC += target; 3893 NEXT_INSTRUCTION(); 3894 } 3895 3896 vPC += OPCODE_LENGTH(op_jnless); 3897 NEXT_INSTRUCTION(); 3898 } 3899 DEFINE_OPCODE(op_jnlesseq) { 3900 /* jnlesseq src1(r) src2(r) target(offset) 3901 3902 Checks whether register src1 is less than or equal to 3903 register src2, as with the ECMAScript '<=' operator, 3904 and then jumps to offset target from the current instruction, 3905 if and only if theresult of the comparison is false. 3906 */ 3907 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3908 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3909 int target = vPC[3].u.operand; 3910 3911 bool result = jsLessEq(callFrame, src1, src2); 3912 CHECK_FOR_EXCEPTION(); 3913 3914 if (!result) { 3915 vPC += target; 3916 NEXT_INSTRUCTION(); 3917 } 3918 3919 vPC += OPCODE_LENGTH(op_jnlesseq); 3920 NEXT_INSTRUCTION(); 3921 } 3922 DEFINE_OPCODE(op_jngreater) { 3923 /* jngreater src1(r) src2(r) target(offset) 3924 3925 Checks whether register src1 is greater than register src2, as 3926 with the ECMAScript '>' operator, and then jumps to offset 3927 target from the current instruction, if and only if the 3928 result of the comparison is false. 3929 */ 3930 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3931 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3932 int target = vPC[3].u.operand; 3933 3934 bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880 3935 CHECK_FOR_EXCEPTION(); 3936 3937 if (!result) { 3938 vPC += target; 3939 NEXT_INSTRUCTION(); 3940 } 3941 3942 vPC += OPCODE_LENGTH(op_jngreater); 3943 NEXT_INSTRUCTION(); 3944 } 3945 DEFINE_OPCODE(op_jngreatereq) { 3946 /* jngreatereq src1(r) src2(r) target(offset) 3947 3948 Checks whether register src1 is greater than or equal to 3949 register src2, as with the ECMAScript '>=' operator, 3950 and then jumps to offset target from the current instruction, 3951 if and only if theresult of the comparison is false. 3952 */ 3953 JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3954 JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3955 int target = vPC[3].u.operand; 3956 3957 bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880 3958 CHECK_FOR_EXCEPTION(); 3959 3960 if (!result) { 3961 vPC += target; 3962 NEXT_INSTRUCTION(); 3963 } 3964 3965 vPC += OPCODE_LENGTH(op_jngreatereq); 3786 3966 NEXT_INSTRUCTION(); 3787 3967 } -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r89885 r90371 199 199 DEFINE_BINARY_OP(op_less) 200 200 DEFINE_BINARY_OP(op_lesseq) 201 DEFINE_BINARY_OP(op_greater) 202 DEFINE_BINARY_OP(op_greatereq) 201 203 DEFINE_UNARY_OP(op_is_boolean) 202 204 DEFINE_UNARY_OP(op_is_function) … … 250 252 DEFINE_OP(op_jneq_null) 251 253 DEFINE_OP(op_jneq_ptr) 252 DEFINE_OP(op_jnless)253 254 DEFINE_OP(op_jless) 254 255 DEFINE_OP(op_jlesseq) 256 DEFINE_OP(op_jgreater) 257 DEFINE_OP(op_jgreatereq) 258 DEFINE_OP(op_jnless) 255 259 DEFINE_OP(op_jnlesseq) 260 DEFINE_OP(op_jngreater) 261 DEFINE_OP(op_jngreatereq) 256 262 DEFINE_OP(op_jsr) 257 263 DEFINE_OP(op_jtrue) … … 260 266 DEFINE_OP(op_loop_if_less) 261 267 DEFINE_OP(op_loop_if_lesseq) 268 DEFINE_OP(op_loop_if_greater) 269 DEFINE_OP(op_loop_if_greatereq) 262 270 DEFINE_OP(op_loop_if_true) 263 271 DEFINE_OP(op_loop_if_false) … … 406 414 DEFINE_SLOWCASE_OP(op_instanceof) 407 415 DEFINE_SLOWCASE_OP(op_jfalse) 408 DEFINE_SLOWCASE_OP(op_jnless)409 416 DEFINE_SLOWCASE_OP(op_jless) 410 417 DEFINE_SLOWCASE_OP(op_jlesseq) 418 DEFINE_SLOWCASE_OP(op_jgreater) 419 DEFINE_SLOWCASE_OP(op_jgreatereq) 420 DEFINE_SLOWCASE_OP(op_jnless) 411 421 DEFINE_SLOWCASE_OP(op_jnlesseq) 422 DEFINE_SLOWCASE_OP(op_jngreater) 423 DEFINE_SLOWCASE_OP(op_jngreatereq) 412 424 DEFINE_SLOWCASE_OP(op_jtrue) 413 425 DEFINE_SLOWCASE_OP(op_load_varargs) 414 426 DEFINE_SLOWCASE_OP(op_loop_if_less) 415 427 DEFINE_SLOWCASE_OP(op_loop_if_lesseq) 428 DEFINE_SLOWCASE_OP(op_loop_if_greater) 429 DEFINE_SLOWCASE_OP(op_loop_if_greatereq) 416 430 DEFINE_SLOWCASE_OP(op_loop_if_true) 417 431 DEFINE_SLOWCASE_OP(op_loop_if_false) -
trunk/Source/JavaScriptCore/jit/JIT.h
r90352 r90371 764 764 void emit_op_jneq_null(Instruction*); 765 765 void emit_op_jneq_ptr(Instruction*); 766 void emit_op_jnless(Instruction*);767 766 void emit_op_jless(Instruction*); 768 767 void emit_op_jlesseq(Instruction*); 768 void emit_op_jgreater(Instruction*); 769 void emit_op_jgreatereq(Instruction*); 770 void emit_op_jnless(Instruction*); 769 771 void emit_op_jnlesseq(Instruction*); 772 void emit_op_jngreater(Instruction*); 773 void emit_op_jngreatereq(Instruction*); 770 774 void emit_op_jsr(Instruction*); 771 775 void emit_op_jtrue(Instruction*); … … 774 778 void emit_op_loop_if_less(Instruction*); 775 779 void emit_op_loop_if_lesseq(Instruction*); 780 void emit_op_loop_if_greater(Instruction*); 781 void emit_op_loop_if_greatereq(Instruction*); 776 782 void emit_op_loop_if_true(Instruction*); 777 783 void emit_op_loop_if_false(Instruction*); … … 860 866 void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); 861 867 void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); 862 void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);863 868 void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&); 864 869 void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); 870 void emitSlow_op_jgreater(Instruction*, Vector<SlowCaseEntry>::iterator&); 871 void emitSlow_op_jgreatereq(Instruction*, Vector<SlowCaseEntry>::iterator&); 872 void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); 865 873 void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); 874 void emitSlow_op_jngreater(Instruction*, Vector<SlowCaseEntry>::iterator&); 875 void emitSlow_op_jngreatereq(Instruction*, Vector<SlowCaseEntry>::iterator&); 866 876 void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); 867 877 void emitSlow_op_load_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); 868 878 void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&); 869 879 void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); 880 void emitSlow_op_loop_if_greater(Instruction*, Vector<SlowCaseEntry>::iterator&); 881 void emitSlow_op_loop_if_greatereq(Instruction*, Vector<SlowCaseEntry>::iterator&); 870 882 void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&); 871 883 void emitSlow_op_loop_if_false(Instruction*, Vector<SlowCaseEntry>::iterator&); … … 1055 1067 } 1056 1068 1069 inline void JIT::emit_op_loop_if_greater(Instruction* currentInstruction) 1070 { 1071 emitTimeoutCheck(); 1072 emit_op_jgreater(currentInstruction); 1073 } 1074 1075 inline void JIT::emitSlow_op_loop_if_greater(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1076 { 1077 emitSlow_op_jgreater(currentInstruction, iter); 1078 } 1079 1080 inline void JIT::emit_op_loop_if_greatereq(Instruction* currentInstruction) 1081 { 1082 emitTimeoutCheck(); 1083 emit_op_jgreatereq(currentInstruction); 1084 } 1085 1086 inline void JIT::emitSlow_op_loop_if_greatereq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1087 { 1088 emitSlow_op_jgreatereq(currentInstruction, iter); 1089 } 1090 1057 1091 } // namespace JSC 1058 1092 -
trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp
r90352 r90371 65 65 } 66 66 67 void JIT::emit_op_jgreater(Instruction* currentInstruction) 68 { 69 unsigned op1 = currentInstruction[1].u.operand; 70 unsigned op2 = currentInstruction[2].u.operand; 71 unsigned target = currentInstruction[3].u.operand; 72 73 emit_compareAndJump(op_jgreater, op1, op2, target, GreaterThan); 74 } 75 76 void JIT::emit_op_jgreatereq(Instruction* currentInstruction) 77 { 78 unsigned op1 = currentInstruction[1].u.operand; 79 unsigned op2 = currentInstruction[2].u.operand; 80 unsigned target = currentInstruction[3].u.operand; 81 82 emit_compareAndJump(op_jgreatereq, op1, op2, target, GreaterThanOrEqual); 83 } 84 67 85 void JIT::emit_op_jnless(Instruction* currentInstruction) 68 86 { … … 83 101 } 84 102 103 void JIT::emit_op_jngreater(Instruction* currentInstruction) 104 { 105 unsigned op1 = currentInstruction[1].u.operand; 106 unsigned op2 = currentInstruction[2].u.operand; 107 unsigned target = currentInstruction[3].u.operand; 108 109 emit_compareAndJump(op_jngreater, op1, op2, target, LessThanOrEqual); 110 } 111 112 void JIT::emit_op_jngreatereq(Instruction* currentInstruction) 113 { 114 unsigned op1 = currentInstruction[1].u.operand; 115 unsigned op2 = currentInstruction[2].u.operand; 116 unsigned target = currentInstruction[3].u.operand; 117 118 emit_compareAndJump(op_jngreatereq, op1, op2, target, LessThan); 119 } 120 85 121 void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 86 122 { … … 101 137 } 102 138 139 void JIT::emitSlow_op_jgreater(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 140 { 141 unsigned op1 = currentInstruction[1].u.operand; 142 unsigned op2 = currentInstruction[2].u.operand; 143 unsigned target = currentInstruction[3].u.operand; 144 145 emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThan, cti_op_jgreater, false, iter); 146 } 147 148 void JIT::emitSlow_op_jgreatereq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 149 { 150 unsigned op1 = currentInstruction[1].u.operand; 151 unsigned op2 = currentInstruction[2].u.operand; 152 unsigned target = currentInstruction[3].u.operand; 153 154 emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThanOrEqual, cti_op_jgreatereq, false, iter); 155 } 156 103 157 void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 104 158 { … … 117 171 118 172 emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThanOrUnordered, cti_op_jlesseq, true, iter); 173 } 174 175 void JIT::emitSlow_op_jngreater(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 176 { 177 unsigned op1 = currentInstruction[1].u.operand; 178 unsigned op2 = currentInstruction[2].u.operand; 179 unsigned target = currentInstruction[3].u.operand; 180 181 emit_compareAndJumpSlow(op1, op2, target, DoubleLessThanOrEqualOrUnordered, cti_op_jgreater, true, iter); 182 } 183 184 void JIT::emitSlow_op_jngreatereq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 185 { 186 unsigned op1 = currentInstruction[1].u.operand; 187 unsigned op2 = currentInstruction[2].u.operand; 188 unsigned target = currentInstruction[3].u.operand; 189 190 emit_compareAndJumpSlow(op1, op2, target, DoubleLessThanOrUnordered, cti_op_jgreatereq, true, iter); 119 191 } 120 192 … … 362 434 void JIT::emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition condition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator& iter) 363 435 { 436 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jlesseq), OPCODE_LENGTH_op_jlesseq_equals_op_jless); 437 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jnless), OPCODE_LENGTH_op_jnless_equals_op_jless); 438 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jnlesseq), OPCODE_LENGTH_op_jnlesseq_equals_op_jless); 439 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jgreater), OPCODE_LENGTH_op_jgreater_equals_op_jless); 440 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jgreatereq), OPCODE_LENGTH_op_jgreatereq_equals_op_jless); 441 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jngreater), OPCODE_LENGTH_op_jngreater_equals_op_jless); 442 COMPILE_ASSERT(OPCODE_LENGTH(op_jless) == OPCODE_LENGTH(op_jngreatereq), OPCODE_LENGTH_op_jngreatereq_equals_op_jless); 443 364 444 // We generate inline code for the following cases in the slow path: 365 445 // - floating-point number to constant int immediate … … 394 474 emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target); 395 475 396 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_j nless));476 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jless)); 397 477 398 478 fail1.link(this); … … 420 500 emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target); 421 501 422 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_j nless));502 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jless)); 423 503 424 504 fail1.link(this); … … 430 510 stubCall.call(); 431 511 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 432 433 512 } else { 434 513 linkSlowCase(iter); … … 445 524 emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target); 446 525 447 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_j nless));526 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jless)); 448 527 449 528 fail1.link(this); -
trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
r90352 r90371 865 865 emitStoreDouble(dst, fpRegT1); 866 866 break; 867 case op_jless: 868 emitLoadDouble(op1, fpRegT2); 869 addJump(branchDouble(DoubleLessThan, fpRegT2, fpRegT0), dst); 870 break; 871 case op_jlesseq: 872 emitLoadDouble(op1, fpRegT2); 873 addJump(branchDouble(DoubleLessThanOrEqual, fpRegT2, fpRegT0), dst); 874 break; 875 case op_jgreater: 876 emitLoadDouble(op1, fpRegT2); 877 addJump(branchDouble(DoubleGreaterThan, fpRegT2, fpRegT0), dst); 878 break; 879 case op_jgreatereq: 880 emitLoadDouble(op1, fpRegT2); 881 addJump(branchDouble(DoubleGreaterThanOrEqual, fpRegT2, fpRegT0), dst); 882 break; 867 883 case op_jnless: 868 884 emitLoadDouble(op1, fpRegT2); 869 885 addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst); 870 886 break; 871 case op_jless:872 emitLoadDouble(op1, fpRegT2);873 addJump(branchDouble(DoubleLessThan, fpRegT2, fpRegT0), dst);874 break;875 case op_jlesseq:876 emitLoadDouble(op1, fpRegT2);877 addJump(branchDouble(DoubleLessThanOrEqual, fpRegT2, fpRegT0), dst);878 break;879 887 case op_jnlesseq: 880 888 emitLoadDouble(op1, fpRegT2); 881 889 addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT0, fpRegT2), dst); 890 break; 891 case op_jngreater: 892 emitLoadDouble(op1, fpRegT2); 893 addJump(branchDouble(DoubleGreaterThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst); 894 break; 895 case op_jngreatereq: 896 emitLoadDouble(op1, fpRegT2); 897 addJump(branchDouble(DoubleGreaterThanOrUnordered, fpRegT0, fpRegT2), dst); 882 898 break; 883 899 default: … … 926 942 emitStoreDouble(dst, fpRegT0); 927 943 break; 944 case op_jless: 945 emitLoadDouble(op2, fpRegT1); 946 addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), dst); 947 break; 948 case op_jlesseq: 949 emitLoadDouble(op2, fpRegT1); 950 addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT1), dst); 951 break; 952 case op_jgreater: 953 emitLoadDouble(op2, fpRegT1); 954 addJump(branchDouble(DoubleGreaterThan, fpRegT0, fpRegT1), dst); 955 break; 956 case op_jgreatereq: 957 emitLoadDouble(op2, fpRegT1); 958 addJump(branchDouble(DoubleGreaterThanOrEqual, fpRegT0, fpRegT1), dst); 959 break; 928 960 case op_jnless: 929 961 emitLoadDouble(op2, fpRegT1); 930 962 addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst); 931 963 break; 932 case op_jless:933 emitLoadDouble(op2, fpRegT1);934 addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), dst);935 break;936 964 case op_jnlesseq: 937 965 emitLoadDouble(op2, fpRegT1); 938 966 addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), dst); 939 967 break; 940 case op_j lesseq:968 case op_jngreater: 941 969 emitLoadDouble(op2, fpRegT1); 942 addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT1), dst); 970 addJump(branchDouble(DoubleGreaterThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst); 971 break; 972 case op_jngreatereq: 973 emitLoadDouble(op2, fpRegT1); 974 addJump(branchDouble(DoubleGreaterThanOrUnordered, fpRegT1, fpRegT0), dst); 943 975 break; 944 976 default: -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r90352 r90371 2537 2537 } 2538 2538 2539 DEFINE_STUB_FUNCTION(EncodedJSValue, op_less) 2540 { 2541 STUB_INIT_STACK_FRAME(stackFrame); 2542 2543 CallFrame* callFrame = stackFrame.callFrame; 2544 JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue())); 2545 CHECK_FOR_EXCEPTION_AT_END(); 2546 return JSValue::encode(result); 2547 } 2548 2539 2549 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq) 2540 2550 { … … 2543 2553 CallFrame* callFrame = stackFrame.callFrame; 2544 2554 JSValue result = jsBoolean(jsLessEq(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue())); 2555 CHECK_FOR_EXCEPTION_AT_END(); 2556 return JSValue::encode(result); 2557 } 2558 2559 DEFINE_STUB_FUNCTION(EncodedJSValue, op_greater) 2560 { 2561 STUB_INIT_STACK_FRAME(stackFrame); 2562 2563 CallFrame* callFrame = stackFrame.callFrame; 2564 JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue())); // FIXME: Bug#63880 2565 CHECK_FOR_EXCEPTION_AT_END(); 2566 return JSValue::encode(result); 2567 } 2568 2569 DEFINE_STUB_FUNCTION(EncodedJSValue, op_greatereq) 2570 { 2571 STUB_INIT_STACK_FRAME(stackFrame); 2572 2573 CallFrame* callFrame = stackFrame.callFrame; 2574 JSValue result = jsBoolean(jsLessEq(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue())); // FIXME: Bug#63880 2545 2575 CHECK_FOR_EXCEPTION_AT_END(); 2546 2576 return JSValue::encode(result); … … 2808 2838 } 2809 2839 2840 DEFINE_STUB_FUNCTION(int, op_jgreater) 2841 { 2842 STUB_INIT_STACK_FRAME(stackFrame); 2843 2844 JSValue src1 = stackFrame.args[0].jsValue(); 2845 JSValue src2 = stackFrame.args[1].jsValue(); 2846 CallFrame* callFrame = stackFrame.callFrame; 2847 2848 bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880 2849 CHECK_FOR_EXCEPTION_AT_END(); 2850 return result; 2851 } 2852 2853 DEFINE_STUB_FUNCTION(int, op_jgreatereq) 2854 { 2855 STUB_INIT_STACK_FRAME(stackFrame); 2856 2857 JSValue src1 = stackFrame.args[0].jsValue(); 2858 JSValue src2 = stackFrame.args[1].jsValue(); 2859 CallFrame* callFrame = stackFrame.callFrame; 2860 2861 bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880 2862 CHECK_FOR_EXCEPTION_AT_END(); 2863 return result; 2864 } 2865 2810 2866 DEFINE_STUB_FUNCTION(EncodedJSValue, op_not) 2811 2867 { … … 3091 3147 } 3092 3148 3093 DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)3094 {3095 STUB_INIT_STACK_FRAME(stackFrame);3096 3097 CallFrame* callFrame = stackFrame.callFrame;3098 JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));3099 CHECK_FOR_EXCEPTION_AT_END();3100 return JSValue::encode(result);3101 }3102 3103 3149 DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec) 3104 3150 { -
trunk/Source/JavaScriptCore/jit/JITStubs.h
r90352 r90371 353 353 EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION); 354 354 EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION); 355 EncodedJSValue JIT_STUB cti_op_greater(STUB_ARGS_DECLARATION); 356 EncodedJSValue JIT_STUB cti_op_greatereq(STUB_ARGS_DECLARATION); 355 357 EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION); 356 358 EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION); … … 395 397 int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION); 396 398 int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION); 399 int JIT_STUB cti_op_jgreater(STUB_ARGS_DECLARATION); 400 int JIT_STUB cti_op_jgreatereq(STUB_ARGS_DECLARATION); 397 401 int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION); 398 402 int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION); -
trunk/Source/JavaScriptCore/parser/NodeConstructors.h
r61878 r90371 450 450 } 451 451 452 inline ReverseBinaryOpNode::ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)453 : BinaryOpNode(globalData, expr1, expr2, opcodeID, rightHasAssignments)454 {455 }456 457 inline ReverseBinaryOpNode::ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)458 : BinaryOpNode(globalData, type, expr1, expr2, opcodeID, rightHasAssignments)459 {460 }461 462 452 inline MultNode::MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 463 453 : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, op_mul, rightHasAssignments) … … 507 497 508 498 inline GreaterNode::GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 509 : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_less, rightHasAssignments)499 : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_greater, rightHasAssignments) 510 500 { 511 501 } … … 517 507 518 508 inline GreaterEqNode::GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 519 : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_lesseq, rightHasAssignments)509 : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_greatereq, rightHasAssignments) 520 510 { 521 511 } -
trunk/Source/JavaScriptCore/parser/Nodes.h
r76248 r90371 830 830 }; 831 831 832 class ReverseBinaryOpNode : public BinaryOpNode {833 public:834 ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);835 ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);836 837 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);838 };839 840 832 class MultNode : public BinaryOpNode { 841 833 public: … … 887 879 }; 888 880 889 class GreaterNode : public ReverseBinaryOpNode {881 class GreaterNode : public BinaryOpNode { 890 882 public: 891 883 GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); … … 897 889 }; 898 890 899 class GreaterEqNode : public ReverseBinaryOpNode {891 class GreaterEqNode : public BinaryOpNode { 900 892 public: 901 893 GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
Note: See TracChangeset
for help on using the changeset viewer.