⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 194067 in webkit


Ignore:
Timestamp:
Dec 14, 2015, 3:18:36 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

FTL B3 should do PutById
https://bugs.webkit.org/show_bug.cgi?id=152268

Reviewed by Saam Barati.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::createGenericCompare): I realized that we were missing some useful matching rules.

  • b3/testb3.cpp: Added a bunch of tests.
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compilePutById): Do the things.

  • jit/GPRInfo.cpp: Added. I had to do this yucky thing because clang was having issues compiling references to this from deeply nested lambdas.
  • jit/GPRInfo.h: Added a comment about how patchpointScratchRegister is bizarre and should probably die.
Location:
trunk/Source/JavaScriptCore
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r194003 r194067  
    452452    jit/ExecutableAllocatorFixedVMPool.cpp
    453453    jit/GCAwareJITStubRoutine.cpp
     454    jit/GPRInfo.cpp
    454455    jit/HostCallReturnValue.cpp
    455456    jit/IntrinsicEmitter.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r194062 r194067  
     12015-12-14  Filip Pizlo  <fpizlo@apple.com>
     2
     3        FTL B3 should do PutById
     4        https://bugs.webkit.org/show_bug.cgi?id=152268
     5
     6        Reviewed by Saam Barati.
     7
     8        * CMakeLists.txt:
     9        * JavaScriptCore.xcodeproj/project.pbxproj:
     10        * b3/B3LowerToAir.cpp:
     11        (JSC::B3::Air::LowerToAir::createGenericCompare): I realized that we were missing some useful matching rules.
     12        * b3/testb3.cpp: Added a bunch of tests.
     13        * ftl/FTLLowerDFGToLLVM.cpp:
     14        (JSC::FTL::DFG::LowerDFGToLLVM::compilePutById): Do the things.
     15        * jit/GPRInfo.cpp: Added. I had to do this yucky thing because clang was having issues compiling references to this from deeply nested lambdas.
     16        * jit/GPRInfo.h: Added a comment about how patchpointScratchRegister is bizarre and should probably die.
     17
    1182015-12-14  Benjamin Poulain  <bpoulain@apple.com>
    219
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r194003 r194067  
    482482                0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D2315853CDE004A4E7D /* Watchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
    483483                0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D2715856770004A4E7D /* SymbolTable.cpp */; };
     484                0F93274D1C1F66AA00CF6564 /* GPRInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F93274C1C1F66AA00CF6564 /* GPRInfo.cpp */; };
    484485                0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */; };
    485486                0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    25932594                0F919D2315853CDE004A4E7D /* Watchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchpoint.h; sourceTree = "<group>"; };
    25942595                0F919D2715856770004A4E7D /* SymbolTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolTable.cpp; sourceTree = "<group>"; };
     2596                0F93274C1C1F66AA00CF6564 /* GPRInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GPRInfo.cpp; sourceTree = "<group>"; };
    25952597                0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallLinkStatus.cpp; sourceTree = "<group>"; };
    25962598                0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallLinkStatus.h; sourceTree = "<group>"; };
     
    48934895                                0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */,
    48944896                                0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */,
     4897                                0F93274C1C1F66AA00CF6564 /* GPRInfo.cpp */,
    48954898                                0F24E53F17EA9F5900ABB217 /* GPRInfo.h */,
    48964899                                0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
     
    49054908                                FE3A06AD1C10CB6F00390FDD /* JITBitAndGenerator.cpp */,
    49064909                                FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */,
     4910                                FE3A06A71C10BC7400390FDD /* JITBitBinaryOpGenerator.h */,
    49074911                                FE3A06A31C10B70800390FDD /* JITBitOrGenerator.cpp */,
    49084912                                FE3A06A41C10B70800390FDD /* JITBitOrGenerator.h */,
    49094913                                FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */,
    49104914                                FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */,
    4911                                 FE3A06A71C10BC7400390FDD /* JITBitBinaryOpGenerator.h */,
    49124915                                86CC85A20EE79B7400288682 /* JITCall.cpp */,
    49134916                                146FE51111A710430087AE66 /* JITCall32_64.cpp */,
     
    87568759                                0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
    87578760                                0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
     8761                                0F93274D1C1F66AA00CF6564 /* GPRInfo.cpp in Sources */,
    87588762                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
    87598763                                0FEA0A09170513DB00BB722C /* FTLCapabilities.cpp in Sources */,
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r194062 r194067  
    11321132        Arg resCond = Arg::resCond(MacroAssembler::NonZero).inverted(inverted);
    11331133       
     1134        auto tryTest = [&] (
     1135            Arg::Width width, const ArgPromise& left, const ArgPromise& right) -> Inst {
     1136            if (Inst result = test(width, resCond, left, right))
     1137                return result;
     1138            if (Inst result = test(width, resCond, right, left))
     1139                return result;
     1140            return Inst();
     1141        };
     1142
    11341143        auto attemptFused = [&] () -> Inst {
    11351144            switch (value->opcode()) {
     
    11661175                Arg rightImm = imm(right);
    11671176               
    1168                 auto tryTest = [&] (
    1169                     Arg::Width width, const ArgPromise& left, const ArgPromise& right) -> Inst {
    1170                     if (Inst result = test(width, resCond, left, right))
    1171                         return result;
    1172                     if (Inst result = test(width, resCond, right, left))
    1173                         return result;
    1174                     return Inst();
    1175                 };
    1176 
    11771177                auto tryTestLoadImm = [&] (Arg::Width width, B3::Opcode loadOpcode) -> Inst {
    11781178                    if (rightImm && rightImm.isRepresentableAs(width, Arg::Unsigned)) {
     
    12511251            if (Inst result = attemptFused()) {
    12521252                commitFusion(value, fusionResult);
     1253                return result;
     1254            }
     1255        }
     1256
     1257        if (canCommitInternal && value->as<MemoryValue>()) {
     1258            // Handle things like Branch(Load8Z(value))
     1259
     1260            if (Inst result = tryTest(Arg::Width8, loadPromise(value, Load8Z), Arg::imm(-1))) {
     1261                commitInternal(value);
     1262                return result;
     1263            }
     1264
     1265            if (Inst result = tryTest(Arg::Width8, loadPromise(value, Load8S), Arg::imm(-1))) {
     1266                commitInternal(value);
     1267                return result;
     1268            }
     1269
     1270            if (Inst result = tryTest(Arg::Width16, loadPromise(value, Load16Z), Arg::imm(-1))) {
     1271                commitInternal(value);
     1272                return result;
     1273            }
     1274
     1275            if (Inst result = tryTest(Arg::Width16, loadPromise(value, Load16S), Arg::imm(-1))) {
     1276                commitInternal(value);
     1277                return result;
     1278            }
     1279
     1280            if (Inst result = tryTest(width, loadPromise(value), Arg::imm(-1))) {
     1281                commitInternal(value);
    12531282                return result;
    12541283            }
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r194062 r194067  
    51655165
    51665166    CHECK(compileAndRun<int>(proc) == !value);
     5167}
     5168
     5169void testBranchLoadPtr()
     5170{
     5171    Procedure proc;
     5172    BasicBlock* root = proc.addBlock();
     5173    BasicBlock* thenCase = proc.addBlock();
     5174    BasicBlock* elseCase = proc.addBlock();
     5175
     5176    root->appendNew<ControlValue>(
     5177        proc, Branch, Origin(),
     5178        root->appendNew<MemoryValue>(
     5179            proc, Load, pointerType(), Origin(),
     5180            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     5181        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     5182
     5183    thenCase->appendNew<ControlValue>(
     5184        proc, Return, Origin(),
     5185        thenCase->appendNew<Const32Value>(proc, Origin(), 1));
     5186
     5187    elseCase->appendNew<ControlValue>(
     5188        proc, Return, Origin(),
     5189        elseCase->appendNew<Const32Value>(proc, Origin(), 0));
     5190
     5191    auto code = compile(proc);
     5192    intptr_t cond;
     5193    cond = 42;
     5194    CHECK(invoke<int>(*code, &cond) == 1);
     5195    cond = 0;
     5196    CHECK(invoke<int>(*code, &cond) == 0);
     5197}
     5198
     5199void testBranchLoad32()
     5200{
     5201    Procedure proc;
     5202    BasicBlock* root = proc.addBlock();
     5203    BasicBlock* thenCase = proc.addBlock();
     5204    BasicBlock* elseCase = proc.addBlock();
     5205
     5206    root->appendNew<ControlValue>(
     5207        proc, Branch, Origin(),
     5208        root->appendNew<MemoryValue>(
     5209            proc, Load, Int32, Origin(),
     5210            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     5211        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     5212
     5213    thenCase->appendNew<ControlValue>(
     5214        proc, Return, Origin(),
     5215        thenCase->appendNew<Const32Value>(proc, Origin(), 1));
     5216
     5217    elseCase->appendNew<ControlValue>(
     5218        proc, Return, Origin(),
     5219        elseCase->appendNew<Const32Value>(proc, Origin(), 0));
     5220
     5221    auto code = compile(proc);
     5222    int32_t cond;
     5223    cond = 42;
     5224    CHECK(invoke<int>(*code, &cond) == 1);
     5225    cond = 0;
     5226    CHECK(invoke<int>(*code, &cond) == 0);
     5227}
     5228
     5229void testBranchLoad8S()
     5230{
     5231    Procedure proc;
     5232    BasicBlock* root = proc.addBlock();
     5233    BasicBlock* thenCase = proc.addBlock();
     5234    BasicBlock* elseCase = proc.addBlock();
     5235
     5236    root->appendNew<ControlValue>(
     5237        proc, Branch, Origin(),
     5238        root->appendNew<MemoryValue>(
     5239            proc, Load8S, Origin(),
     5240            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     5241        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     5242
     5243    thenCase->appendNew<ControlValue>(
     5244        proc, Return, Origin(),
     5245        thenCase->appendNew<Const32Value>(proc, Origin(), 1));
     5246
     5247    elseCase->appendNew<ControlValue>(
     5248        proc, Return, Origin(),
     5249        elseCase->appendNew<Const32Value>(proc, Origin(), 0));
     5250
     5251    auto code = compile(proc);
     5252    int8_t cond;
     5253    cond = -1;
     5254    CHECK(invoke<int>(*code, &cond) == 1);
     5255    cond = 0;
     5256    CHECK(invoke<int>(*code, &cond) == 0);
     5257}
     5258
     5259void testBranchLoad8Z()
     5260{
     5261    Procedure proc;
     5262    BasicBlock* root = proc.addBlock();
     5263    BasicBlock* thenCase = proc.addBlock();
     5264    BasicBlock* elseCase = proc.addBlock();
     5265
     5266    root->appendNew<ControlValue>(
     5267        proc, Branch, Origin(),
     5268        root->appendNew<MemoryValue>(
     5269            proc, Load8Z, Origin(),
     5270            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     5271        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     5272
     5273    thenCase->appendNew<ControlValue>(
     5274        proc, Return, Origin(),
     5275        thenCase->appendNew<Const32Value>(proc, Origin(), 1));
     5276
     5277    elseCase->appendNew<ControlValue>(
     5278        proc, Return, Origin(),
     5279        elseCase->appendNew<Const32Value>(proc, Origin(), 0));
     5280
     5281    auto code = compile(proc);
     5282    uint8_t cond;
     5283    cond = 1;
     5284    CHECK(invoke<int>(*code, &cond) == 1);
     5285    cond = 0;
     5286    CHECK(invoke<int>(*code, &cond) == 0);
     5287}
     5288
     5289void testBranchLoad16S()
     5290{
     5291    Procedure proc;
     5292    BasicBlock* root = proc.addBlock();
     5293    BasicBlock* thenCase = proc.addBlock();
     5294    BasicBlock* elseCase = proc.addBlock();
     5295
     5296    root->appendNew<ControlValue>(
     5297        proc, Branch, Origin(),
     5298        root->appendNew<MemoryValue>(
     5299            proc, Load16S, Origin(),
     5300            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     5301        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     5302
     5303    thenCase->appendNew<ControlValue>(
     5304        proc, Return, Origin(),
     5305        thenCase->appendNew<Const32Value>(proc, Origin(), 1));
     5306
     5307    elseCase->appendNew<ControlValue>(
     5308        proc, Return, Origin(),
     5309        elseCase->appendNew<Const32Value>(proc, Origin(), 0));
     5310
     5311    auto code = compile(proc);
     5312    int16_t cond;
     5313    cond = -1;
     5314    CHECK(invoke<int>(*code, &cond) == 1);
     5315    cond = 0;
     5316    CHECK(invoke<int>(*code, &cond) == 0);
     5317}
     5318
     5319void testBranchLoad16Z()
     5320{
     5321    Procedure proc;
     5322    BasicBlock* root = proc.addBlock();
     5323    BasicBlock* thenCase = proc.addBlock();
     5324    BasicBlock* elseCase = proc.addBlock();
     5325
     5326    root->appendNew<ControlValue>(
     5327        proc, Branch, Origin(),
     5328        root->appendNew<MemoryValue>(
     5329            proc, Load16Z, Origin(),
     5330            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     5331        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     5332
     5333    thenCase->appendNew<ControlValue>(
     5334        proc, Return, Origin(),
     5335        thenCase->appendNew<Const32Value>(proc, Origin(), 1));
     5336
     5337    elseCase->appendNew<ControlValue>(
     5338        proc, Return, Origin(),
     5339        elseCase->appendNew<Const32Value>(proc, Origin(), 0));
     5340
     5341    auto code = compile(proc);
     5342    uint16_t cond;
     5343    cond = 1;
     5344    CHECK(invoke<int>(*code, &cond) == 1);
     5345    cond = 0;
     5346    CHECK(invoke<int>(*code, &cond) == 0);
    51675347}
    51685348
     
    89159095    RUN(testBranchEqualFoldPtr(42));
    89169096    RUN(testBranchEqualFoldPtr(0));
     9097    RUN(testBranchLoadPtr());
     9098    RUN(testBranchLoad32());
     9099    RUN(testBranchLoad8S());
     9100    RUN(testBranchLoad8Z());
     9101    RUN(testBranchLoad16S());
     9102    RUN(testBranchLoad16Z());
    89179103
    89189104    RUN(testComplex(64, 128));
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r194048 r194067  
    24732473    void compilePutById()
    24742474    {
     2475        Node* node = m_node;
     2476       
    24752477        // See above; CellUse is easier so we do only that for now.
    2476         ASSERT(m_node->child1().useKind() == CellUse);
     2478        ASSERT(node->child1().useKind() == CellUse);
     2479
     2480        LValue base = lowCell(node->child1());
     2481        LValue value = lowJSValue(node->child2());
     2482        auto uid = m_graph.identifiers()[node->identifierNumber()];
    24772483
    24782484#if FTL_USES_B3
    2479         if (verboseCompilationEnabled() || !verboseCompilationEnabled())
    2480             CRASH();
     2485        // FIXME: Make this do exceptions.
     2486        // https://bugs.webkit.org/show_bug.cgi?id=151686
     2487
     2488        B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
     2489        patchpoint->append(base, ValueRep::SomeRegister);
     2490        patchpoint->append(value, ValueRep::SomeRegister);
     2491        patchpoint->clobber(RegisterSet::macroScratchRegisters());
     2492
     2493        State* state = &m_ftlState;
     2494        ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
     2495       
     2496        patchpoint->setGenerator(
     2497            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     2498                AllowMacroScratchRegisterUsage allowScratch(jit);
     2499
     2500                auto generator = Box<JITPutByIdGenerator>::create(
     2501                    jit.codeBlock(), node->origin.semantic,
     2502                    state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic),
     2503                    params.usedRegisters(), JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()),
     2504                    GPRInfo::patchpointScratchRegister, ecmaMode,
     2505                    node->op() == PutByIdDirect ? Direct : NotDirect);
     2506
     2507                generator->generateFastPath(jit);
     2508                CCallHelpers::Label done = jit.label();
     2509
     2510                params.addLatePath(
     2511                    [=] (CCallHelpers& jit) {
     2512                        AllowMacroScratchRegisterUsage allowScratch(jit);
     2513
     2514                        // FIXME: Make this do something.
     2515                        CCallHelpers::JumpList exceptions;
     2516
     2517                        generator->slowPathJump().link(&jit);
     2518                        CCallHelpers::Label slowPathBegin = jit.label();
     2519                        CCallHelpers::Call slowPathCall = callOperation(
     2520                            *state, params.usedRegisters(), jit, node->origin.semantic, &exceptions,
     2521                            generator->slowPathFunction(), InvalidGPRReg,
     2522                            CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
     2523                            params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
     2524                        jit.jump().linkTo(done, &jit);
     2525
     2526                        generator->reportSlowPathCall(slowPathBegin, slowPathCall);
     2527
     2528                        jit.addLinkTask(
     2529                            [=] (LinkBuffer& linkBuffer) {
     2530                                generator->finalize(linkBuffer);
     2531                            });
     2532                    });
     2533            });
    24812534#else
    2482         LValue base = lowCell(m_node->child1());
    2483         LValue value = lowJSValue(m_node->child2());
    2484         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
    2485 
    24862535        // Arguments: id, bytes, target, numArgs, args...
    24872536        unsigned stackmapID = m_stackmapIDs++;
     
    25052554       
    25062555        m_ftlState.putByIds.append(PutByIdDescriptor(
    2507             stackmapID, m_node->origin.semantic, uid,
    2508             m_graph.executableFor(m_node->origin.semantic)->ecmaMode(),
    2509             m_node->op() == PutByIdDirect ? Direct : NotDirect));
     2556            stackmapID, node->origin.semantic, uid,
     2557            m_graph.executableFor(node->origin.semantic)->ecmaMode(),
     2558            node->op() == PutByIdDirect ? Direct : NotDirect));
    25102559#endif
    25112560    }
  • trunk/Source/JavaScriptCore/jit/GPRInfo.h

    r192812 r194067  
    454454    static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
    455455    static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
    456     static const GPRReg patchpointScratchRegister = MacroAssembler::s_scratchRegister;
     456
     457    // FIXME: I believe that all uses of this are dead in the sense that it just causes the scratch
     458    // register allocator to select a different register and potentially spill things. It would be better
     459    // if we instead had a more explicit way of saying that we don't have a scratch register.
     460    static const GPRReg patchpointScratchRegister;
    457461
    458462    static GPRReg toRegister(unsigned index)
Note: See TracChangeset for help on using the changeset viewer.