Title: [90950] trunk/Source/_javascript_Core
Revision
90950
Author
[email protected]
Date
2011-07-13 14:44:42 -0700 (Wed, 13 Jul 2011)

Log Message

DFG JIT does not implement prototype chain or list caching for get_by_id.
https://bugs.webkit.org/show_bug.cgi?id=64147

Patch by Filip Pizlo <[email protected]> on 2011-07-13
Reviewed by Gavin Barraclough.

This implements unified support for prototype caching, prototype chain
caching, and polymorphic (i.e. list) prototype and prototype chain
caching.  This is done by creating common code for emitting prototype
or chain access stubs, and having it factored out into
generateProtoChainAccessStub().  This function is called by
tryCacheGetByID once the latter determines that some form of prototype
access caching is necessary (i.e. the slot being accessed is not on the
base value but on some other object).

Direct prototype list, and prototype chain list, caching is implemented by
linking the slow path to operationGetByIdProtoBuildList(), which uses the
same helper function (generateProtoChainAccessStub()) as tryCacheGetByID.

This change required ensuring that the value in the scratchGPR field in
StructureStubInfo is preserved even after the stub info is in the
chain, or proto_list, states.  Hence scratchGPR was moved out of the union
and into the top-level of StructureStubInfo.

* bytecode/StructureStubInfo.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGRepatch.cpp:
(JSC::DFG::emitRestoreScratch):
(JSC::DFG::linkRestoreScratch):
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDProtoList):
(JSC::DFG::dfgBuildGetByIDProtoList):
(JSC::DFG::tryCachePutByID):
* dfg/DFGRepatch.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (90949 => 90950)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-13 21:44:42 UTC (rev 90950)
@@ -1,3 +1,43 @@
+2011-07-13  Filip Pizlo  <[email protected]>
+
+        DFG JIT does not implement prototype chain or list caching for get_by_id.
+        https://bugs.webkit.org/show_bug.cgi?id=64147
+
+        Reviewed by Gavin Barraclough.
+        
+        This implements unified support for prototype caching, prototype chain
+        caching, and polymorphic (i.e. list) prototype and prototype chain
+        caching.  This is done by creating common code for emitting prototype
+        or chain access stubs, and having it factored out into
+        generateProtoChainAccessStub().  This function is called by
+        tryCacheGetByID once the latter determines that some form of prototype
+        access caching is necessary (i.e. the slot being accessed is not on the
+        base value but on some other object).
+        
+        Direct prototype list, and prototype chain list, caching is implemented by
+        linking the slow path to operationGetByIdProtoBuildList(), which uses the
+        same helper function (generateProtoChainAccessStub()) as tryCacheGetByID.
+        
+        This change required ensuring that the value in the scratchGPR field in
+        StructureStubInfo is preserved even after the stub info is in the
+        chain, or proto_list, states.  Hence scratchGPR was moved out of the union
+        and into the top-level of StructureStubInfo.
+        
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileFunction):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGRepatch.cpp:
+        (JSC::DFG::emitRestoreScratch):
+        (JSC::DFG::linkRestoreScratch):
+        (JSC::DFG::generateProtoChainAccessStub):
+        (JSC::DFG::tryCacheGetByID):
+        (JSC::DFG::tryBuildGetByIDProtoList):
+        (JSC::DFG::dfgBuildGetByIDProtoList):
+        (JSC::DFG::tryCachePutByID):
+        * dfg/DFGRepatch.h:
+
 2011-07-12  Brent Fulgham  <[email protected]>
 
         Standardize WinCairo conditionalized code under PLATFORM macro.

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (90949 => 90950)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2011-07-13 21:44:42 UTC (rev 90950)
@@ -133,6 +133,7 @@
 #if ENABLE(DFG_JIT)
         int8_t baseGPR;
         int8_t valueGPR;
+        int8_t scratchGPR;
         int8_t deltaCallToDone;
         int8_t deltaCallToStructCheck;
         int8_t deltaCallToSlowCase;
@@ -142,7 +143,6 @@
             struct {
                 int8_t deltaCheckImmToCall;
                 int8_t deltaCallToLoadOrStore;
-                int8_t scratchGPR;
             } unset;
             struct {
                 WriteBarrierBase<Structure> baseObjectStructure;

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (90949 => 90950)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-07-13 21:44:42 UTC (rev 90950)
@@ -398,7 +398,7 @@
         info.deltaCallToDone = m_propertyAccesses[i].m_deltaCallToDone;
         info.baseGPR = m_propertyAccesses[i].m_baseGPR;
         info.valueGPR = m_propertyAccesses[i].m_valueGPR;
-        info.u.unset.scratchGPR = m_propertyAccesses[i].m_scratchGPR;
+        info.scratchGPR = m_propertyAccesses[i].m_scratchGPR;
     }
     
     m_codeBlock->setNumberOfCallLinkInfos(m_jsCalls.size());

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (90949 => 90950)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-07-13 21:44:42 UTC (rev 90950)
@@ -259,6 +259,20 @@
     return JSValue::encode(result);
 }
 
