| Differences between
and this patch
- Source/JavaScriptCore/dfg/DFGCommon.h -1 / +1 lines
Lines 38-44 namespace JSC { namespace DFG { Source/JavaScriptCore/dfg/DFGCommon.h_sec1
38
// We are in the middle of an experimental transition from LLVM to B3 as the backend for the FTL. We don't
38
// We are in the middle of an experimental transition from LLVM to B3 as the backend for the FTL. We don't
39
// yet know how it will turn out. For now, this flag will control whether FTL uses B3. Remember to set this
39
// yet know how it will turn out. For now, this flag will control whether FTL uses B3. Remember to set this
40
// to 0 before committing!
40
// to 0 before committing!
41
#define FTL_USES_B3 0
41
#define FTL_USES_B3 1
42
42
43
struct Node;
43
struct Node;
44
44
- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp -17 / +108 lines
Lines 205-212 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
205
#endif // FTL_USE_B3
205
#endif // FTL_USE_B3
206
206
207
        auto preOrder = m_graph.blocksInPreOrder();
207
        auto preOrder = m_graph.blocksInPreOrder();
208
        
208
209
        // If we have any CallVarargs then we need to have a spill slot for it.
209
#if !FTL_USES_B3
210
        bool hasVarargs = false;
210
        bool hasVarargs = false;
211
        size_t maxNumberOfCatchSpills = 0;
211
        size_t maxNumberOfCatchSpills = 0;
212
        for (DFG::BasicBlock* block : preOrder) {
212
        for (DFG::BasicBlock* block : preOrder) {
Lines 270-279 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
270
            }
270
            }
271
        }
271
        }
272
272
273
#if FTL_USES_B3
273
        // B3 doesn't need the varargs spill slot because we just use call arg area size as a way to
274
        UNUSED_PARAM(hasVarargs);
274
        // request spill slots.
275
        // FIXME
276
#else
277
        if (hasVarargs) {
275
        if (hasVarargs) {
278
            LValue varargsSpillSlots = m_out.alloca(
276
            LValue varargsSpillSlots = m_out.alloca(
279
                arrayType(m_out.int64, JSCallVarargs::numSpillSlotsNeeded()));
277
                arrayType(m_out.int64, JSCallVarargs::numSpillSlotsNeeded()));
Lines 284-289 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
284
                m_out.int32Zero, varargsSpillSlots);
282
                m_out.int32Zero, varargsSpillSlots);
285
        }
283
        }
286
284
285
        // B3 doesn't need the exception spill slot because we just use the 
287
        if (m_graph.m_hasExceptionHandlers && maxNumberOfCatchSpills) {
286
        if (m_graph.m_hasExceptionHandlers && maxNumberOfCatchSpills) {
288
            RegisterSet volatileRegisters = RegisterSet::volatileRegistersForJSCall();
287
            RegisterSet volatileRegisters = RegisterSet::volatileRegistersForJSCall();
289
            maxNumberOfCatchSpills = std::min(volatileRegisters.numberOfSetRegisters(), maxNumberOfCatchSpills);
288
            maxNumberOfCatchSpills = std::min(volatileRegisters.numberOfSetRegisters(), maxNumberOfCatchSpills);
Lines 296-302 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec4
296
                m_out.constInt64(m_ftlState.exceptionHandlingSpillSlotStackmapID),
295
                m_out.constInt64(m_ftlState.exceptionHandlingSpillSlotStackmapID),
297
                m_out.int32Zero, exceptionHandlingVolatileRegistersSpillSlots);
296
                m_out.int32Zero, exceptionHandlingVolatileRegistersSpillSlots);
298
        }
297
        }
299
#endif
298
#endif // !FTL_USES_B3
300
        
299
        
301
        // We should not create any alloca's after this point, since they will cease to
300
        // We should not create any alloca's after this point, since they will cease to
302
        // be mem2reg candidates.
301
        // be mem2reg candidates.
Lines 5069-5089 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec5
5069
    
5068
    
5070
    void compileCallOrConstructVarargs()
5069
    void compileCallOrConstructVarargs()
