Title: [189323] trunk/Source/_javascript_Core
Revision
189323
Author
[email protected]
Date
2015-09-03 17:02:29 -0700 (Thu, 03 Sep 2015)

Log Message

StructureStubInfo should be able to reset itself without going through CodeBlock
https://bugs.webkit.org/show_bug.cgi?id=148743

Reviewed by Geoffrey Garen.

We had some resetStub...() methods in CodeBlock that didn't really do anything that
StructureStubInfo couldn't do by itself. It makes sense for the functionality to reset a
stub to be in the stub class, not in CodeBlock.

It's still true that:

- In order to mess with a StructureStubInfo, you either have to be in GC or you have to
  be holding the owning CodeBlock's lock.

- StructureStubInfo doesn't remember which CodeBlock owns it (to save space), and all
  of the callers of StructureStubInfo methods know which CodeBlock own it. So, many stub
  methods take CodeBlock* as an argument.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::addCallLinkInfo):
(JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
(JSC::CodeBlock::resetStub): Deleted.
(JSC::CodeBlock::resetStubInternal): Deleted.
(JSC::CodeBlock::resetStubDuringGCInternal): Deleted.
* bytecode/CodeBlock.h:
* bytecode/StructureStubClearingWatchpoint.cpp:
(JSC::StructureStubClearingWatchpoint::fireInternal):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::reset):
(JSC::StructureStubInfo::visitWeakReferences):
* bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::initInList):
(JSC::StructureStubInfo::seenOnce):
(JSC::StructureStubInfo::reset): Deleted.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (189322 => 189323)


--- trunk/Source/_javascript_Core/ChangeLog	2015-09-03 23:53:33 UTC (rev 189322)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-09-04 00:02:29 UTC (rev 189323)
@@ -1,3 +1,42 @@
+2015-09-03  Filip Pizlo  <[email protected]>
+
+        StructureStubInfo should be able to reset itself without going through CodeBlock
+        https://bugs.webkit.org/show_bug.cgi?id=148743
+
+        Reviewed by Geoffrey Garen.
+
+        We had some resetStub...() methods in CodeBlock that didn't really do anything that
+        StructureStubInfo couldn't do by itself. It makes sense for the functionality to reset a
+        stub to be in the stub class, not in CodeBlock.
+
+        It's still true that:
+
+        - In order to mess with a StructureStubInfo, you either have to be in GC or you have to
+          be holding the owning CodeBlock's lock.
+
+        - StructureStubInfo doesn't remember which CodeBlock owns it (to save space), and all
+          of the callers of StructureStubInfo methods know which CodeBlock own it. So, many stub
+          methods take CodeBlock* as an argument.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::addCallLinkInfo):
+        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
+        (JSC::CodeBlock::resetStub): Deleted.
+        (JSC::CodeBlock::resetStubInternal): Deleted.
+        (JSC::CodeBlock::resetStubDuringGCInternal): Deleted.
+        * bytecode/CodeBlock.h:
+        * bytecode/StructureStubClearingWatchpoint.cpp:
+        (JSC::StructureStubClearingWatchpoint::fireInternal):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::deref):
+        (JSC::StructureStubInfo::reset):
+        (JSC::StructureStubInfo::visitWeakReferences):
+        * bytecode/StructureStubInfo.h:
+        (JSC::StructureStubInfo::initInList):
+        (JSC::StructureStubInfo::seenOnce):
+        (JSC::StructureStubInfo::reset): Deleted.
+
 2015-09-03  Sukolsak Sakshuwong  <[email protected]>
 
         Implement some arithmetic instructions in WebAssembly

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (189322 => 189323)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2015-09-03 23:53:33 UTC (rev 189322)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2015-09-04 00:02:29 UTC (rev 189323)
@@ -2690,11 +2690,7 @@
 
         for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
             StructureStubInfo& stubInfo = **iter;
-            
-            if (stubInfo.visitWeakReferences(*vm()))
-                continue;
-            
-            resetStubDuringGCInternal(stubInfo);
+            stubInfo.visitWeakReferences(this);
         }
     }
 #endif
