Changeset 209653 in webkit for trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
- Timestamp:
- Dec 9, 2016, 11:32:38 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r209638 r209653 81 81 } 82 82 83 GPRReg SpeculativeJIT::fillJSValue(Edge edge )83 GPRReg SpeculativeJIT::fillJSValue(Edge edge, GPRReg gprToUse) 84 84 { 85 85 VirtualRegister virtualRegister = edge->virtualRegister(); … … 88 88 switch (info.registerFormat()) { 89 89 case DataFormatNone: { 90 GPRReg gpr = allocate( );90 GPRReg gpr = allocate(gprToUse); 91 91 92 92 if (edge->hasConstant()) { … … 121 121 // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInt32, not DataFormatJSInt32. 122 122 if (m_gprs.isLocked(gpr)) { 123 GPRReg result = allocate(); 123 GPRReg result = allocate(gprToUse); 124 m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr, result); 125 return result; 126 } 127 if (gprToUse != InvalidGPRReg && gpr != gprToUse) { 128 GPRReg result = allocate(gprToUse); 124 129 m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr, result); 125 130 return result; … … 139 144 case DataFormatJSBoolean: { 140 145 GPRReg gpr = info.gpr(); 146 if (gprToUse != InvalidGPRReg && gpr != gprToUse) { 147 GPRReg result = allocate(gprToUse); 148 m_jit.move(gpr, result); 149 return result; 150 } 141 151 m_gprs.lock(gpr); 142 152 return gpr; … … 633 643 { 634 644 CallLinkInfo::CallType callType; 645 ArgumentsLocation argumentsLocation = StackArgs; 635 646 bool isVarargs = false; 636 647 bool isForwardVarargs = false; … … 715 726 GPRReg calleeGPR = InvalidGPRReg; 716 727 CallFrameShuffleData shuffleData; 717 728 std::optional<JSValueOperand> tailCallee; 729 std::optional<GPRTemporary> calleeGPRTemporary; 730 731 incrementCounter(&m_jit, VM::DFGCaller); 732 718 733 ExecutableBase* executable = nullptr; 719 734 FunctionExecutable* functionExecutable = nullptr; … … 734 749 unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal; 735 750 751 incrementCounter(&m_jit, VM::CallVarargs); 736 752 if (isForwardVarargs) { 737 753 flushRegisters(); … … 842 858 843 859 if (isTail) { 860 incrementCounter(&m_jit, VM::TailCall); 844 861 Edge calleeEdge = m_jit.graph().child(node, 0); 845 JSValueOperand callee(this, calleeEdge); 846 calleeGPR = callee.gpr(); 862 // We can't get the a specific register for the callee, since that will just move 863 // from any current register. When we silent fill in the slow path we'll fill 864 // the original register and won't have the callee in the right register. 865 // Therefore we allocate a temp register for the callee and move ourselves. 866 tailCallee.emplace(this, calleeEdge); 867 GPRReg tailCalleeGPR = tailCallee->gpr(); 868 calleeGPR = argumentRegisterForCallee(); 869 if (tailCalleeGPR != calleeGPR) 870 calleeGPRTemporary = GPRTemporary(this, calleeGPR); 847 871 if (!isDirect) 848 callee.use(); 849 872 tailCallee->use(); 873 874 argumentsLocation = argumentsLocationFor(numAllocatedArgs); 875 shuffleData.argumentsInRegisters = argumentsLocation != StackArgs; 850 876 shuffleData.tagTypeNumber = GPRInfo::tagTypeNumberRegister; 851 877 shuffleData.numLocals = m_jit.graph().frameRegisterCount(); 852 shuffleData.callee = ValueRecovery::inGPR( calleeGPR, DataFormatJS);878 shuffleData.callee = ValueRecovery::inGPR(tailCalleeGPR, DataFormatJS); 853 879 shuffleData.args.resize(numAllocatedArgs); 854 880 … … 865 891 866 892 shuffleData.setupCalleeSaveRegisters(m_jit.codeBlock()); 867 } else { 893 } else if (node->op() == CallEval) { 894 // CallEval is handled with the arguments in the stack 868 895 m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), JITCompiler::calleeFramePayloadSlot(CallFrameSlot::argumentCount)); 869 896 … … 879 906 for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i) 880 907 m_jit.storeTrustedValue(jsUndefined(), JITCompiler::calleeArgumentSlot(i)); 908 909 incrementCounter(&m_jit, VM::CallEval); 910 } else { 911 for (unsigned i = numPassedArgs; i-- > 0;) { 912 GPRReg platformArgGPR = argumentRegisterForFunctionArgument(i); 913 Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i]; 914 JSValueOperand arg(this, argEdge, platformArgGPR); 915 GPRReg argGPR = arg.gpr(); 916 ASSERT(argGPR == platformArgGPR || platformArgGPR == InvalidGPRReg); 917 918 // Only free the non-argument registers at this point. 919 if (platformArgGPR == InvalidGPRReg) { 920 use(argEdge); 921 m_jit.store64(argGPR, JITCompiler::calleeArgumentSlot(i)); 922 } 923 } 924 925 // Use the argument edges for arguments passed in registers. 926 for (unsigned i = numPassedArgs; i-- > 0;) { 927 GPRReg argGPR = argumentRegisterForFunctionArgument(i); 928 if (argGPR != InvalidGPRReg) { 929 Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i]; 930 use(argEdge); 931 } 932 } 933 934 GPRTemporary argCount(this, argumentRegisterForArgumentCount()); 935 GPRReg argCountGPR = argCount.gpr(); 936 m_jit.move(TrustedImm32(numPassedArgs), argCountGPR); 937 argumentsLocation = argumentsLocationFor(numAllocatedArgs); 938 939 for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i) { 940 GPRReg platformArgGPR = argumentRegisterForFunctionArgument(i); 941 942 if (platformArgGPR == InvalidGPRReg) 943 m_jit.storeTrustedValue(jsUndefined(), JITCompiler::calleeArgumentSlot(i)); 944 else { 945 GPRTemporary argumentTemp(this, platformArgGPR); 946 m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), argumentTemp.gpr()); 947 } 948 } 881 949 } 882 950 } … … 884 952 if (!isTail || isVarargs || isForwardVarargs) { 885 953 Edge calleeEdge = m_jit.graph().child(node, 0); 886 JSValueOperand callee(this, calleeEdge );954 JSValueOperand callee(this, calleeEdge, argumentRegisterForCallee()); 887 955 calleeGPR = callee.gpr(); 888 956 callee.use(); 889 m_jit.store64(calleeGPR, JITCompiler::calleeFrameSlot(CallFrameSlot::callee)); 957 if (argumentsLocation == StackArgs) 958 m_jit.store64(calleeGPR, JITCompiler::calleeFrameSlot(CallFrameSlot::callee)); 890 959 891 960 flushRegisters(); … … 914 983 915 984 CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo(); 916 callLinkInfo->setUpCall(callType, m_currentNode->origin.semantic, calleeGPR);985 callLinkInfo->setUpCall(callType, argumentsLocation, m_currentNode->origin.semantic, calleeGPR); 917 986 918 987 if (node->op() == CallEval) { … … 955 1024 RELEASE_ASSERT(node->op() == DirectTailCall); 956 1025 1026 if (calleeGPRTemporary != std::nullopt) 1027 m_jit.move(tailCallee->gpr(), calleeGPRTemporary->gpr()); 1028 957 1029 JITCompiler::PatchableJump patchableJump = m_jit.patchableJump(); 958 1030 JITCompiler::Label mainPath = m_jit.label(); 1031 1032 incrementCounter(&m_jit, VM::TailCall); 1033 incrementCounter(&m_jit, VM::DirectCall); 959 1034 960 1035 m_jit.emitStoreCallSiteIndex(callSite); … … 972 1047 silentFillAllRegisters(InvalidGPRReg); 973 1048 m_jit.exceptionCheck(); 1049 if (calleeGPRTemporary != std::nullopt) 1050 m_jit.move(tailCallee->gpr(), calleeGPRTemporary->gpr()); 974 1051 m_jit.jump().linkTo(mainPath, &m_jit); 975 1052 … … 982 1059 JITCompiler::Label mainPath = m_jit.label(); 983 1060 1061 incrementCounter(&m_jit, VM::DirectCall); 1062 984 1063 m_jit.emitStoreCallSiteIndex(callSite); 985 1064 … … 989 1068 JITCompiler::Label slowPath = m_jit.label(); 990 1069 if (isX86()) 991 m_jit.pop(JITCompiler::selectScratchGPR(calleeGPR)); 992 993 callOperation(operationLinkDirectCall, callLinkInfo, calleeGPR); 1070 m_jit.pop(GPRInfo::nonArgGPR0); 1071 1072 m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::nonArgGPR0); // Link info needs to be in nonArgGPR0 1073 JITCompiler::Call slowCall = m_jit.nearCall(); 1074 994 1075 m_jit.exceptionCheck(); 995 1076 m_jit.jump().linkTo(mainPath, &m_jit); … … 998 1079 999 1080 setResultAndResetStack(); 1000 1001 m_jit.addJSDirectCall(call, slow Path, callLinkInfo);1081 1082 m_jit.addJSDirectCall(call, slowCall, slowPath, callLinkInfo); 1002 1083 return; 1003 1084 } 1004 1085 1086 if (isTail && calleeGPRTemporary != std::nullopt) 1087 m_jit.move(tailCallee->gpr(), calleeGPRTemporary->gpr()); 1088 1005 1089 m_jit.emitStoreCallSiteIndex(callSite); 1006 1090 … … 1026 1110 if (node->op() == TailCall) { 1027 1111 CallFrameShuffler callFrameShuffler(m_jit, shuffleData); 1028 callFrameShuffler.setCalleeJSValueRegs(JSValueRegs(GPRInfo::regT0)); 1112 if (argumentsLocation == StackArgs) 1113 callFrameShuffler.setCalleeJSValueRegs(JSValueRegs(argumentRegisterForCallee())); 1029 1114 callFrameShuffler.prepareForSlowPath(); 1030 } else { 1031 m_jit.move(calleeGPR, GPRInfo::regT0); // Callee needs to be in regT0 1032 1033 if (isTail) 1034 m_jit.emitRestoreCalleeSaves(); // This needs to happen after we moved calleeGPR to regT0 1035 } 1036 1037 m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::regT2); // Link info needs to be in regT2 1115 } else if (isTail) 1116 m_jit.emitRestoreCalleeSaves(); 1117 1118 m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::nonArgGPR0); // Link info needs to be in nonArgGPR0 1038 1119 JITCompiler::Call slowCall = m_jit.nearCall(); 1039 1120 1040 1121 done.link(&m_jit); 1041 1122 1042 if (isTail) 1123 if (isTail) { 1124 tailCallee = std::nullopt; 1125 calleeGPRTemporary = std::nullopt; 1043 1126 m_jit.abortWithReason(JITDidReturnFromTailCall); 1044 else1127 } else 1045 1128 setResultAndResetStack(); 1046 1129 … … 4167 4250 } 4168 4251 4252 case GetArgumentRegister: 4253 break; 4254 4169 4255 case GetRestLength: { 4170 4256 compileGetRestLength(node);
Note:
See TracChangeset
for help on using the changeset viewer.