+EncodedJSValue operationGetByIdProtoBuildListWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdProtoBuildList);
+EncodedJSValue operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
+{
+    JSValue baseValue = JSValue::decode(encodedBase);
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(exec, *propertyName, slot);
+
+    StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+    dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
+
+    return JSValue::encode(result);
+}
+
 EncodedJSValue operationGetByIdOptimizeWithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr);
 FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(operationGetByIdOptimize);
 EncodedJSValue operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (90949 => 90950)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2011-07-13 21:44:42 UTC (rev 90950)
@@ -61,6 +61,7 @@
 EncodedJSValue operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty);
 EncodedJSValue operationGetById(ExecState*, EncodedJSValue encodedBase, Identifier*);
 EncodedJSValue operationGetByIdBuildList(ExecState*, EncodedJSValue encodedBase, Identifier*);
+EncodedJSValue operationGetByIdProtoBuildList(ExecState*, EncodedJSValue encodedBase, Identifier*);
 EncodedJSValue operationGetByIdOptimize(ExecState*, EncodedJSValue encodedBase, Identifier*);
 EncodedJSValue operationGetMethodOptimize(ExecState*, EncodedJSValue encodedBase, Identifier*);
 EncodedJSValue operationInstanceOf(ExecState*, EncodedJSValue value, EncodedJSValue base, EncodedJSValue prototype);

Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (90949 => 90950)


--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp	2011-07-13 21:44:42 UTC (rev 90950)
@@ -56,6 +56,90 @@
         repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.u.unset.deltaCallToLoadOrStore), sizeof(JSValue) * offset);
 }
 
+static void emitRestoreScratch(MacroAssembler& stubJit, bool needToRestoreScratch, GPRReg scratchGPR, MacroAssembler::Jump& success, MacroAssembler::Jump& fail, MacroAssembler::JumpList failureCases)
+{
+    if (needToRestoreScratch) {
+        stubJit.pop(scratchGPR);
+        
+        success = stubJit.jump();
+        
+        // link failure cases here, so we can pop scratchGPR, and then jump back.
+        failureCases.link(&stubJit);
+        
+        stubJit.pop(scratchGPR);
+        
+        fail = stubJit.jump();
+        return;
+    }
+    
+    success = stubJit.jump();
+}
+
+static void linkRestoreScratch(LinkBuffer& patchBuffer, bool needToRestoreScratch, MacroAssembler::Jump success, MacroAssembler::Jump fail, MacroAssembler::JumpList failureCases, CodeLocationLabel successLabel, CodeLocationLabel slowCaseBegin)
+{
+    patchBuffer.link(success, successLabel);
+        
+    if (needToRestoreScratch) {
+        patchBuffer.link(fail, slowCaseBegin);
+        return;
+    }
+    
+    // link failure cases directly back to normal path
+    patchBuffer.link(failureCases, slowCaseBegin);
+}
+
+static void linkRestoreScratch(LinkBuffer& patchBuffer, bool needToRestoreScratch, StructureStubInfo& stubInfo, MacroAssembler::Jump success, MacroAssembler::Jump fail, MacroAssembler::JumpList failureCases)
+{
+    linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase));
+}
+
+static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stubInfo, StructureChain* chain, size_t count, size_t offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, CodeLocationLabel& stubRoutine)
+{
+    JSGlobalData* globalData = &exec->globalData();
+
+    MacroAssembler stubJit;
+        
+    GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
+    GPRReg resultGPR = static_cast<GPRReg>(stubInfo.valueGPR);
+    GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.scratchGPR);
+    bool needToRestoreScratch = false;
+    
+    if (scratchGPR == InvalidGPRReg) {
+        scratchGPR = JITCodeGenerator::selectScratchGPR(baseGPR, resultGPR);
+        stubJit.push(scratchGPR);
+        needToRestoreScratch = true;
+    }
+    
+    MacroAssembler::JumpList failureCases;
+    
+    failureCases.append(stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(structure)));
+    
+    Structure* currStructure = structure;
+    WriteBarrier<Structure>* it = chain->head();
+    JSObject* protoObject = 0;
+    for (unsigned i = 0; i < count; ++i, ++it) {
+        protoObject = asObject(currStructure->prototypeForLookup(exec));
+        stubJit.move(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR);
+        failureCases.append(stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(scratchGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(protoObject->structure())));
+        currStructure = it->get();
+    }
+    
+    if (protoObject->structure()->isUsingInlineStorage())
+        stubJit.loadPtr(MacroAssembler::Address(scratchGPR, JSObject::offsetOfInlineStorage() + offset * sizeof(JSValue)), resultGPR);
+    else
+        stubJit.loadPtr(protoObject->addressOfPropertyAtOffset(offset), resultGPR);
+        
+    MacroAssembler::Jump success, fail;
+    
+    emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
+    
+    LinkBuffer patchBuffer(*globalData, &stubJit, exec->codeBlock()->executablePool());
+    
+    linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
+    
+    stubRoutine = patchBuffer.finalizeCodeAddendum();
+}
+
 static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
 {
     // FIXME: Write a test that proves we need to check for recursion here just
@@ -67,7 +151,7 @@
     if (isJSArray(globalData, baseValue) && propertyName == exec->propertyNames().length) {
         GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
         GPRReg resultGPR = static_cast<GPRReg>(stubInfo.valueGPR);
-        GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.u.unset.scratchGPR);
+        GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.scratchGPR);
         bool needToRestoreScratch = false;
         
         MacroAssembler stubJit;