@@ -2774,46 +2770,6 @@
     return m_callLinkInfos.add();
 }
 
-void CodeBlock::resetStub(StructureStubInfo& stubInfo)
-{
-    if (stubInfo.accessType == access_unset)
-        return;
-    
-    ConcurrentJITLocker locker(m_lock);
-    
-    resetStubInternal(stubInfo);
-}
-
-void CodeBlock::resetStubInternal(StructureStubInfo& stubInfo)
-{
-    AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
-    
-    if (Options::verboseOSR()) {
-        // This can be called from GC destructor calls, so we don't try to do a full dump
-        // of the CodeBlock.
-        dataLog("Clearing structure cache (kind ", static_cast<int>(stubInfo.accessType), ") in ", RawPointer(this), ".\n");
-    }
-    
-    RELEASE_ASSERT(JITCode::isJIT(jitType()));
-    
-    if (isGetByIdAccess(accessType))
-        resetGetByID(this, stubInfo);
-    else if (isPutByIdAccess(accessType))
-        resetPutByID(this, stubInfo);
-    else {
-        RELEASE_ASSERT(isInAccess(accessType));
-        resetIn(this, stubInfo);
-    }
-    
-    stubInfo.reset();
-}
-
-void CodeBlock::resetStubDuringGCInternal(StructureStubInfo& stubInfo)
-{
-    resetStubInternal(stubInfo);
-    stubInfo.resetByGC = true;
-}
-
 CallLinkInfo* CodeBlock::getCallLinkInfoForBytecodeIndex(unsigned index)
 {
     for (auto iter = m_callLinkInfos.begin(); !!iter; ++iter) {

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (189322 => 189323)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2015-09-03 23:53:33 UTC (rev 189322)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2015-09-04 00:02:29 UTC (rev 189323)
@@ -215,8 +215,6 @@
     // stub info.
     StructureStubInfo* findStubInfo(CodeOrigin);
 
-    void resetStub(StructureStubInfo&);
-
     ByValInfo* addByValInfo();
 
     CallLinkInfo* addCallLinkInfo();
@@ -980,10 +978,6 @@
 
     void insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruction, 0, UnsafeVectorOverflow>&);
 
-#if ENABLE(JIT)
-    void resetStubInternal(StructureStubInfo&);
-    void resetStubDuringGCInternal(StructureStubInfo&);
-#endif
     WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
     int m_numParameters;
     union {

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubClearingWatchpoint.cpp (189322 => 189323)


--- trunk/Source/_javascript_Core/bytecode/StructureStubClearingWatchpoint.cpp	2015-09-03 23:53:33 UTC (rev 189322)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubClearingWatchpoint.cpp	2015-09-04 00:02:29 UTC (rev 189323)
@@ -51,7 +51,8 @@
         // This will implicitly cause my own demise: stub reset removes all watchpoints.
         // That works, because deleting a watchpoint removes it from the set's list, and
         // the set's list traversal for firing is robust against the set changing.
-        m_holder.codeBlock()->resetStub(*m_holder.stubInfo());
+        ConcurrentJITLocker locker(m_holder.codeBlock()->m_lock);
+        m_holder.stubInfo()->reset(m_holder.codeBlock());
         return;
     }
 

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp (189322 => 189323)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp	2015-09-03 23:53:33 UTC (rev 189322)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp	2015-09-04 00:02:29 UTC (rev 189323)
@@ -29,6 +29,7 @@
 #include "JSObject.h"
 #include "PolymorphicGetByIdList.h"
 #include "PolymorphicPutByIdList.h"
+#include "Repatch.h"
 
 namespace JSC {
 
@@ -63,46 +64,75 @@
     }
 }
 
