diff options
author | Steve Block <steveblock@google.com> | 2010-04-27 16:31:00 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:12 +0100 |
commit | dcc8cf2e65d1aa555cce12431a16547e66b469ee (patch) | |
tree | 92a8d65cd5383bca9749f5327fb5e440563926e6 /JavaScriptCore/jit/JITPropertyAccess.cpp | |
parent | ccac38a6b48843126402088a309597e682f40fe6 (diff) | |
download | external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2 |
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'JavaScriptCore/jit/JITPropertyAccess.cpp')
-rw-r--r-- | JavaScriptCore/jit/JITPropertyAccess.cpp | 161 |
1 files changed, 144 insertions, 17 deletions
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp index 151bb03..3399f03 100644 --- a/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -32,6 +32,7 @@ #if ENABLE(JIT) #include "CodeBlock.h" +#include "GetterSetter.h" #include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" @@ -695,7 +696,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail)); } -void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) +void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) { // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is // referencing the prototype object - let's speculatively load it's table nice and early!) @@ -713,11 +714,28 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); #endif - // Checks out okay! - getDirectOffset - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); - + bool needsStubLink = false; + + // Checks out okay! + if (slot.cachedPropertyType() == PropertySlot::Getter) { + needsStubLink = true; + compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); + stubCall.addArgument(regT1); + stubCall.addArgument(regT0); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else if (slot.cachedPropertyType() == PropertySlot::Custom) { + needsStubLink = true; + JITStubCall stubCall(this, cti_op_get_by_id_custom_stub); + stubCall.addArgument(ImmPtr(protoObject)); + stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress())); + stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident))); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); - LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); // Use the patch information to link the failure cases back to the original slow case routine. @@ -728,6 +746,12 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); + if (needsStubLink) { + for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { + if (iter->to) + patchBuffer.link(iter->from, FunctionPtr(iter->to)); + } + } // Track the stub we have created so that it will be deleted later. CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum(); stubInfo->stubRoutine = entryLabel; @@ -741,14 +765,43 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); } -void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset) +void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset) { Jump failureCase = checkStructure(regT0, structure); - compileGetDirectOffset(regT0, regT0, structure, cachedOffset); + bool needsStubLink = false; + if (slot.cachedPropertyType() == PropertySlot::Getter) { + needsStubLink = true; + if (!structure->isUsingInlineStorage()) { + move(regT0, regT1); + compileGetDirectOffset(regT1, regT1, structure, cachedOffset); + } else + compileGetDirectOffset(regT0, regT1, structure, cachedOffset); + JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); + stubCall.addArgument(regT1); + stubCall.addArgument(regT0); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else if (slot.cachedPropertyType() == PropertySlot::Custom) { + needsStubLink = true; + JITStubCall stubCall(this, cti_op_get_by_id_custom_stub); + stubCall.addArgument(regT0); + stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress())); + stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident))); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else + compileGetDirectOffset(regT0, regT0, structure, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + if (needsStubLink) { + for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { + if (iter->to) + patchBuffer.link(iter->from, FunctionPtr(iter->to)); + } + } + // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine; if (!lastProtoBegin) @@ -770,7 +823,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic repatchBuffer.relink(jumpLocation, entryLabel); } -void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame) +void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame) { // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is // referencing the prototype object - let's speculatively load it's table nice and early!) @@ -788,13 +841,38 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); #endif - // Checks out okay! - getDirectOffset - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + // Checks out okay! + bool needsStubLink = false; + if (slot.cachedPropertyType() == PropertySlot::Getter) { + needsStubLink = true; + compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); + stubCall.addArgument(regT1); + stubCall.addArgument(regT0); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else if (slot.cachedPropertyType() == PropertySlot::Custom) { + needsStubLink = true; + JITStubCall stubCall(this, cti_op_get_by_id_custom_stub); + stubCall.addArgument(ImmPtr(protoObject)); + stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress())); + stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident))); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + if (needsStubLink) { + for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { + if (iter->to) + patchBuffer.link(iter->from, FunctionPtr(iter->to)); + } + } + // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; patchBuffer.link(failureCases1, lastProtoBegin); @@ -815,10 +893,9 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi repatchBuffer.relink(jumpLocation, entryLabel); } -void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame) +void 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) { ASSERT(count); - JumpList bucketsOfFail; // Check eax is an object of the right Structure. @@ -842,11 +919,36 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi #endif } ASSERT(protoObject); - - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + + bool needsStubLink = false; + if (slot.cachedPropertyType() == PropertySlot::Getter) { + needsStubLink = true; + compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); + stubCall.addArgument(regT1); + stubCall.addArgument(regT0); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else if (slot.cachedPropertyType() == PropertySlot::Custom) { + needsStubLink = true; + JITStubCall stubCall(this, cti_op_get_by_id_custom_stub); + stubCall.addArgument(ImmPtr(protoObject)); + stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress())); + stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident))); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + + if (needsStubLink) { + for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { + if (iter->to) + patchBuffer.link(iter->from, FunctionPtr(iter->to)); + } + } // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; @@ -869,10 +971,10 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi repatchBuffer.relink(jumpLocation, entryLabel); } -void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) +void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) { ASSERT(count); - + JumpList bucketsOfFail; // Check eax is an object of the right Structure. @@ -896,11 +998,36 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str } ASSERT(protoObject); - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + bool needsStubLink = false; + if (slot.cachedPropertyType() == PropertySlot::Getter) { + needsStubLink = true; + compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); + stubCall.addArgument(regT1); + stubCall.addArgument(regT0); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else if (slot.cachedPropertyType() == PropertySlot::Custom) { + needsStubLink = true; + JITStubCall stubCall(this, cti_op_get_by_id_custom_stub); + stubCall.addArgument(ImmPtr(protoObject)); + stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress())); + stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident))); + stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); + stubCall.call(); + } else + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); + if (needsStubLink) { + for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { + if (iter->to) + patchBuffer.link(iter->from, FunctionPtr(iter->to)); + } + } + // Use the patch information to link the failure cases back to the original slow case routine. patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall)); |