Changeset 90035 in webkit


Ignore:
Timestamp:
Jun 29, 2011 12:46:28 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-06-29 Filip Pizlo <fpizlo@apple.com>

Reviewed by Gavin Barraclough.

DFG JIT does not perform get_by_id self list caching.
https://bugs.webkit.org/show_bug.cgi?id=63605

  • bytecode/StructureStubInfo.h:
  • dfg/DFGJITCompiler.cpp: (JSC::DFG::JITCompiler::compileFunction):
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGRepatch.cpp: (JSC::DFG::tryCacheGetByID): (JSC::DFG::tryBuildGetByIDList): (JSC::DFG::dfgBuildGetByIDList):
  • dfg/DFGRepatch.h:
Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r89986 r90035  
     12011-06-29  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Reviewed by Gavin Barraclough.
     4
     5        DFG JIT does not perform get_by_id self list caching.
     6        https://bugs.webkit.org/show_bug.cgi?id=63605
     7
     8        * bytecode/StructureStubInfo.h:
     9        * dfg/DFGJITCompiler.cpp:
     10        (JSC::DFG::JITCompiler::compileFunction):
     11        * dfg/DFGOperations.cpp:
     12        * dfg/DFGOperations.h:
     13        * dfg/DFGRepatch.cpp:
     14        (JSC::DFG::tryCacheGetByID):
     15        (JSC::DFG::tryBuildGetByIDList):
     16        (JSC::DFG::dfgBuildGetByIDList):
     17        * dfg/DFGRepatch.h:
     18
    1192011-06-28  Filip Pizlo  <fpizlo@apple.com>
    220
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h

    r89986 r90035  
    128128        }
    129129
    130         signed accessType : 31;
    131         unsigned seen : 1;
     130        int8_t accessType;
     131        int8_t seen;
     132       
     133#if ENABLE(DFG_JIT)
     134        int8_t baseGPR;
     135        int8_t valueGPR;
     136        int8_t deltaCallToDone;
     137        int8_t deltaCallToStructCheck;
     138        int8_t deltaCallToSlowCase;
     139#endif
    132140
    133141        union {
    134142            struct {
    135143                int8_t deltaCheckImmToCall;
    136                 int8_t deltaCallToStructCheck;
    137144                int8_t deltaCallToLoadOrStore;
    138                 int8_t deltaCallToSlowCase;
    139                 int8_t deltaCallToDone;
    140                 int8_t baseGPR;
    141                 int8_t valueGPR;
    142145                int8_t scratchGPR;
    143146            } unset;
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r89986 r90035  
    389389        info.callReturnLocation = linkBuffer.locationOf(m_propertyAccesses[i].m_functionCall);
    390390        info.u.unset.deltaCheckImmToCall = m_propertyAccesses[i].m_deltaCheckImmToCall;
    391         info.u.unset.deltaCallToStructCheck = m_propertyAccesses[i].m_deltaCallToStructCheck;
     391        info.deltaCallToStructCheck = m_propertyAccesses[i].m_deltaCallToStructCheck;
    392392        info.u.unset.deltaCallToLoadOrStore = m_propertyAccesses[i].m_deltaCallToLoadOrStore;
    393         info.u.unset.deltaCallToSlowCase = m_propertyAccesses[i].m_deltaCallToSlowCase;
    394         info.u.unset.deltaCallToDone = m_propertyAccesses[i].m_deltaCallToDone;
    395         info.u.unset.baseGPR = m_propertyAccesses[i].m_baseGPR;
    396         info.u.unset.valueGPR = m_propertyAccesses[i].m_valueGPR;
     393        info.deltaCallToSlowCase = m_propertyAccesses[i].m_deltaCallToSlowCase;
     394        info.deltaCallToDone = m_propertyAccesses[i].m_deltaCallToDone;
     395        info.baseGPR = m_propertyAccesses[i].m_baseGPR;
     396        info.valueGPR = m_propertyAccesses[i].m_valueGPR;
    397397        info.u.unset.scratchGPR = m_propertyAccesses[i].m_scratchGPR;
    398398    }
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r89861 r90035  
    245245}
    246246
     247EncodedJSValue operationGetByIdBuildListWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
     248FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdBuildList);
     249EncodedJSValue operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
     250{
     251    JSValue baseValue = JSValue::decode(encodedBase);
     252    PropertySlot slot(baseValue);
     253    JSValue result = baseValue.get(exec, *propertyName, slot);
     254
     255    StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
     256    dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
     257
     258    return JSValue::encode(result);
     259}
     260
    247261void operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
    248262{
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r89861 r90035  
    6060EncodedJSValue operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty);
    6161EncodedJSValue operationGetById(ExecState*, EncodedJSValue encodedBase, Identifier*);
     62EncodedJSValue operationGetByIdBuildList(ExecState*, EncodedJSValue encodedBase, Identifier*);
    6263EncodedJSValue operationGetByIdOptimize(ExecState*, EncodedJSValue encodedBase, Identifier*);
    6364void operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
  • trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp

    r89986 r90035  
    6565   
    6666    if (isJSArray(globalData, baseValue) && propertyName == exec->propertyNames().length) {
    67         GPRReg baseGPR = static_cast<GPRReg>(stubInfo.u.unset.baseGPR);
    68         GPRReg resultGPR = static_cast<GPRReg>(stubInfo.u.unset.valueGPR);
     67        GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
     68        GPRReg resultGPR = static_cast<GPRReg>(stubInfo.valueGPR);
    6969        GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.u.unset.scratchGPR);
    7070        bool needToRestoreScratch = false;
     
    105105        LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
    106106       
    107         CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.u.unset.deltaCallToSlowCase);
    108        
    109         patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.u.unset.deltaCallToDone));
     107        CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase);
     108       
     109        patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
    110110       
    111111        if (needToRestoreScratch)
     
    122122        CodeLocationLabel hotPathBegin = stubInfo.hotPathBegin;
    123123        RepatchBuffer repatchBuffer(codeBlock);
    124         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.u.unset.deltaCallToStructCheck), entryLabel);
     124        repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), entryLabel);
    125125        repatchBuffer.relink(stubInfo.callReturnLocation, operationGetById);
    126126       
     
    145145            return false;
    146146
    147         dfgRepatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetById, true);
     147        dfgRepatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdBuildList, true);
    148148        stubInfo.initGetByIdSelf(*globalData, codeBlock->ownerExecutable(), structure);
    149149        return true;
    150150    }
    151 
     151   
    152152    // FIXME: should support prototype & chain accesses!
    153153    return false;
     
    158158    bool cached = tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo);
    159159    if (!cached)
     160        dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);
     161}
     162
     163static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier&, const PropertySlot& slot, StructureStubInfo& stubInfo)
     164{
     165    if (!baseValue.isCell()
     166        || !slot.isCacheable()
     167        || baseValue.asCell()->structure()->isUncacheableDictionary()
     168        || slot.slotBase() != baseValue
     169        || slot.cachedPropertyType() != PropertySlot::Value
     170        || (slot.cachedOffset() * sizeof(JSValue)) > (unsigned)MacroAssembler::MaximumCompactPtrAlignedAddressOffset)
     171        return false;
     172   
     173    CodeBlock* codeBlock = exec->codeBlock();
     174    JSCell* baseCell = baseValue.asCell();
     175    Structure* structure = baseCell->structure();
     176    JSGlobalData* globalData = &exec->globalData();
     177   
     178    ASSERT(slot.slotBase().isObject());
     179   
     180    PolymorphicAccessStructureList* polymorphicStructureList;
     181    int listIndex = 1;
     182   
     183    if (stubInfo.accessType == access_get_by_id_self) {
     184        ASSERT(!stubInfo.stubRoutine);
     185        polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase), stubInfo.u.getByIdSelf.baseObjectStructure.get());
     186        stubInfo.initGetByIdSelfList(polymorphicStructureList, 1);
     187    } else {
     188        polymorphicStructureList = stubInfo.u.getByIdSelfList.structureList;
     189        listIndex = stubInfo.u.getByIdSelfList.listSize;
     190    }
     191   
     192    if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
     193        stubInfo.u.getByIdSelfList.listSize++;
     194       
     195        GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
     196        GPRReg resultGPR = static_cast<GPRReg>(stubInfo.valueGPR);
     197       
     198        MacroAssembler stubJit;
     199       
     200        MacroAssembler::Jump wrongStruct = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(structure));
     201       
     202        if (structure->isUsingInlineStorage())
     203            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue)), resultGPR);
     204        else {
     205            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
     206            stubJit.loadPtr(MacroAssembler::Address(resultGPR, slot.cachedOffset() * sizeof(JSValue)), resultGPR);
     207        }
     208       
     209        MacroAssembler::Jump success = stubJit.jump();
     210       
     211        LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
     212       
     213        CodeLocationLabel lastProtoBegin = polymorphicStructureList->list[listIndex - 1].stubRoutine;
     214        ASSERT(!!lastProtoBegin);
     215       
     216        patchBuffer.link(wrongStruct, lastProtoBegin);
     217        patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
     218       
     219        CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
     220       
     221        polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), entryLabel, structure);
     222       
     223        CodeLocationJump jumpLocation = stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck);
     224        RepatchBuffer repatchBuffer(codeBlock);
     225        repatchBuffer.relink(jumpLocation, entryLabel);
     226       
     227        if (listIndex < (POLYMORPHIC_LIST_CACHE_SIZE - 1))
     228            return true;
     229    }
     230   
     231    return false;
     232}
     233
     234void dfgBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
     235{
     236    bool dontChangeCall = tryBuildGetByIDList(exec, baseValue, propertyName, slot, stubInfo);
     237    if (!dontChangeCall)
    160238        dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);
    161239}
  • trunk/Source/JavaScriptCore/dfg/DFGRepatch.h

    r89861 r90035  
    3535
    3636void dfgRepatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
     37void dfgBuildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
    3738void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
    3839
Note: See TracChangeset for help on using the changeset viewer.