-bool StructureStubInfo::visitWeakReferences(VM& vm)
+void StructureStubInfo::reset(CodeBlock* codeBlock)
 {
+    if (accessType == access_unset)
+        return;
+    
+    if (Options::verboseOSR()) {
+        // This can be called from GC destructor calls, so we don't try to do a full dump
+        // of the CodeBlock.
+        dataLog("Clearing structure cache (kind ", static_cast<int>(accessType), ") in ", RawPointer(codeBlock), ".\n");
+    }
+    
+    if (isGetByIdAccess(static_cast<AccessType>(accessType)))
+        resetGetByID(codeBlock, *this);
+    else if (isPutByIdAccess(static_cast<AccessType>(accessType)))
+        resetPutByID(codeBlock, *this);
+    else {
+        RELEASE_ASSERT(isInAccess(static_cast<AccessType>(accessType)));
+        resetIn(codeBlock, *this);
+    }
+    
+    deref();
+    accessType = access_unset;
+    stubRoutine = nullptr;
+    watchpoints = nullptr;
+}
+
+void StructureStubInfo::visitWeakReferences(CodeBlock* codeBlock)
+{
+    VM& vm = *codeBlock->vm();
+    
     switch (accessType) {
     case access_get_by_id_self:
-        if (!Heap::isMarked(u.getByIdSelf.baseObjectStructure.get()))
-            return false;
+        if (Heap::isMarked(u.getByIdSelf.baseObjectStructure.get()))
+            return;
         break;
     case access_get_by_id_list: {
-        if (!u.getByIdList.list->visitWeak(vm))
-            return false;
+        if (u.getByIdList.list->visitWeak(vm))
+            return;
         break;
     }
     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()))
-            return false;
-        if (!ObjectPropertyConditionSet::fromRawPointer(u.putByIdTransition.rawConditionSet).areStillLive())
-            return false;
+        if (Heap::isMarked(u.putByIdTransition.previousStructure.get())
+            && Heap::isMarked(u.putByIdTransition.structure.get())
+            && ObjectPropertyConditionSet::fromRawPointer(u.putByIdTransition.rawConditionSet).areStillLive())
+            return;
         break;
     case access_put_by_id_replace:
-        if (!Heap::isMarked(u.putByIdReplace.baseObjectStructure.get()))
-            return false;
+        if (Heap::isMarked(u.putByIdReplace.baseObjectStructure.get()))
+            return;
         break;
     case access_put_by_id_list:
-        if (!u.putByIdList.list->visitWeak(vm))
-            return false;
+        if (u.putByIdList.list->visitWeak(vm))
+            return;
         break;
     case access_in_list: {
         PolymorphicAccessStructureList* polymorphicStructures = u.inList.structureList;
-        if (!polymorphicStructures->visitWeak(u.inList.listSize))
-            return false;
+        if (polymorphicStructures->visitWeak(u.inList.listSize))
+            return;
         break;
     }
     default:
         // The rest of the instructions don't require references, so there is no need to
         // do anything.
-        break;
+        return;
     }
-    return true;
+
+    reset(codeBlock);
+    resetByGC = true;
 }
 #endif
 

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (189322 => 189323)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2015-09-03 23:53:33 UTC (rev 189322)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2015-09-04 00:02:29 UTC (rev 189323)
@@ -147,25 +147,13 @@
         u.inList.listSize = listSize;
     }
         
-    void reset()
-    {
-        deref();
-        accessType = access_unset;
-        stubRoutine = nullptr;
-        watchpoints = nullptr;
-    }
+    void reset(CodeBlock*);
 
     void deref();
 
-    // Check if the stub has weak references that are dead. If there are dead ones that imply
-    // that the stub should be entirely reset, this should return false. If there are dead ones
-    // that can be handled internally by the stub and don't require a full reset, then this
-    // should reset them and return true. If there are no dead weak references, return true.
-    // If this method returns true it means that it has left the stub in a state where all
-    // outgoing GC pointers are known to point to currently marked objects; this method is
-    // allowed to accomplish this by either clearing those pointers somehow or by proving that
-    // they have already been marked. It is not allowed to mark new objects.
-    bool visitWeakReferences(VM&);
+    // Check if the stub has weak references that are dead. If it does, then it resets itself,
+    // either entirely or just enough to ensure that those dead pointers don't get used anymore.
+    void visitWeakReferences(CodeBlock*);
         
     bool seenOnce()
     {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to