Commit d13cf48b authored by fpizlo@apple.com's avatar fpizlo@apple.com

Resetting a put_by_id inline cache should preserve the "isDirect" bit

https://bugs.webkit.org/show_bug.cgi?id=73375

Reviewed by Gavin Barraclough.
        
For the replace case, we can find out if it was direct by looking at the
slow call. For the transition case, we explicitly remember if it was
direct.

* bytecode/CodeBlock.cpp:
(JSC::printStructureStubInfo):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::visitWeakReferences):
* bytecode/StructureStubInfo.h:
(JSC::isPutByIdAccess):
(JSC::StructureStubInfo::initPutByIdTransition):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryCachePutByID):
* jit/JIT.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::resetPatchPutById):
(JSC::JIT::isDirectPutById):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::resetPatchPutById):
* jit/JITStubs.cpp:
(JSC::JITThunks::tryCachePutByID):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@101457 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0fe79525
2011-11-29 Filip Pizlo <fpizlo@apple.com>
Resetting a put_by_id inline cache should preserve the "isDirect" bit
https://bugs.webkit.org/show_bug.cgi?id=73375
Reviewed by Gavin Barraclough.
For the replace case, we can find out if it was direct by looking at the
slow call. For the transition case, we explicitly remember if it was
direct.
* bytecode/CodeBlock.cpp:
(JSC::printStructureStubInfo):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::visitWeakReferences):
* bytecode/StructureStubInfo.h:
(JSC::isPutByIdAccess):
(JSC::StructureStubInfo::initPutByIdTransition):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryCachePutByID):
* jit/JIT.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::resetPatchPutById):
(JSC::JIT::isDirectPutById):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::resetPatchPutById):
* jit/JITStubs.cpp:
(JSC::JITThunks::tryCachePutByID):
2011-11-29 Sam Weinig <sam@webkit.org>
Remove RetainPtr::releaseRef
......@@ -257,7 +257,8 @@ static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned i
case access_get_by_id_proto_list:
printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).utf8().data(), stubInfo.u.getByIdProtoList.listSize);
return;
case access_put_by_id_transition:
case access_put_by_id_transition_normal:
case access_put_by_id_transition_direct:
printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).utf8().data());
return;
case access_put_by_id_replace:
......
......@@ -48,7 +48,8 @@ void StructureStubInfo::deref()
case access_get_by_id_self:
case access_get_by_id_proto:
case access_get_by_id_chain:
case access_put_by_id_transition:
case access_put_by_id_transition_normal:
case access_put_by_id_transition_direct:
case access_put_by_id_replace:
case access_unset:
case access_get_by_id_generic:
......@@ -95,7 +96,8 @@ bool StructureStubInfo::visitWeakReferences()
}
break;
}
case access_put_by_id_transition:
case access_put_by_id_transition_normal:
case access_put_by_id_transition_direct:
if (!Heap::isMarked(u.putByIdTransition.previousStructure.get())
|| !Heap::isMarked(u.putByIdTransition.structure.get())
|| !Heap::isMarked(u.putByIdTransition.chain.get()))
......
......@@ -41,7 +41,8 @@ namespace JSC {
access_get_by_id_chain,
access_get_by_id_self_list,
access_get_by_id_proto_list,
access_put_by_id_transition,
access_put_by_id_transition_normal,
access_put_by_id_transition_direct,
access_put_by_id_replace,
access_unset,
access_get_by_id_generic,
......@@ -70,7 +71,8 @@ namespace JSC {
inline bool isPutByIdAccess(AccessType accessType)
{
switch (accessType) {
case access_put_by_id_transition:
case access_put_by_id_transition_normal:
case access_put_by_id_transition_direct:
case access_put_by_id_replace:
case access_put_by_id_generic:
return true;
......@@ -127,9 +129,12 @@ namespace JSC {
// PutById*
void initPutByIdTransition(JSGlobalData& globalData, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain)
void initPutByIdTransition(JSGlobalData& globalData, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain, bool isDirect)
{
accessType = access_put_by_id_transition;
if (isDirect)
accessType = access_put_by_id_transition_direct;
else
accessType = access_put_by_id_transition_normal;
u.putByIdTransition.previousStructure.set(globalData, owner, previousStructure);
u.putByIdTransition.structure.set(globalData, owner, structure);
......
......@@ -1797,7 +1797,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
break;
}
case access_put_by_id_transition: {
case access_put_by_id_transition_normal:
case access_put_by_id_transition_direct: {
Structure* previousStructure = stubInfo.u.putByIdTransition.previousStructure.get();
Structure* newStructure = stubInfo.u.putByIdTransition.structure.get();
......
......@@ -551,7 +551,7 @@ static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier
repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine.code()));
repatchBuffer.relink(stubInfo.callReturnLocation, appropriatePutByIdFunction(slot, putKind));
stubInfo.initPutByIdTransition(*globalData, codeBlock->ownerExecutable(), oldStructure, structure, prototypeChain);
stubInfo.initPutByIdTransition(*globalData, codeBlock->ownerExecutable(), oldStructure, structure, prototypeChain, putKind == Direct);
return true;
}
......
......@@ -298,6 +298,8 @@ namespace JSC {
CodeRef privateCompileCTINativeCall(JSGlobalData*, NativeFunction);
void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
static bool isDirectPutById(StructureStubInfo*);
void addSlowCase(Jump);
void addSlowCase(JumpList);
void addSlowCase();
......
......@@ -1054,7 +1054,10 @@ void JIT::resetPatchGetById(RepatchBuffer& repatchBuffer, StructureStubInfo* stu
void JIT::resetPatchPutById(RepatchBuffer& repatchBuffer, StructureStubInfo* stubInfo)
{
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id);
if (isDirectPutById(stubInfo))
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id_direct);
else
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id);
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), reinterpret_cast<void*>(-1));
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(patchOffsetPutByIdPropertyMapOffset), 0);
}
......@@ -1145,6 +1148,31 @@ void JIT::patchMethodCallProto(JSGlobalData& globalData, CodeBlock* codeBlock, M
repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_method_check_update));
}
bool JIT::isDirectPutById(StructureStubInfo* stubInfo)
{
switch (stubInfo->accessType) {
case access_put_by_id_transition_normal:
return false;
case access_put_by_id_transition_direct:
return true;
case access_put_by_id_replace:
case access_put_by_id_generic: {
void* oldCall = MacroAssembler::readCallTarget(stubInfo->callReturnLocation).executableAddress();
if (oldCall == bitwise_cast<void*>(cti_op_put_by_id_direct)
|| oldCall == bitwise_cast<void*>(cti_op_put_by_id_direct_generic)
|| oldCall == bitwise_cast<void*>(cti_op_put_by_id_direct_fail))
return true;
ASSERT(oldCall == bitwise_cast<void*>(cti_op_put_by_id)
|| oldCall == bitwise_cast<void*>(cti_op_put_by_id_generic)
|| oldCall == bitwise_cast<void*>(cti_op_put_by_id_fail));
return false;
}
default:
ASSERT_NOT_REACHED();
return false;
}
}
} // namespace JSC
#endif // ENABLE(JIT)
......@@ -1118,7 +1118,10 @@ void JIT::resetPatchGetById(RepatchBuffer& repatchBuffer, StructureStubInfo* stu
void JIT::resetPatchPutById(RepatchBuffer& repatchBuffer, StructureStubInfo* stubInfo)
{
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id);
if (isDirectPutById(stubInfo))
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id_direct);
else
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id);
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), reinterpret_cast<void*>(-1));
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(patchOffsetPutByIdPropertyMapOffset1), 0);
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(patchOffsetPutByIdPropertyMapOffset2), 0);
......
......@@ -852,7 +852,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
normalizePrototypeChain(callFrame, baseCell);
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
stubInfo->initPutByIdTransition(callFrame->globalData(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain);
stubInfo->initPutByIdTransition(callFrame->globalData(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain, direct);
JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
return;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment