Changeset 209725 in webkit for trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
- Timestamp:
- Dec 12, 2016, 1:46:45 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r209678 r209725 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 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=165769 943 // Eliminate filling extra stack slots with undefined JSValues for register arguments. 944 // The LLInt thunks aren't smart enough to know what register arguments to spill therefore 945 // we put undefined in both the extra argument register and stack slot. 946 if (platformArgGPR != InvalidGPRReg) { 947 GPRTemporary argumentTemp(this, platformArgGPR); 948 m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), argumentTemp.gpr()); 949 } 950 m_jit.storeTrustedValue(jsUndefined(), JITCompiler::calleeArgumentSlot(i)); 951 } 881 952 } 882 953 } … … 884 955 if (!isTail || isVarargs || isForwardVarargs) { 885 956 Edge calleeEdge = m_jit.graph().child(node, 0); 886 JSValueOperand callee(this, calleeEdge );957 JSValueOperand callee(this, calleeEdge, argumentRegisterForCallee()); 887 958 calleeGPR = callee.gpr(); 888 959 callee.use(); 889 m_jit.store64(calleeGPR, JITCompiler::calleeFrameSlot(CallFrameSlot::callee)); 960 if (argumentsLocation == StackArgs) 961 m_jit.store64(calleeGPR, JITCompiler::calleeFrameSlot(CallFrameSlot::callee)); 890 962 891 963 flushRegisters(); … … 914 986 915 987 CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo(); 916 callLinkInfo->setUpCall(callType, m_currentNode->origin.semantic, calleeGPR);988 callLinkInfo->setUpCall(callType, argumentsLocation, m_currentNode->origin.semantic, calleeGPR); 917 989 918 990 if (node->op() == CallEval) { … … 955 1027 RELEASE_ASSERT(node->op() == DirectTailCall); 956 1028 1029 if (calleeGPRTemporary != std::nullopt) 1030 m_jit.move(tailCallee->gpr(), calleeGPRTemporary->gpr()); 1031 957 1032 JITCompiler::PatchableJump patchableJump = m_jit.patchableJump(); 958 1033 JITCompiler::Label mainPath = m_jit.label(); 1034 1035 incrementCounter(&m_jit, VM::TailCall); 1036 incrementCounter(&m_jit, VM::DirectCall); 959 1037 960 1038 m_jit.emitStoreCallSiteIndex(callSite); … … 972 1050 silentFillAllRegisters(InvalidGPRReg); 973 1051 m_jit.exceptionCheck(); 1052 if (calleeGPRTemporary != std::nullopt) 1053 m_jit.move(tailCallee->gpr(), calleeGPRTemporary->gpr()); 974 1054 m_jit.jump().linkTo(mainPath, &m_jit); 975 1055 … … 982 1062 JITCompiler::Label mainPath = m_jit.label(); 983 1063 1064 incrementCounter(&m_jit, VM::DirectCall); 1065 984 1066 m_jit.emitStoreCallSiteIndex(callSite); 985 1067 … … 989 1071 JITCompiler::Label slowPath = m_jit.label(); 990 1072 if (isX86()) 991 m_jit.pop(JITCompiler::selectScratchGPR(calleeGPR)); 992 993 callOperation(operationLinkDirectCall, callLinkInfo, calleeGPR); 1073 m_jit.pop(GPRInfo::nonArgGPR0); 1074 1075 m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::nonArgGPR0); // Link info needs to be in nonArgGPR0 1076 JITCompiler::Call slowCall = m_jit.nearCall(); 1077 994 1078 m_jit.exceptionCheck(); 995 1079 m_jit.jump().linkTo(mainPath, &m_jit); … … 998 1082 999 1083 setResultAndResetStack(); 1000 1001 m_jit.addJSDirectCall(call, slow Path, callLinkInfo);1084 1085 m_jit.addJSDirectCall(call, slowCall, slowPath, callLinkInfo); 1002 1086 return; 1003 1087 } 1004 1088 1089 if (isTail && calleeGPRTemporary != std::nullopt) 1090 m_jit.move(tailCallee->gpr(), calleeGPRTemporary->gpr()); 1091 1005 1092 m_jit.emitStoreCallSiteIndex(callSite); 1006 1093 … … 1026 1113 if (node->op() == TailCall) { 1027 1114 CallFrameShuffler callFrameShuffler(m_jit, shuffleData); 1028 callFrameShuffler.setCalleeJSValueRegs(JSValueRegs(GPRInfo::regT0)); 1115 if (argumentsLocation == StackArgs) 1116 callFrameShuffler.setCalleeJSValueRegs(JSValueRegs(argumentRegisterForCallee())); 1029 1117 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 1118 } else if (isTail) 1119 m_jit.emitRestoreCalleeSaves(); 1120 1121 m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::nonArgGPR0); // Link info needs to be in nonArgGPR0 1038 1122 JITCompiler::Call slowCall = m_jit.nearCall(); 1039 1123 1040 1124 done.link(&m_jit); 1041 1125 1042 if (isTail) 1126 if (isTail) { 1127 tailCallee = std::nullopt; 1128 calleeGPRTemporary = std::nullopt; 1043 1129 m_jit.abortWithReason(JITDidReturnFromTailCall); 1044 else1130 } else 1045 1131 setResultAndResetStack(); 1046 1132 … … 4167 4253 } 4168 4254 4255 case GetArgumentRegister: 4256 break; 4257 4169 4258 case GetRestLength: { 4170 4259 compileGetRestLength(node);
Note:
See TracChangeset
for help on using the changeset viewer.