Changeset 158681 in webkit


Ignore:
Timestamp:
Nov 5, 2013 10:56:06 AM (10 years ago)
Author:
fpizlo@apple.com
Message:

FTL should support PutById
https://bugs.webkit.org/show_bug.cgi?id=123784

Reviewed by Geoffrey Garen.

  • ftl/FTLAbbreviations.h:

(JSC::FTL::buildCall):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLCompile.cpp:

(JSC::FTL::generateICFastPath):
(JSC::FTL::fixFunctionBasedOnStackMaps):

  • ftl/FTLInlineCacheDescriptor.h:

(JSC::FTL::InlineCacheDescriptor::InlineCacheDescriptor):
(JSC::FTL::GetByIdDescriptor::GetByIdDescriptor):
(JSC::FTL::PutByIdDescriptor::PutByIdDescriptor):
(JSC::FTL::PutByIdDescriptor::ecmaMode):
(JSC::FTL::PutByIdDescriptor::putKind):

  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compilePutById):

  • ftl/FTLOutput.h:

(JSC::FTL::Output::call):

  • ftl/FTLSlowPathCall.cpp:

(JSC::FTL::callOperation):

  • ftl/FTLSlowPathCall.h:
  • ftl/FTLState.h:
  • jit/CCallHelpers.h:

(JSC::CCallHelpers::setupArguments):

  • runtime/Executable.h:

(JSC::ScriptExecutable::ecmaMode):

