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

Changeset 90601 in webkit


Ignore:
Timestamp:
Jul 7, 2011, 4:48:39 PM (15 years ago)
Author:
commit-queue@webkit.org
Message:

DFG JIT does not implement get_by_id prototype caching.
https://bugs.webkit.org/show_bug.cgi?id=64077

Patch by Filip Pizlo <fpizlo@apple.com> on 2011-07-07
Reviewed by Gavin Barraclough.

  • dfg/DFGRepatch.cpp:

(JSC::DFG::emitRestoreScratch):
(JSC::DFG::linkRestoreScratch):
(JSC::DFG::tryCacheGetByID):

  • runtime/JSObject.h:

(JSC::JSObject::addressOfPropertyAtOffset):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r90598 r90601  
     12011-07-07  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG JIT does not implement get_by_id prototype caching.
     4        https://bugs.webkit.org/show_bug.cgi?id=64077
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        * dfg/DFGRepatch.cpp:
     9        (JSC::DFG::emitRestoreScratch):
     10        (JSC::DFG::linkRestoreScratch):
     11        (JSC::DFG::tryCacheGetByID):
     12        * runtime/JSObject.h:
     13        (JSC::JSObject::addressOfPropertyAtOffset):
     14
    1152011-07-07  Filip Pizlo  <fpizlo@apple.com>
    216
  • trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp

    r90598 r90601  
    5757}
    5858
     59static void emitRestoreScratch(MacroAssembler& stubJit, bool needToRestoreScratch, GPRReg scratchGPR, MacroAssembler::Jump& success, MacroAssembler::Jump& fail, MacroAssembler::Jump failureCase1, MacroAssembler::Jump failureCase2)
     60{
     61    if (needToRestoreScratch) {
     62        stubJit.pop(scratchGPR);
     63       
     64        success = stubJit.jump();
     65       
     66        // link failure cases here, so we can pop scratchGPR, and then jump back.
     67        failureCase1.link(&stubJit);
     68        failureCase2.link(&stubJit);
     69       
     70        stubJit.pop(scratchGPR);
     71       
     72        fail = stubJit.jump();
     73        return;
     74    }
     75   
     76    success = stubJit.jump();
     77}
     78
     79static void linkRestoreScratch(LinkBuffer& patchBuffer, bool needToRestoreScratch, StructureStubInfo& stubInfo, MacroAssembler::Jump& success, MacroAssembler::Jump& fail, MacroAssembler::Jump failureCase1, MacroAssembler::Jump failureCase2)
     80{
     81    CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase);
     82   
     83    patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
     84       
     85    patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
     86   
     87    if (needToRestoreScratch) {
     88        patchBuffer.link(fail, slowCaseBegin);
     89        return;
     90    }
     91   
     92    // link failure cases directly back to normal path
     93    patchBuffer.link(failureCase1, slowCaseBegin);
     94    patchBuffer.link(failureCase2, slowCaseBegin);
     95}
     96           
    5997static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
    6098{
     
    89127        MacroAssembler::Jump success, fail;
    90128       
    91         if (needToRestoreScratch) {
    92             stubJit.pop(scratchGPR);
    93            
    94             success = stubJit.jump();
    95            
    96             // link failure cases here, so we can pop scratchGPR, and then jump back.
    97             failureCase1.link(&stubJit);
    98             failureCase2.link(&stubJit);
    99            
    100             stubJit.pop(scratchGPR);
    101            
    102             fail = stubJit.jump();
    103         } else
    104             success = stubJit.jump();
     129        emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCase1, failureCase2);
    105130       
    106131        LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
    107132       
    108         CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase);
    109        
    110         patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
    111        
    112         if (needToRestoreScratch)
    113             patchBuffer.link(fail, slowCaseBegin);
    114         else {
    115             // link failure cases directly back to normal path
    116             patchBuffer.link(failureCase1, slowCaseBegin);
    117             patchBuffer.link(failureCase2, slowCaseBegin);
    118         }
     133        linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCase1, failureCase2);
    119134       
    120135        CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
     
    151166    }
    152167   
    153     // FIXME: should support prototype & chain accesses!
     168    if (structure->isDictionary())
     169        return false;
     170   
     171    // Optimize accesses on the direct prototype
     172    if (slot.slotBase() == structure->prototypeForLookup(exec)) {
     173        if (slot.cachedPropertyType() != PropertySlot::Value)
     174            return false;
     175       
     176        ASSERT(slot.slotBase().isObject());
     177       
     178        JSObject* slotBaseObject = asObject(slot.slotBase());
     179        size_t offset = slot.cachedOffset();
     180       
     181        if (slotBaseObject->structure()->isDictionary()) {
     182            slotBaseObject->flattenDictionaryObject(*globalData);
     183            offset = slotBaseObject->structure()->get(*globalData, propertyName);
     184        }
     185       
     186        ASSERT(!structure->isDictionary());
     187        ASSERT(!slotBaseObject->structure()->isDictionary());
     188       
     189        ASSERT(asObject(structure->prototypeForLookup(exec)) == slotBaseObject);
     190       
     191        GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
     192        GPRReg resultGPR = static_cast<GPRReg>(stubInfo.valueGPR);
     193        GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.u.unset.scratchGPR);
     194        bool needToRestoreScratch = false;
     195       
     196        MacroAssembler stubJit;
     197       
     198        if (scratchGPR == InvalidGPRReg) {
     199            scratchGPR = JITCodeGenerator::selectScratchGPR(baseGPR, resultGPR);
     200            stubJit.push(scratchGPR);
     201            needToRestoreScratch = true;
     202        }
     203       
     204        MacroAssembler::Jump failureCase1 = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(structure));
     205       
     206        stubJit.move(MacroAssembler::TrustedImmPtr(slotBaseObject), scratchGPR);
     207        MacroAssembler::Jump failureCase2 = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(scratchGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(slotBaseObject->structure()));
     208       
     209        if (slotBaseObject->structure()->isUsingInlineStorage())
     210            stubJit.loadPtr(MacroAssembler::Address(scratchGPR, JSObject::offsetOfInlineStorage() + offset * sizeof(JSValue)), resultGPR);
     211        else
     212            stubJit.loadPtr(slotBaseObject->addressOfPropertyAtOffset(offset), resultGPR);
     213       
     214        MacroAssembler::Jump success, fail;
     215       
     216        emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCase1, failureCase2);
     217       
     218        LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
     219       
     220        linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCase1, failureCase2);
     221       
     222        CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
     223        stubInfo.stubRoutine = entryLabel;
     224       
     225        CodeLocationLabel hotPathBegin = stubInfo.hotPathBegin;
     226        RepatchBuffer repatchBuffer(codeBlock);
     227        repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), entryLabel);
     228        repatchBuffer.relink(stubInfo.callReturnLocation, operationGetById);
     229       
     230        stubInfo.initGetByIdProto(*globalData, codeBlock->ownerExecutable(), structure, slotBaseObject->structure());
     231        return true;
     232    }
     233   
     234    // FIXME: should support chain accesses!
    154235    return false;
    155236}
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r89069 r90601  
    220220        void allocatePropertyStorage(size_t oldSize, size_t newSize);
    221221        bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
     222       
     223        void* addressOfPropertyAtOffset(size_t offset)
     224        {
     225            return static_cast<void*>(&m_propertyStorage[offset]);
     226        }
    222227
    223228        static const unsigned baseExternalStorageCapacity = 16;
Note: See TracChangeset for help on using the changeset viewer.