5071
    {
5070
    {
5072
#if FTL_USES_B3
5071
        Node* node = m_node;
5073
        if (verboseCompilationEnabled() || !verboseCompilationEnabled())
5074
            CRASH();
5075
#else
5076
        LValue jsCallee = lowJSValue(m_node->child1());
5072
        LValue jsCallee = lowJSValue(m_node->child1());
5077
        LValue thisArg = lowJSValue(m_node->child3());
5073
        LValue thisArg = lowJSValue(m_node->child3());
5078
        
5074
        
5079
        LValue jsArguments = nullptr;
5075
        LValue jsArguments = nullptr;
5080
        
5076
        
5081
        switch (m_node->op()) {
5077
        switch (node->op()) {
5082
        case CallVarargs:
5078
        case CallVarargs:
5083
        case TailCallVarargs:
5079
        case TailCallVarargs:
5084
        case TailCallVarargsInlinedCaller:
5080
        case TailCallVarargsInlinedCaller:
5085
        case ConstructVarargs:
5081
        case ConstructVarargs:
5086
            jsArguments = lowJSValue(m_node->child2());
5082
            jsArguments = lowJSValue(node->child2());
5087
            break;
5083
            break;
5088
        case CallForwardVarargs:
5084
        case CallForwardVarargs:
5089
        case TailCallForwardVarargs:
5085
        case TailCallForwardVarargs:
Lines 5091-5100 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec6
5091
        case ConstructForwardVarargs:
5087
        case ConstructForwardVarargs:
5092
            break;
5088
            break;
5093
        default:
5089
        default:
5094
            DFG_CRASH(m_graph, m_node, "bad node type");
5090
            DFG_CRASH(m_graph, node, "bad node type");
5095
            break;
5091
            break;
5096
        }
5092
        }
5097
        
5093
        
5094
#if FTL_USES_B3
5095
        // FIXME: Need a story for exceptions.
5096
        // https://bugs.webkit.org/show_bug.cgi?id=151686
5097
5098
        PatckpointValue* patchpoint = m_out.patchpoint(Int64);
5099
        patchpoint->append(jsCallee, ValueRep::SomeRegister);
5100
        if (jsArguments)
5101
            patchpoint->append(jsArguments, ValueRep::SomeRegister);
5102
        patchpoint->append(thisArg, ValueRep::SomeRegister);
5103
5104
        patchpoint->clobber(RegisterSet::macroScratchRegisters());
5105
        parchpoint->clobberLate(RegisterSet::volatileRegistersForJSCall());
5106
        patchpoint->resultConstraint = ValueRep::reg(GPRInfo::returnValueGPR);
5107
5108
        // This is the minimum amount of call arg area stack space that all JS->JS calls always have.
5109
        unsigned minimumJSCallAreaSize =
5110
            sizeof(CallerFrameAndPC) +
5111
            WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(EncodedJSValue));
5112
5113
        // This is the number of spill slots we will want.
5114
        unsigned spillAreaSize = 3 * sizeof(EncodedJSValue);
5115
        
5116
        CodeOrigin codeOrigin = codeOriginDescriptionOfCallSite();
5117
        State* state = &m_ftlState;
5118
        patchpoint->setGenerator(
5119
            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
5120
                AllowMacroScratchRegisterUsage allowScratch(jit);
5121
                CallSiteIndex callSiteIndex =
5122
                    state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
5123
5124
                // FIXME: We would ask the OSR exit descriptor to prepare and then we would modify
5125
                // the OSRExit data structure inside the OSRExitHandle to link it up to this call.
5126
                // Also, the exception checks JumpList should be linked to somewhere.
5127
                // https://bugs.webkit.org/show_bug.cgi?id=151686
5128
                CCallHelpers::JumpList exceptions;
5129
5130
                jit.store32(
5131
                    CCallHelpers::TrustedImm32(callSiteIndex.bits()),
5132
                    CCallHelpers::tagFor(VirtualRegister(JSStack::ArgumentCount)));
5133
5134
                CallLinkInfo* callLinkInfo = jit.codeBlock()->addCallLinkInfo();
5135
                CallVarargsData* data = node->callVarargsData();
5136
5137
                unsigned argIndex = 1;
5138
                GPRReg calleeGPR = params[argIndex++].gpr();
5139
                GPRReg argumentsGPR = InvalidGPRReg;
5140
                bool forwarding = false;
5141
                if (jsArguments)
5142
                    argumentsGPR = params[argIndex++].gpr();
5143
                else
5144
                    forwarding = true;
5145
                GPRReg thisGPR = params[argIndex++].gpr();
5146
5147
                // Get some scratch registers.
5148
                RegisterSet usedRegisters;
5149
                usedRegisters.merge(RegisterSet::stackRegisters());
5150
                usedRegisters.merge(RegisterSet::reservedHardwareRegisters());
5151
                usedRegisters.merge(RegisterSet::calleeSaveRegisters());
5152
                usedRegisters.set(calleeGPR);
5153
                if (argumentsGPR != InvalidGPRReg)
5154
                    usedRegisters.set(argumentsGPR);
5155
                usedRegisters.set(thisGPR);
5156
                ScratchRegisterAllocator allocator(usedRegisters);
5157
                GPRReg scratchGPR1 = allocator.allocateScratchGPR();
5158
                GPRReg scratchGPR2 = allocator.allocateScratchGPR();
5159
                GPRReg scratchGPR3 = allocator.allocateScratchGPR();
5160
                RELEASE_ASSERT(!allocator.numberOfReusedRegisters());
5161
5162
                auto computeUsedStack = [&] (GPRReg targetGPR, unsigned extra) {
5163
                    if (isARM64()) {
5164
                        // Have to do this the weird way because %sp on ARM64 means zero when used in
5165
                        // a subtraction.
5166
                        jit.move(CCallHelpers::stackPointerRegister, targetGPR);
5167
                        jit.negPtr(targetGPR);
5168
                        jit.addPtr(GPRInfo::callFrameRegister, targetGPR);
5169
                    } else {
5170
                        jit.move(GPRInfo::callFrameRegister, targetGPR);
5171
                        jit.subPtr(CCallHelpers::stackPointerRegister, targetGPR);
5172
                    }
5173
                    if (extra)
5174
                        jit.subPtr(CCallHelpers::TrustedImm32(extra), targetGPR);
5175
                    jit.urshiftPtr(CCallHelpers::Imm32(3), targetGPR);
5176
                };
5177
5178
                auto callWithExceptionCheck = [&] (void* callee) {
5179
                    jit.move(CCallHelpers::TrustedImmPtr(callee), GPRInfo::nonPreservedNonArgumentGPR);
5180
                    jit.call(GPRInfo::nonPreservedNonArgumentGPR);
5181
                    exceptions.append(jit.emitExceptionCheck(AssemblyHelpers::NormalExceptionCheck, AssemblyHelpers::FarJumpWidth));
5182
                };
5183
5184
                unsigned originalStackHeight = params.proc().frameSize();
5185
5186
                unsigned extraStack = sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*));