@@ -78,49 +162,27 @@
             needToRestoreScratch = true;
         }
         
-        MacroAssembler::Jump failureCase1 = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(globalData->jsArrayVPtr));
+        MacroAssembler::JumpList failureCases;
         
+        failureCases.append(stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(globalData->jsArrayVPtr)));
+        
         stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), scratchGPR);
         stubJit.load32(MacroAssembler::Address(scratchGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), scratchGPR);
-        MacroAssembler::Jump failureCase2 = stubJit.branch32(MacroAssembler::LessThan, scratchGPR, MacroAssembler::TrustedImm32(0));
+        failureCases.append(stubJit.branch32(MacroAssembler::LessThan, scratchGPR, MacroAssembler::TrustedImm32(0)));
         
         stubJit.orPtr(GPRInfo::tagTypeNumberRegister, scratchGPR, resultGPR);
 
         MacroAssembler::Jump success, fail;
         
-        if (needToRestoreScratch) {
-            stubJit.pop(scratchGPR);
-            
-            success = stubJit.jump();
-            
-            // link failure cases here, so we can pop scratchGPR, and then jump back.
-            failureCase1.link(&stubJit);
-            failureCase2.link(&stubJit);
-            
-            stubJit.pop(scratchGPR);
-            
-            fail = stubJit.jump();
-        } else
-            success = stubJit.jump();
+        emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
         
         LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
         
-        CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase);
+        linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
         
-        patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
-        
-        if (needToRestoreScratch)
-            patchBuffer.link(fail, slowCaseBegin);
-        else {
-            // link failure cases directly back to normal path
-            patchBuffer.link(failureCase1, slowCaseBegin);
-            patchBuffer.link(failureCase2, slowCaseBegin);
-        }
-        
         CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
         stubInfo.stubRoutine = entryLabel;
         
-        CodeLocationLabel hotPathBegin = stubInfo.hotPathBegin;
         RepatchBuffer repatchBuffer(codeBlock);
         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), entryLabel);
         repatchBuffer.relink(stubInfo.callReturnLocation, operationGetById);
@@ -137,7 +199,7 @@
     Structure* structure = baseCell->structure();
     if (!slot.isCacheable())
         return false;
-    if (structure->isUncacheableDictionary())
+    if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching())
         return false;
 
     // Optimize self access.
@@ -150,8 +212,30 @@
         return true;
     }
     
-    // FIXME: should support prototype & chain accesses!
-    return false;
+    if (structure->isDictionary())
+        return false;
+    
+    // FIXME: optimize getters and setters
+    if (slot.cachedPropertyType() != PropertySlot::Value)
+        return false;
+    
+    size_t offset = slot.cachedOffset();
+    size_t count = normalizePrototypeChain(exec, baseValue, slot.slotBase(), propertyName, offset);
+    if (!count)
+        return false;
+
+    StructureChain* prototypeChain = structure->prototypeChain(exec);
+    
+    ASSERT(slot.slotBase().isObject());
+    
+    generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase), stubInfo.stubRoutine);
+    
+    RepatchBuffer repatchBuffer(codeBlock);
+    repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), stubInfo.stubRoutine);
+    repatchBuffer.relink(stubInfo.callReturnLocation, operationGetByIdProtoBuildList);
+    
+    stubInfo.initGetByIdChain(*globalData, codeBlock->ownerExecutable(), structure, prototypeChain);
+    return true;
 }
 
 void dfgRepatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
@@ -296,6 +380,72 @@
         dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);
 }
 
+static bool tryBuildGetByIDProtoList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
+{
+    if (!baseValue.isCell()
+        || !slot.isCacheable()
+        || baseValue.asCell()->structure()->isDictionary()
+        || baseValue.asCell()->structure()->typeInfo().prohibitsPropertyCaching()
+        || slot.slotBase() == baseValue
+        || slot.cachedPropertyType() != PropertySlot::Value)
+        return false;
+    
+    ASSERT(slot.slotBase().isObject());
+    
+    size_t offset = slot.cachedOffset();
+    size_t count = normalizePrototypeChain(exec, baseValue, slot.slotBase(), propertyName, offset);
+    if (!count)
+        return false;
+
+    Structure* structure = baseValue.asCell()->structure();
+    StructureChain* prototypeChain = structure->prototypeChain(exec);
+    CodeBlock* codeBlock = exec->codeBlock();
+    JSGlobalData* globalData = &exec->globalData();
+    
+    PolymorphicAccessStructureList* polymorphicStructureList;
+    int listIndex = 1;
+    
+    if (stubInfo.accessType == access_get_by_id_chain) {
+        ASSERT(!!stubInfo.stubRoutine);
+        polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get());
+        stubInfo.stubRoutine = CodeLocationLabel();
+        stubInfo.initGetByIdProtoList(polymorphicStructureList, 1);
+    } else {
+        ASSERT(stubInfo.accessType = access_get_by_id_proto_list);
+        polymorphicStructureList = stubInfo.u.getByIdProtoList.structureList;
+        listIndex = stubInfo.u.getByIdProtoList.listSize;
+    }
+    
+    if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
+        stubInfo.u.getByIdProtoList.listSize++;
+        
+        CodeLocationLabel lastProtoBegin = polymorphicStructureList->list[listIndex - 1].stubRoutine;
+        ASSERT(!!lastProtoBegin);
+
+        CodeLocationLabel entryLabel;
+        
+        generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone), lastProtoBegin, entryLabel);
+        
+        polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), entryLabel, structure);
+        
+        CodeLocationJump jumpLocation = stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck);
+        RepatchBuffer repatchBuffer(codeBlock);
+        repatchBuffer.relink(jumpLocation, entryLabel);
+        
+        if (listIndex < (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+            return true;
+    }
+    
+    return false;
+}
+
+void dfgBuildGetByIDProtoList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
+{
+    bool dontChangeCall = tryBuildGetByIDProtoList(exec, baseValue, propertyName, slot, stubInfo);
+    if (!dontChangeCall)
+        dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);
+}
+
 static V_DFGOperation_EJJI appropriatePutByIdFunction(const PutPropertySlot &slot, PutKind putKind)
 {
     if (slot.isStrictMode()) {
@@ -351,7 +501,7 @@
             
             GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
             GPRReg valueGPR = static_cast<GPRReg>(stubInfo.valueGPR);
-            GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.u.unset.scratchGPR);
+            GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.scratchGPR);
             bool needToRestoreScratch = false;
             
             ASSERT(scratchGPR != baseGPR);
@@ -408,7 +558,6 @@
             CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
             stubInfo.stubRoutine = entryLabel;
             
-            CodeLocationLabel hotPathBegin = stubInfo.hotPathBegin;
             RepatchBuffer repatchBuffer(codeBlock);
             repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), entryLabel);
             repatchBuffer.relink(stubInfo.callReturnLocation, appropriatePutByIdFunction(slot, putKind));

Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.h (90949 => 90950)


--- trunk/Source/_javascript_Core/dfg/DFGRepatch.h	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.h	2011-07-13 21:44:42 UTC (rev 90950)
@@ -36,6 +36,7 @@
 void dfgRepatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
 void dfgRepatchGetMethod(ExecState*, JSValue, const Identifier&, const PropertySlot&, MethodCallLinkInfo&);
 void dfgBuildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
+void dfgBuildGetByIDProtoList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
 void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
 void dfgLinkFor(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr, CodeSpecializationKind);
 

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (90949 => 90950)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2011-07-13 21:44:29 UTC (rev 90949)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2011-07-13 21:44:42 UTC (rev 90950)
@@ -220,6 +220,11 @@
         void allocatePropertyStorage(size_t oldSize, size_t newSize);
         bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
 
+        void* addressOfPropertyAtOffset(size_t offset)
+        {
+            return static_cast<void*>(&m_propertyStorage[offset]);
+        }
+
         static const unsigned baseExternalStorageCapacity = 16;
 
         void flattenDictionaryObject(JSGlobalData& globalData)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to