Title: [101457] trunk/Source/_javascript_Core
Revision
101457
Author
fpi...@apple.com
Date
2011-11-30 00:44:12 -0800 (Wed, 30 Nov 2011)

Log Message

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):

Modified Paths

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;
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to