Changeset 190649 in webkit
- Timestamp:
- Oct 6, 2015, 3:29:27 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/Source/JavaScriptCore/ChangeLog ¶
r190617 r190649 1 2015-10-06 Mark Lam <mark.lam@apple.com> 2 3 Factoring out op_sub baseline code generation into JITSubGenerator. 4 https://bugs.webkit.org/show_bug.cgi?id=149600 5 6 Reviewed by Geoffrey Garen. 7 8 We're going to factor out baseline code generation into snippet generators so 9 that we can later use them in the DFG and FTL to emit code for to perform the 10 JS operations where the operand types are predicted to be polymorphic. 11 We are starting in this patch with the implementation of op_sub. 12 13 What was done in this patch: 14 1. Created JITSubGenerator based on the baseline implementation of op_sub as 15 expressed in compileBinaryArithOp() and compileBinaryArithOpSlowCase(). 16 I did not attempt to do write a more optimal version of op_sub. I'll 17 leave that to a later patch. 18 19 2. Convert the 32-bit op_sub baseline implementation to use the same 20 JITSubGenerator which was based on the 64-bit implementation. The 21 pre-existing 32-bit baseline op_sub had handling for more optimization cases. 22 However, a benchmark run shows that simply going with the 64-bit version 23 (foregoing those extra optimizations) did not change the performance. 24 25 Also, previously, the 32-bit version was able to move double results directly 26 into the result location on the stack directly. By using JITSubGenerator, 27 we now always move that result into a pair of GPRs before storing it into 28 the stack location. 29 30 3. Add some needed emitters to AssemblyHelpers that play nice with JSValueRegs. 31 32 * JavaScriptCore.xcodeproj/project.pbxproj: 33 * jit/AssemblyHelpers.h: 34 (JSC::AssemblyHelpers::boxDouble): 35 (JSC::AssemblyHelpers::unboxDouble): 36 (JSC::AssemblyHelpers::boxBooleanPayload): 37 * jit/JIT.h: 38 (JSC::JIT::linkDummySlowCase): 39 * jit/JITArithmetic.cpp: 40 (JSC::JIT::compileBinaryArithOp): 41 (JSC::JIT::compileBinaryArithOpSlowCase): 42 (JSC::JIT::emitSlow_op_div): 43 (JSC::JIT::emit_op_sub): 44 (JSC::JIT::emitSlow_op_sub): 45 * jit/JITArithmetic32_64.cpp: 46 (JSC::JIT::emitBinaryDoubleOp): 47 (JSC::JIT::emit_op_sub): Deleted. 48 (JSC::JIT::emitSub32Constant): Deleted. 49 (JSC::JIT::emitSlow_op_sub): Deleted. 50 * jit/JITInlines.h: 51 (JSC::JIT::linkSlowCaseIfNotJSCell): 52 (JSC::JIT::linkAllSlowCasesForBytecodeOffset): 53 (JSC::JIT::addSlowCase): 54 (JSC::JIT::emitLoad): 55 (JSC::JIT::emitGetVirtualRegister): 56 (JSC::JIT::emitPutVirtualRegister): 57 * jit/JITSubGenerator.h: Added. 58 (JSC::JITSubGenerator::JITSubGenerator): 59 (JSC::JITSubGenerator::generateFastPath): 60 (JSC::JITSubGenerator::slowPathJumpList): 61 1 62 2015-10-06 Daniel Bates <dbates@webkit.org> 2 63 -
TabularUnified trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj ¶
r190569 r190649 3708 3708 FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapVerifier.h; sourceTree = "<group>"; }; 3709 3709 FE90BB3A1B7CF64E006B3F03 /* VMInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInlines.h; sourceTree = "<group>"; }; 3710 FE98B5B61BB9AE110073E7A6 /* JITSubGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITSubGenerator.h; sourceTree = "<group>"; }; 3710 3711 FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = "<group>"; }; 3711 3712 FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = "<group>"; }; … … 4190 4191 FEF6835C174343CC00A32E25 /* JITStubsX86_64.h */, 4191 4192 A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */, 4193 FE98B5B61BB9AE110073E7A6 /* JITSubGenerator.h */, 4192 4194 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */, 4193 4195 0F5EF91C16878F78003E5C25 /* JITThunks.h */, -
TabularUnified trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h ¶
r190606 r190649 965 965 boxDouble(fpr, regs.gpr()); 966 966 } 967 967 void unboxDouble(JSValueRegs regs, FPRReg destFPR, FPRReg) 968 { 969 unboxDouble(regs.payloadGPR(), destFPR); 970 } 971 968 972 // Here are possible arrangements of source, target, scratch: 969 973 // - source, target, scratch can all be separate registers. … … 1002 1006 { 1003 1007 boxDouble(fpr, regs.tagGPR(), regs.payloadGPR()); 1008 } 1009 void unboxDouble(JSValueRegs regs, FPRReg fpr, FPRReg scratchFPR) 1010 { 1011 unboxDouble(regs.tagGPR(), regs.payloadGPR(), fpr, scratchFPR); 1004 1012 } 1005 1013 #endif -
TabularUnified trunk/Source/JavaScriptCore/jit/JIT.h ¶
r190561 r190649 400 400 401 401 enum FinalObjectMode { MayBeFinal, KnownNotFinal }; 402 403 void emitGetVirtualRegister(int src, JSValueRegs dst); 404 void emitPutVirtualRegister(int dst, JSValueRegs src); 402 405 403 406 #if USE(JSVALUE32_64) … … 709 712 } 710 713 void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int virtualRegisterIndex); 714 void linkAllSlowCasesForBytecodeOffset(Vector<SlowCaseEntry>& slowCases, 715 Vector<SlowCaseEntry>::iterator&, unsigned bytecodeOffset); 711 716 712 717 MacroAssembler::Call appendCallWithExceptionCheck(const FunctionPtr&); -
TabularUnified trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp ¶
r190435 r190649 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 33 33 #include "JITOperations.h" 34 34 #include "JITStubs.h" 35 #include "JITSubGenerator.h" 35 36 #include "JSArray.h" 36 37 #include "JSFunction.h" … … 669 670 if (opcodeID == op_add) 670 671 addSlowCase(branchAdd32(Overflow, regT1, regT0)); 671 else if (opcodeID == op_sub)672 addSlowCase(branchSub32(Overflow, regT1, regT0));673 672 else { 674 673 ASSERT(opcodeID == op_mul); … … 722 721 Label stubFunctionCall(this); 723 722 724 JITSlowPathCall slowPathCall(this, currentInstruction, opcodeID == op_add ? slow_path_add : opcodeID == op_sub ? slow_path_sub :slow_path_mul);723 JITSlowPathCall slowPathCall(this, currentInstruction, opcodeID == op_add ? slow_path_add : slow_path_mul); 725 724 slowPathCall.call(); 726 725 Jump end = jump(); … … 768 767 if (opcodeID == op_add) 769 768 addDouble(fpRegT2, fpRegT1); 770 else if (opcodeID == op_sub)771 subDouble(fpRegT2, fpRegT1);772 769 else if (opcodeID == op_mul) 773 770 mulDouble(fpRegT2, fpRegT1); … … 962 959 } 963 960 961 #endif // USE(JSVALUE64) 962 964 963 void JIT::emit_op_sub(Instruction* currentInstruction) 965 964 { … … 969 968 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 970 969 971 compileBinaryArithOp(op_sub, result, op1, op2, types); 972 emitPutVirtualRegister(result); 970 #if USE(JSVALUE64) 971 JSValueRegs leftRegs = JSValueRegs(regT0); 972 JSValueRegs rightRegs = JSValueRegs(regT1); 973 JSValueRegs resultRegs = leftRegs; 974 GPRReg scratchGPR = InvalidGPRReg; 975 FPRReg scratchFPR = InvalidFPRReg; 976 #else 977 JSValueRegs leftRegs = JSValueRegs(regT1, regT0); 978 JSValueRegs rightRegs = JSValueRegs(regT3, regT2); 979 JSValueRegs resultRegs = leftRegs; 980 GPRReg scratchGPR = regT4; 981 FPRReg scratchFPR = fpRegT2; 982 #endif 983 984 emitGetVirtualRegister(op1, leftRegs); 985 emitGetVirtualRegister(op2, rightRegs); 986 987 JITSubGenerator gen(resultRegs, leftRegs, rightRegs, types.first(), types.second(), 988 fpRegT0, fpRegT1, scratchGPR, scratchFPR); 989 990 gen.generateFastPath(*this); 991 emitPutVirtualRegister(result, resultRegs); 992 993 addSlowCase(gen.slowPathJumpList()); 973 994 } 974 995 975 996 void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 976 997 { 977 int result = currentInstruction[1].u.operand; 978 int op1 = currentInstruction[2].u.operand; 979 int op2 = currentInstruction[3].u.operand; 980 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 981 982 compileBinaryArithOpSlowCase(currentInstruction, op_sub, iter, result, op1, op2, types, false, false); 998 linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset); 999 1000 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_sub); 1001 slowPathCall.call(); 983 1002 } 984 1003 985 1004 /* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */ 986 1005 987 #endif // USE(JSVALUE64)988 989 1006 } // namespace JSC 990 1007 -
TabularUnified trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp ¶
r190230 r190649 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 595 595 // Subtraction (-) 596 596 597 void JIT::emit_op_sub(Instruction* currentInstruction)598 {599 int dst = currentInstruction[1].u.operand;600 int op1 = currentInstruction[2].u.operand;601 int op2 = currentInstruction[3].u.operand;602 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);603 604 JumpList notInt32Op1;605 JumpList notInt32Op2;606 607 if (isOperandConstantInt(op2)) {608 emitSub32Constant(dst, op1, getConstantOperand(op2).asInt32(), types.first());609 return;610 }611 612 emitLoad2(op1, regT1, regT0, op2, regT3, regT2);613 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));614 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));615 616 // Int32 case.617 addSlowCase(branchSub32(Overflow, regT2, regT0));618 emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));619 620 if (!supportsFloatingPoint()) {621 addSlowCase(notInt32Op1);622 addSlowCase(notInt32Op2);623 return;624 }625 Jump end = jump();626 627 // Double case.628 emitBinaryDoubleOp(op_sub, dst, op1, op2, types, notInt32Op1, notInt32Op2);629 end.link(this);630 }631 632 void JIT::emitSub32Constant(int dst, int op, int32_t constant, ResultType opType)633 {634 // Int32 case.635 emitLoad(op, regT1, regT0);636 Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));637 addSlowCase(branchSub32(Overflow, regT0, Imm32(constant), regT2, regT3));638 emitStoreInt32(dst, regT2, (op == dst));639 640 // Double case.641 if (!supportsFloatingPoint()) {642 addSlowCase(notInt32);643 return;644 }645 Jump end = jump();646 647 notInt32.link(this);648 if (!opType.definitelyIsNumber())649 addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));650 move(Imm32(constant), regT2);651 convertInt32ToDouble(regT2, fpRegT0);652 emitLoadDouble(op, fpRegT1);653 subDouble(fpRegT0, fpRegT1);654 emitStoreDouble(dst, fpRegT1);655 656 end.link(this);657 }658 659 void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)660 {661 int op2 = currentInstruction[3].u.operand;662 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);663 664 if (isOperandConstantInt(op2)) {665 linkSlowCase(iter); // overflow check666 667 if (!supportsFloatingPoint() || !types.first().definitelyIsNumber())668 linkSlowCase(iter); // int32 or double check669 } else {670 linkSlowCase(iter); // overflow check671 672 if (!supportsFloatingPoint()) {673 linkSlowCase(iter); // int32 check674 linkSlowCase(iter); // int32 check675 } else {676 if (!types.first().definitelyIsNumber())677 linkSlowCase(iter); // double check678 679 if (!types.second().definitelyIsNumber()) {680 linkSlowCase(iter); // int32 check681 linkSlowCase(iter); // double check682 }683 }684 }685 686 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_sub);687 slowPathCall.call();688 }689 690 597 void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, int dst, int op1, int op2, OperandTypes types, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters, bool op2IsInRegisters) 691 598 { … … 729 636 addDouble(fpRegT2, fpRegT0); 730 637 emitStoreDouble(dst, fpRegT0); 731 break;732 case op_sub:733 emitLoadDouble(op1, fpRegT1);734 subDouble(fpRegT0, fpRegT1);735 emitStoreDouble(dst, fpRegT1);736 638 break; 737 639 case op_div: { … … 829 731 emitLoadDouble(op2, fpRegT2); 830 732 addDouble(fpRegT2, fpRegT0); 831 emitStoreDouble(dst, fpRegT0);832 break;833 case op_sub:834 emitLoadDouble(op2, fpRegT2);835 subDouble(fpRegT2, fpRegT0);836 733 emitStoreDouble(dst, fpRegT0); 837 734 break; -
TabularUnified trunk/Source/JavaScriptCore/jit/JITInlines.h ¶
r190230 r190649 770 770 } 771 771 772 ALWAYS_INLINE void JIT::linkAllSlowCasesForBytecodeOffset(Vector<SlowCaseEntry>& slowCases, Vector<SlowCaseEntry>::iterator& iter, unsigned bytecodeOffset) 773 { 774 while (iter != slowCases.end() && iter->to == bytecodeOffset) { 775 iter->from.link(this); 776 ++iter; 777 } 778 } 779 772 780 ALWAYS_INLINE void JIT::addSlowCase(Jump jump) 773 781 { … … 999 1007 } 1000 1008 1009 ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, JSValueRegs dst) 1010 { 1011 emitLoad(src, dst.tagGPR(), dst.payloadGPR()); 1012 } 1013 1014 ALWAYS_INLINE void JIT::emitPutVirtualRegister(int dst, JSValueRegs from) 1015 { 1016 emitStore(dst, from.tagGPR(), from.payloadGPR()); 1017 } 1018 1001 1019 inline void JIT::emitLoad(int index, RegisterID tag, RegisterID payload, RegisterID base) 1002 1020 { … … 1157 1175 } 1158 1176 1177 ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, JSValueRegs dst) 1178 { 1179 emitGetVirtualRegister(src, dst.payloadGPR()); 1180 } 1181 1159 1182 ALWAYS_INLINE void JIT::emitGetVirtualRegister(VirtualRegister src, RegisterID dst) 1160 1183 { … … 1186 1209 { 1187 1210 store64(from, Address(callFrameRegister, dst * sizeof(Register))); 1211 } 1212 1213 ALWAYS_INLINE void JIT::emitPutVirtualRegister(int dst, JSValueRegs from) 1214 { 1215 emitPutVirtualRegister(dst, from.payloadGPR()); 1188 1216 } 1189 1217
Note:
See TracChangeset
for help on using the changeset viewer.