Changeset 48744 in webkit for trunk/JavaScriptCore
- Timestamp:
- Sep 24, 2009, 7:40:59 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r48738 r48744 1 2009-09-24 Oliver Hunt <[email protected]> 2 3 Reviewed by Gavin Barraclough. 4 5 Division is needlessly slow in 64-bit 6 https://bugs.webkit.org/show_bug.cgi?id=29723 7 8 Add codegen for op_div on x86-64 9 10 * jit/JIT.cpp: 11 (JSC::JIT::privateCompileMainPass): 12 (JSC::JIT::privateCompileSlowCases): 13 * jit/JIT.h: 14 * jit/JITArithmetic.cpp: 15 (JSC::JIT::compileBinaryArithOpSlowCase): 16 (JSC::JIT::emit_op_div): 17 (JSC::JIT::emitSlow_op_div): 18 * jit/JITInlineMethods.h: 19 (JSC::JIT::isOperandConstantImmediateDouble): 20 (JSC::JIT::addressFor): 21 (JSC::JIT::emitLoadDouble): 22 (JSC::JIT::emitLoadInt32ToDouble): 23 (JSC::JIT::emitJumpSlowCaseIfNotImmediateNumber): 24 1 25 2009-09-24 Jeremy Orlow <[email protected]> 2 26 -
trunk/JavaScriptCore/jit/JIT.cpp
r47597 r48744 196 196 switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) { 197 197 DEFINE_BINARY_OP(op_del_by_val) 198 #if !USE(JSVALUE32_64)198 #if USE(JSVALUE32) 199 199 DEFINE_BINARY_OP(op_div) 200 200 #endif … … 231 231 DEFINE_OP(op_debug) 232 232 DEFINE_OP(op_del_by_id) 233 #if USE(JSVALUE32_64)233 #if !USE(JSVALUE32) 234 234 DEFINE_OP(op_div) 235 235 #endif … … 380 380 DEFINE_SLOWCASE_OP(op_construct_verify) 381 381 DEFINE_SLOWCASE_OP(op_convert_this) 382 #if USE(JSVALUE32_64)382 #if !USE(JSVALUE32) 383 383 DEFINE_SLOWCASE_OP(op_div) 384 384 #endif -
trunk/JavaScriptCore/jit/JIT.h
r48525 r48744 380 380 enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq }; 381 381 void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type); 382 bool isOperandConstantImmediateDouble(unsigned src); 383 384 void emitLoadDouble(unsigned index, FPRegisterID value); 385 void emitLoadInt32ToDouble(unsigned index, FPRegisterID value); 386 387 Address addressFor(unsigned index, RegisterID base = callFrameRegister); 382 388 383 389 #if USE(JSVALUE32_64) 384 390 Address tagFor(unsigned index, RegisterID base = callFrameRegister); 385 391 Address payloadFor(unsigned index, RegisterID base = callFrameRegister); 386 Address addressFor(unsigned index, RegisterID base = callFrameRegister);387 392 388 393 bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant); 389 bool isOperandConstantImmediateDouble(unsigned src);390 394 391 395 void emitLoadTag(unsigned index, RegisterID tag); … … 395 399 void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); 396 400 void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2); 397 void emitLoadDouble(unsigned index, FPRegisterID value);398 void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);399 401 400 402 void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); … … 500 502 JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); 501 503 void emitJumpSlowCaseIfNotImmediateInteger(RegisterID); 504 void emitJumpSlowCaseIfNotImmediateNumber(RegisterID); 502 505 void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); 503 506 -
trunk/JavaScriptCore/jit/JITArithmetic.cpp
r47530 r48744 1979 1979 else if (opcodeID == op_sub) 1980 1980 subDouble(fpRegT2, fpRegT1); 1981 else if (opcodeID == op_mul) 1982 mulDouble(fpRegT2, fpRegT1); 1981 1983 else { 1982 ASSERT(opcodeID == op_ mul);1983 mulDouble(fpRegT2, fpRegT1);1984 ASSERT(opcodeID == op_div); 1985 divDouble(fpRegT2, fpRegT1); 1984 1986 } 1985 1987 moveDoubleToPtr(fpRegT1, regT0); … … 2081 2083 } else 2082 2084 compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types); 2085 } 2086 2087 void JIT::emit_op_div(Instruction* currentInstruction) 2088 { 2089 unsigned dst = currentInstruction[1].u.operand; 2090 unsigned op1 = currentInstruction[2].u.operand; 2091 unsigned op2 = currentInstruction[3].u.operand; 2092 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 2093 2094 if (isOperandConstantImmediateDouble(op1)) { 2095 emitGetVirtualRegister(op1, regT0); 2096 addPtr(tagTypeNumberRegister, regT0); 2097 movePtrToDouble(regT0, fpRegT0); 2098 } else if (isOperandConstantImmediateInt(op1)) { 2099 emitLoadInt32ToDouble(op1, fpRegT0); 2100 } else { 2101 emitGetVirtualRegister(op1, regT0); 2102 if (!types.first().definitelyIsNumber()) 2103 emitJumpSlowCaseIfNotImmediateNumber(regT0); 2104 Jump notInt = emitJumpIfNotImmediateInteger(regT0); 2105 convertInt32ToDouble(regT0, fpRegT0); 2106 Jump skipDoubleLoad = jump(); 2107 notInt.link(this); 2108 addPtr(tagTypeNumberRegister, regT0); 2109 movePtrToDouble(regT0, fpRegT0); 2110 skipDoubleLoad.link(this); 2111 } 2112 2113 if (isOperandConstantImmediateDouble(op2)) { 2114 emitGetVirtualRegister(op2, regT1); 2115 addPtr(tagTypeNumberRegister, regT1); 2116 movePtrToDouble(regT1, fpRegT1); 2117 } else if (isOperandConstantImmediateInt(op2)) { 2118 emitLoadInt32ToDouble(op2, fpRegT1); 2119 } else { 2120 emitGetVirtualRegister(op2, regT1); 2121 if (!types.second().definitelyIsNumber()) 2122 emitJumpSlowCaseIfNotImmediateNumber(regT1); 2123 Jump notInt = emitJumpIfNotImmediateInteger(regT1); 2124 convertInt32ToDouble(regT1, fpRegT1); 2125 Jump skipDoubleLoad = jump(); 2126 notInt.link(this); 2127 addPtr(tagTypeNumberRegister, regT1); 2128 movePtrToDouble(regT1, fpRegT1); 2129 skipDoubleLoad.link(this); 2130 } 2131 divDouble(fpRegT1, fpRegT0); 2132 2133 JumpList doubleResult; 2134 Jump end; 2135 bool attemptIntConversion = (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) && isOperandConstantImmediateInt(op2); 2136 if (attemptIntConversion) { 2137 m_assembler.cvttsd2si_rr(fpRegT0, regT0); 2138 doubleResult.append(branchTest32(Zero, regT0)); 2139 m_assembler.ucomisd_rr(fpRegT1, fpRegT0); 2140 2141 doubleResult.append(m_assembler.jne()); 2142 doubleResult.append(m_assembler.jp()); 2143 emitFastArithIntToImmNoCheck(regT0, regT0); 2144 end = jump(); 2145 } 2146 2147 // Double result. 2148 doubleResult.link(this); 2149 moveDoubleToPtr(fpRegT0, regT0); 2150 subPtr(tagTypeNumberRegister, regT0); 2151 2152 if (attemptIntConversion) 2153 end.link(this); 2154 emitPutVirtualRegister(dst, regT0); 2155 } 2156 2157 void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 2158 { 2159 unsigned result = currentInstruction[1].u.operand; 2160 unsigned op1 = currentInstruction[2].u.operand; 2161 unsigned op2 = currentInstruction[3].u.operand; 2162 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 2163 if (types.first().definitelyIsNumber() && types.second().definitelyIsNumber()) { 2164 #ifndef NDEBUG 2165 breakpoint(); 2166 #endif 2167 return; 2168 } 2169 if (!isOperandConstantImmediateDouble(op1) && !isOperandConstantImmediateInt(op1)) { 2170 if (!types.first().definitelyIsNumber()) 2171 linkSlowCase(iter); 2172 } 2173 if (!isOperandConstantImmediateDouble(op2) && !isOperandConstantImmediateInt(op2)) { 2174 if (!types.second().definitelyIsNumber()) 2175 linkSlowCase(iter); 2176 } 2177 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. 2178 JITStubCall stubCall(this, cti_op_div); 2179 stubCall.addArgument(op1, regT2); 2180 stubCall.addArgument(op2, regT2); 2181 stubCall.call(result); 2083 2182 } 2084 2183 -
trunk/JavaScriptCore/jit/JITInlineMethods.h
r48525 r48744 66 66 } 67 67 68 ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src) 69 { 70 return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble(); 71 } 72 68 73 ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src) 69 74 { … … 306 311 #endif 307 312 313 inline JIT::Address JIT::addressFor(unsigned index, RegisterID base) 314 { 315 return Address(base, (index * sizeof(Register))); 316 } 317 308 318 #if USE(JSVALUE32_64) 309 319 … … 316 326 { 317 327 return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); 318 }319 320 inline JIT::Address JIT::addressFor(unsigned index, RegisterID base)321 {322 return Address(base, (index * sizeof(Register)));323 328 } 324 329 … … 578 583 579 584 return false; 580 }581 582 ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src)583 {584 return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble();585 585 } 586 586 … … 733 733 return branchTestPtr(Zero, reg, tagTypeNumberRegister); 734 734 } 735 736 inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value) 737 { 738 if (m_codeBlock->isConstantRegisterIndex(index)) { 739 Register& inConstantPool = m_codeBlock->constantRegister(index); 740 loadDouble(&inConstantPool, value); 741 } else 742 loadDouble(addressFor(index), value); 743 } 744 745 inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value) 746 { 747 if (m_codeBlock->isConstantRegisterIndex(index)) { 748 Register& inConstantPool = m_codeBlock->constantRegister(index); 749 convertInt32ToDouble(AbsoluteAddress(&inConstantPool), value); 750 } else 751 convertInt32ToDouble(addressFor(index), value); 752 } 735 753 #endif 736 754 … … 768 786 { 769 787 addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch)); 788 } 789 790 ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg) 791 { 792 addSlowCase(emitJumpIfNotImmediateNumber(reg)); 770 793 } 771 794
Note:
See TracChangeset
for help on using the changeset viewer.