Location:
trunk/Source/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r158680 r158681  
     12013-11-04  Filip Pizlo  <fpizlo@apple.com>
     2
     3        FTL should support PutById
     4        https://bugs.webkit.org/show_bug.cgi?id=123784
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * ftl/FTLAbbreviations.h:
     9        (JSC::FTL::buildCall):
     10        * ftl/FTLCapabilities.cpp:
     11        (JSC::FTL::canCompile):
     12        * ftl/FTLCompile.cpp:
     13        (JSC::FTL::generateICFastPath):
     14        (JSC::FTL::fixFunctionBasedOnStackMaps):
     15        * ftl/FTLInlineCacheDescriptor.h:
     16        (JSC::FTL::InlineCacheDescriptor::InlineCacheDescriptor):
     17        (JSC::FTL::GetByIdDescriptor::GetByIdDescriptor):
     18        (JSC::FTL::PutByIdDescriptor::PutByIdDescriptor):
     19        (JSC::FTL::PutByIdDescriptor::ecmaMode):
     20        (JSC::FTL::PutByIdDescriptor::putKind):
     21        * ftl/FTLIntrinsicRepository.h:
     22        * ftl/FTLLowerDFGToLLVM.cpp:
     23        (JSC::FTL::LowerDFGToLLVM::compileNode):
     24        (JSC::FTL::LowerDFGToLLVM::compilePutById):
     25        * ftl/FTLOutput.h:
     26        (JSC::FTL::Output::call):
     27        * ftl/FTLSlowPathCall.cpp:
     28        (JSC::FTL::callOperation):
     29        * ftl/FTLSlowPathCall.h:
     30        * ftl/FTLState.h:
     31        * jit/CCallHelpers.h:
     32        (JSC::CCallHelpers::setupArguments):
     33        * runtime/Executable.h:
     34        (JSC::ScriptExecutable::ecmaMode):
     35
    1362013-11-04  Filip Pizlo  <fpizlo@apple.com>
    237
  • trunk/Source/JavaScriptCore/ftl/FTLAbbreviations.h

    r157872 r158681  
    260260    return buildCall(builder, function, args, 6);
    261261}
     262static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7)
     263{
     264    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
     265    return buildCall(builder, function, args, 7);
     266}
     267static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8)
     268{
     269    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
     270    return buildCall(builder, function, args, 8);
     271}
    262272enum TailCallMode { IsNotTailCall, IsTailCall };
    263273static inline void setTailCall(LValue call, TailCallMode mode) { llvm->SetTailCall(call, mode == IsTailCall); }
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r158304 r158681  
    100100        break;
    101101    case GetById:
     102    case PutById:
    102103        if (node->child1().useKind() == CellUse)
    103104            break;
  • trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp

    r158535 r158681  
    107107}
    108108
     109template<typename DescriptorType>
     110void generateICFastPath(
     111    State& state, CodeBlock* codeBlock, GeneratedFunction generatedFunction,
     112    StackMaps::RecordMap& recordMap, DescriptorType& ic, size_t sizeOfIC)
     113{
     114    VM& vm = state.graph.m_vm;
     115
     116    StackMaps::RecordMap::iterator iter = recordMap.find(ic.stackmapID());
     117    if (iter == recordMap.end()) {
     118        // It was optimized out.
     119        return;
     120    }
     121   
     122    StackMaps::Record& record = iter->value;
     123
     124    CCallHelpers fastPathJIT(&vm, codeBlock);
     125    ic.m_generator.generateFastPath(fastPathJIT);
     126
     127    char* startOfIC =
     128        bitwise_cast<char*>(generatedFunction) + record.instructionOffset;
     129           
     130    LinkBuffer linkBuffer(vm, &fastPathJIT, startOfIC, sizeOfIC);
     131    // Note: we could handle the !isValid() case. We just don't appear to have a
     132    // reason to do so, yet.
     133    RELEASE_ASSERT(linkBuffer.isValid());
     134   
     135    state.finalizer->sideCodeLinkBuffer->link(
     136        ic.m_slowPathDone, CodeLocationLabel(startOfIC + sizeOfIC));
     137           
     138    linkBuffer.link(
     139        ic.m_generator.slowPathJump(),
     140        state.finalizer->sideCodeLinkBuffer->locationOf(ic.m_generator.slowPathBegin()));
     141           
     142    ic.m_generator.finalize(linkBuffer, *state.finalizer->sideCodeLinkBuffer);
     143}
     144
    109145static void fixFunctionBasedOnStackMaps(
    110146    State& state, CodeBlock* codeBlock, JITCode* jitCode, GeneratedFunction generatedFunction,
     
    139175    }
    140176
    141     if (!state.getByIds.isEmpty()) {
     177    if (!state.getByIds.isEmpty() || !state.putByIds.isEmpty()) {
    142178        CCallHelpers slowPathJIT(&vm, codeBlock);
    143179       
     
    178214        }
    179215       
    180         state.finalizer->sideCodeLinkBuffer = adoptPtr(
    181             new LinkBuffer(vm, &slowPathJIT, codeBlock, JITCompilationMustSucceed));
    182        
    183         for (unsigned i = state.getByIds.size(); i--;) {
    184             GetByIdDescriptor& getById = state.getByIds[i];
    185            
    186             StackMaps::RecordMap::iterator iter = recordMap.find(getById.stackmapID());
     216        for (unsigned i = state.putByIds.size(); i--;) {
     217            PutByIdDescriptor& putById = state.putByIds[i];
     218           
     219            StackMaps::RecordMap::iterator iter = recordMap.find(putById.stackmapID());
    187220            if (iter == recordMap.end()) {
    188221                // It was optimized out.
     
    191224           
    192225            StackMaps::Record& record = iter->value;
    193 
    194             CCallHelpers fastPathJIT(&vm, codeBlock);
    195             getById.m_generator.generateFastPath(fastPathJIT);
    196 
    197             char* startOfIC =
    198                 bitwise_cast<char*>(generatedFunction) + record.instructionOffset;
    199             size_t sizeOfIC = sizeOfGetById();
    200            
    201             LinkBuffer linkBuffer(vm, &fastPathJIT, startOfIC, sizeOfIC);
    202             // Note: we could handle the !isValid() case. We just don't appear to have a
    203             // reason to do so, yet.
    204             RELEASE_ASSERT(linkBuffer.isValid());
    205            
    206             state.finalizer->sideCodeLinkBuffer->link(
    207                 getById.m_slowPathDone, CodeLocationLabel(startOfIC + sizeOfIC));
    208            
    209             linkBuffer.link(
    210                 getById.m_generator.slowPathJump(),
    211                 state.finalizer->sideCodeLinkBuffer->locationOf(getById.m_generator.slowPathBegin()));
    212            
    213             getById.m_generator.finalize(linkBuffer, *state.finalizer->sideCodeLinkBuffer);
     226           
     227            UNUSED_PARAM(record); // FIXME: use AnyRegs.
     228
     229            // FIXME: LLVM should tell us which registers are live.
     230            RegisterSet usedRegisters = RegisterSet::allRegisters();
     231           
     232            GPRReg callFrameRegister = GPRInfo::argumentGPR0;
     233            GPRReg base = GPRInfo::argumentGPR1;
     234            GPRReg value = GPRInfo::argumentGPR2;
     235           
     236            JITPutByIdGenerator gen(
     237                codeBlock, putById.codeOrigin(), usedRegisters, JSValueRegs(base),
     238                JSValueRegs(value), GPRInfo::argumentGPR3, false, putById.ecmaMode(),
     239                putById.putKind());
     240           
     241            MacroAssembler::Label begin = slowPathJIT.label();
     242           
     243            MacroAssembler::Call call = callOperation(
     244                state, usedRegisters, slowPathJIT, gen.slowPathFunction(), callFrameRegister,
     245                gen.stubInfo(), value, base, putById.uid());
     246           
     247            gen.reportSlowPathCall(begin, call);
     248           
     249            putById.m_slowPathDone = slowPathJIT.jump();
     250            putById.m_generator = gen;
     251        }
     252       
     253        state.finalizer->sideCodeLinkBuffer = adoptPtr(
     254            new LinkBuffer(vm, &slowPathJIT, codeBlock, JITCompilationMustSucceed));
     255       
     256        for (unsigned i = state.getByIds.size(); i--;) {
     257            generateICFastPath(
     258                state, codeBlock, generatedFunction, recordMap, state.getByIds[i],
     259                sizeOfGetById());
     260        }
     261        for (unsigned i = state.putByIds.size(); i--;) {
     262            generateICFastPath(
     263                state, codeBlock, generatedFunction, recordMap, state.putByIds[i],
     264                sizeOfPutById());
    214265        }
    215266    }
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h

    r157872 r158681  
    4040    InlineCacheDescriptor() { }
    4141   
    42     MacroAssembler::Jump m_slowPathDone;
    43 };
    44 
    45 class GetByIdDescriptor : public InlineCacheDescriptor {
    46 public:
    47     GetByIdDescriptor() { }
    48    
    49     GetByIdDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid)
     42    InlineCacheDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid)
    5043        : m_stackmapID(stackmapID)
    5144        , m_codeOrigin(codeOrigin)
     
    6255    CodeOrigin m_codeOrigin;
    6356    StringImpl* m_uid;
     57   
     58public:
     59    MacroAssembler::Jump m_slowPathDone;
     60};
    6461
     62class GetByIdDescriptor : public InlineCacheDescriptor {
    6563public:
     64    GetByIdDescriptor() { }
     65   
     66    GetByIdDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid)
     67        : InlineCacheDescriptor(stackmapID, codeOrigin, uid)
     68    {
     69    }
     70   
    6671    JITGetByIdGenerator m_generator;
     72};
     73
     74class PutByIdDescriptor : public InlineCacheDescriptor {
     75public:
     76    PutByIdDescriptor() { }
     77   
     78    PutByIdDescriptor(
     79        unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid,
     80        ECMAMode ecmaMode, PutKind putKind)
     81        : InlineCacheDescriptor(stackmapID, codeOrigin, uid)
     82        , m_ecmaMode(ecmaMode)
     83        , m_putKind(putKind)
     84    {
     85    }
     86   
     87    JITPutByIdGenerator m_generator;
     88   
     89    ECMAMode ecmaMode() const { return m_ecmaMode; }
     90    PutKind putKind() const { return m_putKind; }
     91
     92private:
     93    ECMAMode m_ecmaMode;
     94    PutKind m_putKind;
    6795};
    6896
  • trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h

    r158535 r158681  
    4646    macro(subWithOverflow64, "llvm.ssub.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \
    4747    macro(patchpointInt64, "llvm.experimental.patchpoint.i64", functionType(int64, int32, int32, ref8, int32, Variadic)) \
     48    macro(patchpointVoid, "llvm.experimental.patchpoint.void", functionType(voidType, int32, int32, ref8, int32, Variadic)) \
    4849    macro(stackmap, "llvm.experimental.stackmap", functionType(voidType, int32, int32, Variadic)) \
    4950    macro(trap, "llvm.trap", functionType(voidType)) \
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r158535 r158681  
    344344            compileGetById();
    345345            break;
     346        case PutById:
     347            compilePutById();
     348            break;
    346349        case GetButterfly:
    347350            compileGetButterfly();
     
    12581261       
    12591262        m_ftlState.getByIds.append(GetByIdDescriptor(stackmapID, m_node->codeOrigin, uid));
     1263    }
     1264   
     1265    void compilePutById()
     1266    {
     1267        // See above; CellUse is easier so we do only that for now.
     1268        ASSERT(m_node->child1().useKind() == CellUse);
     1269
     1270        LValue base = lowCell(m_node->child1());
     1271        LValue value = lowJSValue(m_node->child2());
     1272        StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
     1273
     1274        // Arguments: id, bytes, target, numArgs, args...
     1275        unsigned stackmapID = m_stackmapIDs++;
     1276        m_out.call(
     1277            m_out.patchpointVoidIntrinsic(),
     1278            m_out.constInt32(stackmapID), m_out.constInt32(sizeOfPutById()),
     1279            constNull(m_out.ref8), m_out.constInt32(3), m_callFrame, base, value);
     1280       
     1281        m_ftlState.putByIds.append(PutByIdDescriptor(
     1282            stackmapID, m_node->codeOrigin, uid,
     1283            m_graph.executableFor(m_node->codeOrigin)->ecmaMode(),
     1284            m_node->op() == PutByIdDirect ? Direct : NotDirect));
    12601285    }
    12611286   
  • trunk/Source/JavaScriptCore/ftl/FTLOutput.h

    r157872 r158681  
    351351    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5); }
    352352    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6); }
     353    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6, arg7); }
     354    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }
    353355   
    354356    template<typename FunctionType>
  • trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp

    r157872 r158681  
    101101    ~CallContext()
    102102    {
    103         m_jit.move(GPRInfo::returnValueGPR, m_returnRegister);
     103        if (m_returnRegister != InvalidGPRReg)
     104            m_jit.move(GPRInfo::returnValueGPR, m_returnRegister);
    104105       
    105106        for (unsigned i = std::min(NUMBER_OF_ARGUMENT_REGISTERS, m_numArgs); i--;) {
     
    164165}
    165166
     167MacroAssembler::Call callOperation(
     168    State& state, const RegisterSet& usedRegisters, CCallHelpers& jit,
     169    V_JITOperation_ESsiJJI operation, GPRReg callFrameRegister,
     170    StructureStubInfo* stubInfo, GPRReg value, GPRReg object, StringImpl* uid)
     171{
     172    CallContext context(state, usedRegisters, jit, 5, InvalidGPRReg);
     173    jit.setupArguments(
     174        callFrameRegister, CCallHelpers::TrustedImmPtr(stubInfo), value, object,
     175        CCallHelpers::TrustedImmPtr(uid));
     176    return context.makeCall(bitwise_cast<void*>(operation));
     177    // FIXME: FTL should support exceptions.
     178    // https://bugs.webkit.org/show_bug.cgi?id=113622
     179}
     180
    166181} } // namespace JSC::FTL
    167182
  • trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h

    r157872 r158681  
    6060    GPRReg result, GPRReg callFrameRegister, StructureStubInfo*, GPRReg object,
    6161    StringImpl* uid);
     62MacroAssembler::Call callOperation(
     63    State&, const RegisterSet&, CCallHelpers&, V_JITOperation_ESsiJJI,
     64    GPRReg callFrameRegister, StructureStubInfo*, GPRReg value, GPRReg object,
     65    StringImpl* uid);
    6266
    6367} } // namespace JSC::FTL
  • trunk/Source/JavaScriptCore/ftl/FTLState.h

    r157872 r158681  
    5959    JITFinalizer* finalizer;
    6060    SegmentedVector<GetByIdDescriptor> getByIds;
     61    SegmentedVector<PutByIdDescriptor> putByIds;
    6162    Vector<CString> codeSectionNames;
    6263    Vector<CString> dataSectionNames;
  • trunk/Source/JavaScriptCore/jit/CCallHelpers.h

    r157872 r158681  
    914914    }
    915915   
     916    ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
     917    {
     918        setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg3, arg4);
     919        move(arg2, GPRInfo::argumentGPR1);
     920        move(arg5, GPRInfo::argumentGPR4);
     921    }
     922   
    916923    ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
    917924    {
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r154986 r158681  
    384384    bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
    385385    bool isStrictMode() const { return m_features & StrictModeFeature; }
     386    ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
    386387       
    387388    void setNeverInline(bool value) { m_neverInline = value; }
Note: See TracChangeset for help on using the changeset viewer.