5187
            });
5188
#else
5098
        unsigned stackmapID = m_stackmapIDs++;
5189
        unsigned stackmapID = m_stackmapIDs++;
5099
        
5190
        
5100
        StackmapArgumentList arguments;
5191
        StackmapArgumentList arguments;
Lines 5108-5122 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec7
5108
5199
5109
        arguments.insert(0, m_out.constInt32(2 + !!jsArguments));
5200
        arguments.insert(0, m_out.constInt32(2 + !!jsArguments));
5110
        arguments.insert(0, constNull(m_out.ref8));
5201
        arguments.insert(0, constNull(m_out.ref8));
5111
        arguments.insert(0, m_out.constInt32(sizeOfICFor(m_node)));
5202
        arguments.insert(0, m_out.constInt32(sizeOfICFor(node)));
5112
        arguments.insert(0, m_out.constInt64(stackmapID));
5203
        arguments.insert(0, m_out.constInt64(stackmapID));
5113
        
5204
        
5114
        LValue call = m_out.call(m_out.int64, m_out.patchpointInt64Intrinsic(), arguments);
5205
        LValue call = m_out.call(m_out.int64, m_out.patchpointInt64Intrinsic(), arguments);
5115
        setInstructionCallingConvention(call, LLVMCCallConv);
5206
        setInstructionCallingConvention(call, LLVMCCallConv);
5116
        
5207
        
5117
        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, m_node, codeOriginDescriptionOfCallSite()));
5208
        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, node, codeOriginDescriptionOfCallSite()));
5118
5209
5119
        switch (m_node->op()) {
5210
        switch (node->op()) {
5120
        case TailCallVarargs:
5211
        case TailCallVarargs:
5121
        case TailCallForwardVarargs:
5212
        case TailCallForwardVarargs:
5122
            m_out.unreachable();
5213
            m_out.unreachable();

Return to Bug 152468