Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (101456 => 101457)
--- trunk/Source/_javascript_Core/ChangeLog 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-11-30 08:44:12 UTC (rev 101457)
@@ -1,3 +1,35 @@
+2011-11-29 Filip Pizlo <fpi...@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 <s...@webkit.org>
Remove RetainPtr::releaseRef
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -257,7 +257,8 @@
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:
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -48,7 +48,8 @@
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 @@
}
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()))
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (101456 => 101457)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2011-11-30 08:44:12 UTC (rev 101457)
@@ -41,7 +41,8 @@
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 @@
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 @@
// 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);
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -1797,7 +1797,8 @@
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();
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -551,7 +551,7 @@
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;
}
Modified: trunk/Source/_javascript_Core/jit/JIT.h (101456 => 101457)
--- trunk/Source/_javascript_Core/jit/JIT.h 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2011-11-30 08:44:12 UTC (rev 101457)
@@ -298,6 +298,8 @@
CodeRef privateCompileCTINativeCall(JSGlobalData*, NativeFunction);
void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
+ static bool isDirectPutById(StructureStubInfo*);
+
void addSlowCase(Jump);
void addSlowCase(JumpList);
void addSlowCase();
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -1054,7 +1054,10 @@
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 @@
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)
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -1118,7 +1118,10 @@
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);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (101456 => 101457)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-11-30 08:41:19 UTC (rev 101456)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-11-30 08:44:12 UTC (rev 101457)
@@ -852,7 +852,7 @@
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;
}