Ignore:
Timestamp:
Mar 4, 2010, 5:33:54 PM (15 years ago)
Author:
[email protected]
Message:

2010-03-03 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Allow static property getters to interact with JSCs caching
https://bugs.webkit.org/show_bug.cgi?id=35716

Add new opcodes for handling cached lookup of static value getters.
More or less the same as with JS getters, all that changes is that
instead of calling through a JSFunction we always know that we have
a C function to call.

For the patching routines in the JIT we now need to pass a few
new parameters to allow us to pass enough information to the stub
function to allow us to call the C function correctly. Logically
this shouldn't actually be necessary as all of these functions ignore
the identifier, but removing the ident parameter would require
somewhat involved changes to the way we implement getOwnPropertySlot,
etc.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::derefStructures): (JSC::CodeBlock::refStructures):
  • bytecode/Instruction.h: (JSC::Instruction::Instruction): (JSC::Instruction::):
  • bytecode/Opcode.h:
  • interpreter/Interpreter.cpp: (JSC::Interpreter::tryCacheGetByID): (JSC::Interpreter::privateExecute):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass):
  • jit/JIT.h: (JSC::JIT::compileGetByIdProto): (JSC::JIT::compileGetByIdSelfList): (JSC::JIT::compileGetByIdProtoList): (JSC::JIT::compileGetByIdChainList): (JSC::JIT::compileGetByIdChain):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITPropertyAccess32_64.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITStubs.cpp: (JSC::JITThunks::tryCacheGetByID): (JSC::DEFINE_STUB_FUNCTION):
  • jit/JITStubs.h: (JSC::):
  • runtime/JSFunction.cpp: (JSC::JSFunction::getOwnPropertySlot):
  • runtime/Lookup.h: (JSC::getStaticPropertySlot): (JSC::getStaticValueSlot):
  • runtime/PropertySlot.h: (JSC::PropertySlot::): (JSC::PropertySlot::PropertySlot): (JSC::PropertySlot::cachedPropertyType): (JSC::PropertySlot::isCacheable): (JSC::PropertySlot::isCacheableValue): (JSC::PropertySlot::setValueSlot): (JSC::PropertySlot::setCacheableCustom): (JSC::PropertySlot::setGetterSlot): (JSC::PropertySlot::setCacheableGetterSlot): (JSC::PropertySlot::clearOffset): (JSC::PropertySlot::customGetter):

2010-03-03 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Allow static property getters to interact with JSCs caching
https://bugs.webkit.org/show_bug.cgi?id=35716

Add tests to ensure nothing horrifying happens to static property
getters if they're in a path where we end up caching lookups.

  • fast/js/pic/cached-named-property-getter-expected.txt: Added.
  • fast/js/pic/cached-named-property-getter.html: Added.

2010-03-03 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Allow static property getters to interact with JSCs caching
https://bugs.webkit.org/show_bug.cgi?id=35716

Update the obviously safe getters to allow caching

Test: fast/js/pic/cached-named-property-getter.html

  • bridge/runtime_array.cpp: (JSC::RuntimeArray::getOwnPropertySlot):
  • bridge/runtime_method.cpp: (JSC::RuntimeMethod::getOwnPropertySlot):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITPropertyAccess.cpp

    r55198 r55564  
    697697}
    698698
    699 void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, bool isGetter, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
     699void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
    700700{
    701701    // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
     
    715715#endif
    716716
     717    bool needsStubLink = false;
     718   
    717719    // Checks out okay!
    718     if (isGetter) {
     720    if (slot.cachedPropertyType() == PropertySlot::Getter) {
     721        needsStubLink = true;
    719722        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
    720723        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
     
    723726        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
    724727        stubCall.call();
     728    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
     729        needsStubLink = true;
     730        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
     731        stubCall.addArgument(ImmPtr(protoObject));
     732        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
     733        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
     734        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
     735        stubCall.call();
    725736    } else
    726737        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     
    736747    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
    737748
    738     if (isGetter) {
     749    if (needsStubLink) {
    739750        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
    740751            if (iter->to)
     
    755766}
    756767
    757 void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, bool isGetter, size_t cachedOffset)
     768void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
    758769{
    759770    Jump failureCase = checkStructure(regT0, structure);
    760     if (isGetter) {
     771    bool needsStubLink = false;
     772    if (slot.cachedPropertyType() == PropertySlot::Getter) {
     773        needsStubLink = true;
    761774        if (!structure->isUsingInlineStorage()) {
    762775            move(regT0, regT1);
     
    769782        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
    770783        stubCall.call();
     784    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
     785        needsStubLink = true;
     786        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
     787        stubCall.addArgument(regT0);
     788        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
     789        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
     790        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
     791        stubCall.call();
    771792    } else
    772793        compileGetDirectOffset(regT0, regT0, structure, cachedOffset);
     
    775796    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
    776797
    777     if (isGetter) {
     798    if (needsStubLink) {
    778799        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
    779800            if (iter->to)
     
    803824}
    804825
    805 void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, bool isGetter, size_t cachedOffset, CallFrame* callFrame)
     826void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
    806827{
    807828    // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
     
    822843
    823844    // Checks out okay!
    824     if (isGetter) {
     845    bool needsStubLink = false;
     846    if (slot.cachedPropertyType() == PropertySlot::Getter) {
     847        needsStubLink = true;
    825848        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
    826849        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
     
    829852        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
    830853        stubCall.call();
     854    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
     855        needsStubLink = true;
     856        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
     857        stubCall.addArgument(ImmPtr(protoObject));
     858        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
     859        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
     860        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
     861        stubCall.call();
    831862    } else
    832863        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     
    836867    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
    837868
    838     if (isGetter) {
     869    if (needsStubLink) {
    839870        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
    840871            if (iter->to)
     
    863894}
    864895
    865 void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, bool isGetter, size_t cachedOffset, CallFrame* callFrame)
     896void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
    866897{
    867898    ASSERT(count);
     
    890921    ASSERT(protoObject);
    891922   
    892     if (isGetter) {
     923    bool needsStubLink = false;
     924    if (slot.cachedPropertyType() == PropertySlot::Getter) {
     925        needsStubLink = true;
    893926        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
    894927        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
     
    897930        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
    898931        stubCall.call();
     932    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
     933        needsStubLink = true;
     934        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
     935        stubCall.addArgument(ImmPtr(protoObject));
     936        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
     937        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
     938        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
     939        stubCall.call();
    899940    } else
    900941        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     
    903944    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
    904945   
    905     if (isGetter) {
     946    if (needsStubLink) {
    906947        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
    907948            if (iter->to)
     
    931972}
    932973
    933 void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, bool isGetter, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
     974void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
    934975{
    935976    ASSERT(count);
     
    957998    }
    958999    ASSERT(protoObject);
    959    
    960     if (isGetter) {
     1000
     1001    bool needsStubLink = false;
     1002    if (slot.cachedPropertyType() == PropertySlot::Getter) {
     1003        needsStubLink = true;
    9611004        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
    9621005        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
     
    9651008        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
    9661009        stubCall.call();
     1010    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
     1011        needsStubLink = true;
     1012        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
     1013        stubCall.addArgument(ImmPtr(protoObject));
     1014        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
     1015        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
     1016        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
     1017        stubCall.call();
    9671018    } else
    9681019        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     
    9711022    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
    9721023
    973     if (isGetter) {
     1024    if (needsStubLink) {
    9741025        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
    9751026            if (iter->to)
Note: See TracChangeset for help on using the changeset viewer.