Unreviewed, rolling out r209766.
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Dec 2016 17:50:20 +0000 (17:50 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Dec 2016 17:50:20 +0000 (17:50 +0000)
Regressed Dromaeo JSLib by ~50%

Reverted changeset:

"Make opaque root scanning truly constraint-based"
https://bugs.webkit.org/show_bug.cgi?id=165760
http://trac.webkit.org/changeset/209766

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@209812 268f45cc-cd09-0410-ab3c-d52691b4dbfc

27 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/HeapInlines.h
Source/JavaScriptCore/heap/MarkedSpace.cpp
Source/JavaScriptCore/heap/MarkedSpace.h
Source/JavaScriptCore/heap/SlotVisitor.cpp
Source/JavaScriptCore/heap/SlotVisitor.h
Source/JavaScriptCore/heap/SlotVisitorInlines.h
Source/JavaScriptCore/heap/WeakBlock.cpp
Source/JavaScriptCore/heap/WeakBlock.h
Source/JavaScriptCore/heap/WeakSet.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/CommonVM.cpp
Source/WebCore/bindings/js/CommonVM.h
Source/WebCore/bindings/js/JSAttrCustom.cpp
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSIDBCursorCustom.cpp
Source/WebCore/bindings/js/JSMessageChannelCustom.cpp
Source/WebCore/bindings/js/JSMessagePortCustom.cpp
Source/WebCore/bindings/js/JSNodeIteratorCustom.cpp
Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp
Source/WebCore/bindings/js/JSTreeWalkerCustom.cpp
Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp
Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
Source/WebCore/bindings/js/JSXPathResultCustom.cpp
Source/WebCore/dom/ContainerNodeAlgorithms.cpp

index 1474264..b02f09b 100644 (file)
@@ -1,3 +1,15 @@
+2016-12-14  Chris Dumez  <cdumez@apple.com>
+
+        Unreviewed, rolling out r209766.
+
+        Regressed Dromaeo JSLib by ~50%
+
+        Reverted changeset:
+
+        "Make opaque root scanning truly constraint-based"
+        https://bugs.webkit.org/show_bug.cgi?id=165760
+        http://trac.webkit.org/changeset/209766
+
 2016-12-14  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r209795.
index d39856d..d6165aa 100644 (file)
@@ -519,7 +519,6 @@ void Heap::markToFixpoint(double gcStartTime)
     
     if (m_collectionScope == CollectionScope::Full) {
         m_opaqueRoots.clear();
-        m_constraints.clear();
         m_collectorSlotVisitor->clearMarkStacks();
         m_mutatorMarkStack->clear();
     }
@@ -618,22 +617,18 @@ void Heap::markToFixpoint(double gcStartTime)
                 
         m_jitStubRoutines->traceMarkedStubRoutines(*m_collectorSlotVisitor);
 
-        m_collectorSlotVisitor->mergeIfNecessary();
+        m_collectorSlotVisitor->mergeOpaqueRootsIfNecessary();
         for (auto& parallelVisitor : m_parallelSlotVisitors)
-            parallelVisitor->mergeIfNecessary();
-        
-        for (JSCell* cell : m_constraints)
-            m_collectorSlotVisitor->visitSubsequently(cell);
-        m_collectorSlotVisitor->mergeIfNecessary();
+            parallelVisitor->mergeOpaqueRootsIfNecessary();
 
-        size_t weakSetCount = m_objectSpace.visitWeakSets(heapRootVisitor);
+        m_objectSpace.visitWeakSets(heapRootVisitor);
         harvestWeakReferences();
         visitCompilerWorklistWeakReferences();
         DFG::markCodeBlocks(*m_vm, *m_collectorSlotVisitor);
         bool shouldTerminate = m_collectorSlotVisitor->isEmpty() && m_mutatorMarkStack->isEmpty();
         
         if (Options::logGC()) {
-            dataLog(m_collectorSlotVisitor->collectorMarkStack().size(), "+", m_mutatorMarkStack->size() + m_collectorSlotVisitor->mutatorMarkStack().size(), ", a=", m_bytesAllocatedThisCycle / 1024, " kb, b=", m_barriersExecuted, ", mu=", scheduler.currentDecision().targetMutatorUtilization(), ", ws=", weakSetCount, ", cs=", m_constraints.size(), " ");
+            dataLog(m_collectorSlotVisitor->collectorMarkStack().size(), "+", m_mutatorMarkStack->size() + m_collectorSlotVisitor->mutatorMarkStack().size(), ", a=", m_bytesAllocatedThisCycle / 1024, " kb, b=", m_barriersExecuted, ", mu=", scheduler.currentDecision().targetMutatorUtilization(), " ");
         }
         
         // We want to do this to conservatively ensure that we rescan any code blocks that are
@@ -2225,10 +2220,27 @@ void Heap::forEachSlotVisitor(const Func& func)
         func(*slotVisitor);
 }
 
+void Heap::writeBarrierOpaqueRootSlow(void* root)
+{
+    ASSERT(mutatorShouldBeFenced());
+    
+    auto locker = holdLock(m_opaqueRootsMutex);
+    m_opaqueRoots.add(root);
+}
+
+void Heap::addMutatorShouldBeFencedCache(bool& cache)
+{
+    ASSERT(hasHeapAccess());
+    cache = m_mutatorShouldBeFenced;
+    m_mutatorShouldBeFencedCaches.append(&cache);
+}
+
 void Heap::setMutatorShouldBeFenced(bool value)
 {
     m_mutatorShouldBeFenced = value;
     m_barrierThreshold = value ? tautologicalThreshold : blackThreshold;
+    for (bool* cache : m_mutatorShouldBeFencedCaches)
+        *cache = value;
 }
     
 } // namespace JSC
index dd4cfec..3e0ce66 100644 (file)
@@ -127,6 +127,8 @@ public:
     WriteBarrierBuffer& writeBarrierBuffer() { return m_writeBarrierBuffer; }
     void flushWriteBarrierBuffer(JSCell*);
     
+    void writeBarrierOpaqueRoot(void*);
+
     Heap(VM*, HeapType);
     ~Heap();
     void lastChanceToFinalize();
@@ -350,6 +352,8 @@ public:
     void preventCollection();
     void allowCollection();
     
+    JS_EXPORT_PRIVATE void addMutatorShouldBeFencedCache(bool&);
+    
 #if USE(CF)
     CFRunLoopRef runLoop() const { return m_runLoop.get(); }
     JS_EXPORT_PRIVATE void setRunLoop(CFRunLoopRef);
@@ -493,6 +497,8 @@ private:
     
     void forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>&);
     
+    JS_EXPORT_PRIVATE void writeBarrierOpaqueRootSlow(void*);
+    
     void setMutatorShouldBeFenced(bool value);
 
     const HeapType m_heapType;
@@ -553,6 +559,7 @@ private:
     WriteBarrierBuffer m_writeBarrierBuffer;
     bool m_mutatorShouldBeFenced { Options::forceFencedBarrier() };
     unsigned m_barrierThreshold { Options::forceFencedBarrier() ? tautologicalThreshold : blackThreshold };
+    Vector<bool*> m_mutatorShouldBeFencedCaches;
 
     VM* m_vm;
     double m_lastFullGCLength;
@@ -596,8 +603,7 @@ private:
     bool m_parallelMarkersShouldExit { false };
 
     Lock m_opaqueRootsMutex;
-    HashSet<const void*> m_opaqueRoots;
-    HashSet<JSCell*> m_constraints;
+    HashSet<void*> m_opaqueRoots;
 
     static const size_t s_blockFragmentLength = 32;
 
index 430a90e..55589ff 100644 (file)
@@ -370,4 +370,10 @@ inline void Heap::stopIfNecessary()
     stopIfNecessarySlow();
 }
 
+inline void Heap::writeBarrierOpaqueRoot(void* root)
+{
+    if (mutatorShouldBeFenced())
+        writeBarrierOpaqueRootSlow(root);
+}
+
 } // namespace JSC
index 8f42485..7b81944 100644 (file)
@@ -359,18 +359,16 @@ void MarkedSpace::prepareForAllocation()
     m_allocatorForEmptyAllocation = m_firstAllocator;
 }
 
-size_t MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
+void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
 {
-    size_t count = 0;
     auto visit = [&] (WeakSet* weakSet) {
-        count += weakSet->visit(heapRootVisitor);
+        weakSet->visit(heapRootVisitor);
     };
     
     m_newActiveWeakSets.forEach(visit);
     
     if (m_heap->collectionScope() == CollectionScope::Full)
         m_activeWeakSets.forEach(visit);
-    return count;
 }
 
 void MarkedSpace::reapWeakSets()
index f444e59..c61aa59 100644 (file)
@@ -129,7 +129,7 @@ public:
     
     void prepareForAllocation();
 
-    size_t visitWeakSets(HeapRootVisitor&);
+    void visitWeakSets(HeapRootVisitor&);
     void reapWeakSets();
 
     MarkedBlockSet& blocks() { return m_blocks; }
index 93f7f51..2927949 100644 (file)
@@ -356,8 +356,8 @@ ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell)
     
     if (false) {
         dataLog("Visiting ", RawPointer(cell));
-        if (!m_isFirstVisit)
-            dataLog(" (subsequent)");
+        if (m_isVisitingMutatorStack)
+            dataLog(" (mutator)");
         dataLog("\n");
     }
     
@@ -391,17 +391,11 @@ ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell)
     }
     
     if (UNLIKELY(m_heapSnapshotBuilder)) {
-        if (m_isFirstVisit)
+        if (!m_isVisitingMutatorStack)
             m_heapSnapshotBuilder->appendNode(const_cast<JSCell*>(cell));
     }
 }
 
-void SlotVisitor::visitSubsequently(JSCell* cell)
-{
-    m_isFirstVisit = false;
-    visitChildren(cell);
-}
-
 void SlotVisitor::donateKnownParallel(MarkStackArray& from, MarkStackArray& to)
 {
     // NOTE: Because we re-try often, we can afford to be conservative, and
@@ -471,7 +465,7 @@ void SlotVisitor::drain(MonotonicTime timeout)
         updateMutatorIsStopped(locker);
         if (!m_collectorStack.isEmpty()) {
             m_collectorStack.refill();
-            m_isFirstVisit = true;
+            m_isVisitingMutatorStack = false;
             for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_collectorStack.canRemoveLast() && countdown--;)
                 visitChildren(m_collectorStack.removeLast());
         } else if (!m_mutatorStack.isEmpty()) {
@@ -479,7 +473,7 @@ void SlotVisitor::drain(MonotonicTime timeout)
             // We know for sure that we are visiting objects because of the barrier, not because of
             // marking. Marking will visit an object exactly once. The barrier will visit it
             // possibly many times, and always after it was already marked.
-            m_isFirstVisit = false;
+            m_isVisitingMutatorStack = true;
             for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_mutatorStack.canRemoveLast() && countdown--;)
                 visitChildren(m_mutatorStack.removeLast());
         }
@@ -487,7 +481,7 @@ void SlotVisitor::drain(MonotonicTime timeout)
         donateKnownParallel();
     }
     
-    mergeIfNecessary();
+    mergeOpaqueRootsIfNecessary();
 }
 
 bool SlotVisitor::didReachTermination()
@@ -606,24 +600,12 @@ void SlotVisitor::addOpaqueRoot(void* root)
     if (Options::numberOfGCMarkers() == 1) {
         // Put directly into the shared HashSet.
         m_heap.m_opaqueRoots.add(root);
-        m_heap.m_constraints.add(m_currentCell);
         return;
     }
     // Put into the local set, but merge with the shared one every once in
     // a while to make sure that the local sets don't grow too large.
     mergeOpaqueRootsIfProfitable();
     m_opaqueRoots.add(root);
-    m_constraints.add(m_currentCell);
-}
-
-void SlotVisitor::rescanAsConstraint()
-{
-    if (Options::numberOfGCMarkers() == 1) {
-        m_heap.m_constraints.add(m_currentCell);
-        return;
-    }
-    
-    m_constraints.add(m_currentCell);
 }
 
 bool SlotVisitor::containsOpaqueRoot(void* root) const
@@ -648,13 +630,13 @@ TriState SlotVisitor::containsOpaqueRootTriState(void* root) const
     return MixedTriState;
 }
 
-void SlotVisitor::mergeIfNecessary()
+void SlotVisitor::mergeOpaqueRootsIfNecessary()
 {
-    if (m_opaqueRoots.isEmpty() && m_constraints.isEmpty())
+    if (m_opaqueRoots.isEmpty())
         return;
-    mergeOpaqueRootsAndConstraints();
+    mergeOpaqueRoots();
 }
-
+    
 void SlotVisitor::mergeOpaqueRootsIfProfitable()
 {
     if (static_cast<unsigned>(m_opaqueRoots.size()) < Options::opaqueRootMergeThreshold())
@@ -687,19 +669,6 @@ void SlotVisitor::mergeOpaqueRoots()
     m_opaqueRoots.clear();
 }
 
-void SlotVisitor::mergeOpaqueRootsAndConstraints()
-{
-    {
-        std::lock_guard<Lock> lock(m_heap.m_opaqueRootsMutex);
-        for (const void* root : m_opaqueRoots)
-            m_heap.m_opaqueRoots.add(root);
-        for (JSCell* constraint : m_constraints)
-            m_heap.m_constraints.add(constraint);
-    }
-    m_opaqueRoots.clear();
-    m_constraints.clear();
-}
-
 void SlotVisitor::addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester)
 {
     m_heap.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester);
index 04baacf..b4d2f80 100644 (file)
@@ -85,18 +85,7 @@ public:
     void appendUnbarrieredReadOnlyPointer(T*);
     void appendUnbarrieredReadOnlyValue(JSValue);
     
-    void visitSubsequently(JSCell*);
-    
-    // Does your visitChildren do logic that depends on non-JS-object state that can
-    // change during the course of a GC, or in between GCs? Then you should call this
-    // method! It will cause the GC to invoke your visitChildren method again just before
-    // terminating with the world stopped.
-    JS_EXPORT_PRIVATE void rescanAsConstraint();
-    
-    // Implies rescanAsConstraint, so you don't have to call rescanAsConstraint() if you
-    // call this unconditionally.
     JS_EXPORT_PRIVATE void addOpaqueRoot(void*);
-    
     JS_EXPORT_PRIVATE bool containsOpaqueRoot(void*) const;
     TriState containsOpaqueRootTriState(void*) const;
 
@@ -119,8 +108,6 @@ public:
 
     SharedDrainResult drainInParallel(MonotonicTime timeout = MonotonicTime::infinity());
     SharedDrainResult drainInParallelPassively(MonotonicTime timeout = MonotonicTime::infinity());
-    
-    void mergeIfNecessary();
 
     // This informs the GC about auxiliary of some size that we are keeping alive. If you don't do
     // this then the space will be freed at end of GC.
@@ -140,6 +127,8 @@ public:
     
     HeapVersion markingVersion() const { return m_markingVersion; }
 
+    void mergeOpaqueRootsIfNecessary();
+    
     bool mutatorIsStopped() const { return m_mutatorIsStopped; }
     
     Lock& rightToRun() { return m_rightToRun; }
@@ -178,9 +167,7 @@ private:
     
     void noteLiveAuxiliaryCell(HeapCell*);
     
-    void mergeOpaqueRoots();
-    void mergeOpaqueRootsAndConstraints();
-
+    JS_EXPORT_PRIVATE void mergeOpaqueRoots();
     void mergeOpaqueRootsIfProfitable();
 
     void visitChildren(const JSCell*);
@@ -194,7 +181,6 @@ private:
     MarkStackArray m_collectorStack;
     MarkStackArray m_mutatorStack;
     OpaqueRootSet m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
-    HashSet<JSCell*> m_constraints;
     
     size_t m_bytesVisited;
     size_t m_visitCount;
@@ -206,7 +192,7 @@ private:
 
     HeapSnapshotBuilder* m_heapSnapshotBuilder { nullptr };
     JSCell* m_currentCell { nullptr };
-    bool m_isFirstVisit { false };
+    bool m_isVisitingMutatorStack { false };
     bool m_mutatorIsStopped { false };
     bool m_canOptimizeForStoppedMutator { false };
     Lock m_rightToRun;
index 9adb1e7..cf335d0 100644 (file)
@@ -95,14 +95,14 @@ inline void SlotVisitor::appendValuesHidden(WriteBarrierBase<Unknown>* barriers,
 
 inline void SlotVisitor::reportExtraMemoryVisited(size_t size)
 {
-    if (m_isFirstVisit)
+    if (!m_isVisitingMutatorStack)
         heap()->reportExtraMemoryVisited(size);
 }
 
 #if ENABLE(RESOURCE_USAGE)
 inline void SlotVisitor::reportExternalMemoryVisited(size_t size)
 {
-    if (m_isFirstVisit)
+    if (!m_isVisitingMutatorStack)
         heap()->reportExternalMemoryVisited(size);
 }
 #endif
@@ -127,7 +127,7 @@ inline void SlotVisitor::didNotRace(const VisitRaceKey& race)
     if (ASSERT_DISABLED)
         return;
     
-    if (m_isFirstVisit) {
+    if (!m_isVisitingMutatorStack) {
         // This is the first visit so we don't need to remove anything.
         return;
     }
index 475d84c..dc57cc4 100644 (file)
@@ -97,14 +97,13 @@ void WeakBlock::sweep()
 }
 
 template<typename ContainerType>
-size_t WeakBlock::specializedVisit(ContainerType& container, HeapRootVisitor& heapRootVisitor)
+void WeakBlock::specializedVisit(ContainerType& container, HeapRootVisitor& heapRootVisitor)
 {
     SlotVisitor& visitor = heapRootVisitor.visitor();
     
     HeapVersion markingVersion = visitor.markingVersion();
 
-    size_t count = weakImplCount();
-    for (size_t i = 0; i < count; ++i) {
+    for (size_t i = 0; i < weakImplCount(); ++i) {
         WeakImpl* weakImpl = &weakImpls()[i];
         if (weakImpl->state() != WeakImpl::Live)
             continue;
@@ -122,22 +121,21 @@ size_t WeakBlock::specializedVisit(ContainerType& container, HeapRootVisitor& he
 
         heapRootVisitor.visit(&const_cast<JSValue&>(jsValue));
     }
-    
-    return count;
 }
 
-size_t WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
+void WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
 {
     // If a block is completely empty, a visit won't have any effect.
     if (isEmpty())
-        return 0;
+        return;
 
     // If this WeakBlock doesn't belong to a CellContainer, we won't even be here.
     ASSERT(m_container);
     
     if (m_container.isLargeAllocation())
-        return specializedVisit(m_container.largeAllocation(), heapRootVisitor);
-    return specializedVisit(m_container.markedBlock(), heapRootVisitor);
+        specializedVisit(m_container.largeAllocation(), heapRootVisitor);
+    else
+        specializedVisit(m_container.markedBlock(), heapRootVisitor);
 }
 
 void WeakBlock::reap()
index bd58ea8..b6453f6 100644 (file)
@@ -63,7 +63,7 @@ public:
     void sweep();
     SweepResult takeSweepResult();
 
-    size_t visit(HeapRootVisitor&);
+    void visit(HeapRootVisitor&);
     void reap();
 
     void lastChanceToFinalize();
@@ -73,7 +73,7 @@ private:
     static FreeCell* asFreeCell(WeakImpl*);
     
     template<typename ContainerType>
-    size_t specializedVisit(ContainerType&, HeapRootVisitor&);
+    void specializedVisit(ContainerType&, HeapRootVisitor&);
 
     explicit WeakBlock(CellContainer);
     void finalize(WeakImpl*);
index 47f9d86..36fb594 100644 (file)
@@ -53,7 +53,7 @@ public:
 
     bool isEmpty() const;
 
-    size_t visit(HeapRootVisitor&);
+    unsigned visit(HeapRootVisitor&);
     void reap();
     void sweep();
     void shrink();
@@ -106,11 +106,13 @@ inline void WeakSet::lastChanceToFinalize()
         block->lastChanceToFinalize();
 }
 
-inline size_t WeakSet::visit(HeapRootVisitor& visitor)
+inline unsigned WeakSet::visit(HeapRootVisitor& visitor)
 {
-    size_t count = 0;
-    for (WeakBlock* block = m_blocks.head(); block; block = block->next())
-        count += block->visit(visitor);
+    unsigned count = 0;
+    for (WeakBlock* block = m_blocks.head(); block; block = block->next()) {
+        count++;
+        block->visit(visitor);
+    }
     return count;
 }
 
index a2279a2..eafd97f 100644 (file)
@@ -1,3 +1,15 @@
+2016-12-14  Chris Dumez  <cdumez@apple.com>
+
+        Unreviewed, rolling out r209766.
+
+        Regressed Dromaeo JSLib by ~50%
+
+        Reverted changeset:
+
+        "Make opaque root scanning truly constraint-based"
+        https://bugs.webkit.org/show_bug.cgi?id=165760
+        http://trac.webkit.org/changeset/209766
+
 2016-12-14  Andy Estes  <aestes@apple.com>
 
         EventDispatcher::dispatchEvent() should take its Node by reference
index adda7f4..86f7060 100644 (file)
@@ -38,6 +38,7 @@ using namespace JSC;
 namespace WebCore {
 
 VM* g_commonVMOrNull;
+bool g_opaqueRootWriteBarrierEnabled;
 
 VM& commonVMSlow()
 {
@@ -55,11 +56,18 @@ VM& commonVMSlow()
 #endif
     
     g_commonVMOrNull->setGlobalConstRedeclarationShouldThrow(Settings::globalConstRedeclarationShouldThrow());
+    g_commonVMOrNull->heap.addMutatorShouldBeFencedCache(g_opaqueRootWriteBarrierEnabled);
     
     initNormalWorldClientData(g_commonVMOrNull);
     
     return *g_commonVMOrNull;
 }
 
+void writeBarrierOpaqueRootSlow(void* root)
+{
+    if (VM* vm = g_commonVMOrNull)
+        vm->heap.writeBarrierOpaqueRoot(root);
+}
+
 } // namespace WebCore
 
index 9c69675..244ccdd 100644 (file)
@@ -32,8 +32,10 @@ class VM;
 namespace WebCore {
 
 WEBCORE_EXPORT extern JSC::VM* g_commonVMOrNull;
+WEBCORE_EXPORT extern bool g_opaqueRootWriteBarrierEnabled;
 
 WEBCORE_EXPORT JSC::VM& commonVMSlow();
+WEBCORE_EXPORT void writeBarrierOpaqueRootSlow(void*);
 
 inline JSC::VM& commonVM()
 {
@@ -42,5 +44,12 @@ inline JSC::VM& commonVM()
     return commonVMSlow();
 }
 
+template<typename Func>
+void writeBarrierOpaqueRoot(const Func& rootThunk)
+{
+    if (g_opaqueRootWriteBarrierEnabled)
+        writeBarrierOpaqueRootSlow(rootThunk());
+}
+
 } // namespace WebCore
 
index 55e05c6..d45cf6d 100644 (file)
@@ -35,7 +35,6 @@ namespace WebCore {
 
 void JSAttr::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
     if (Element* element = wrapped().ownerElement())
         visitor.addOpaqueRoot(root(element));
 }
index 508b23e..8a6aabd 100644 (file)
@@ -51,7 +51,6 @@ EncodedJSValue JSC_HOST_CALL jsDOMWindowInstanceFunctionShowModalDialog(ExecStat
 
 void JSDOMWindow::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
     if (Frame* frame = wrapped().frame())
         visitor.addOpaqueRoot(frame);
 }
index 92397cd..4aa505f 100644 (file)
@@ -39,7 +39,6 @@ namespace WebCore {
 
 void JSIDBCursor::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
     auto& cursor = wrapped();
     if (auto* request = cursor.request())
         visitor.addOpaqueRoot(request);
index 8f7e681..375dd4b 100644 (file)
@@ -35,8 +35,6 @@ namespace WebCore {
 
 void JSMessageChannel::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     if (MessagePort* port = wrapped().port1())
         visitor.addOpaqueRoot(port);
 
index 5a8f37e..b168cf2 100644 (file)
@@ -33,8 +33,6 @@ namespace WebCore {
 
 void JSMessagePort::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext().
     if (MessagePort* port = wrapped().locallyEntangledPort())
         visitor.addOpaqueRoot(port);
index 25dfe8c..b3f0361 100644 (file)
@@ -27,8 +27,6 @@ namespace WebCore {
 
 void JSNodeIterator::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     if (NodeFilter* filter = wrapped().filter())
         visitor.addOpaqueRoot(filter);
 }
index f1a010a..6e7774e 100644 (file)
@@ -77,8 +77,6 @@ JSValue toJS(ExecState* state, JSDOMGlobalObject* globalObject, TextTrackCue& cu
 
 void JSTextTrackCue::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     if (TextTrack* textTrack = wrapped().track())
         visitor.addOpaqueRoot(root(textTrack));
 }
index 76e85cd..2be08a9 100644 (file)
@@ -27,8 +27,6 @@ namespace WebCore {
 
 void JSTreeWalker::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     if (NodeFilter* filter = wrapped().filter())
         visitor.addOpaqueRoot(filter);
 }
index 382d8eb..87c9ec8 100644 (file)
@@ -36,8 +36,6 @@ namespace WebCore {
 
 void JSWorkerGlobalScope::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     if (auto* location = wrapped().optionalLocation())
         visitor.addOpaqueRoot(location);
     if (auto* navigator = wrapped().optionalNavigator())
index 2fd72af..de94c5f 100644 (file)
@@ -58,8 +58,6 @@ namespace WebCore {
 
 void JSXMLHttpRequest::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     if (XMLHttpRequestUpload* upload = wrapped().optionalUpload())
         visitor.addOpaqueRoot(upload);
 
index cfd269e..d4fbbef 100644 (file)
@@ -33,8 +33,6 @@ namespace WebCore {
 
 void JSXPathResult::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    visitor.rescanAsConstraint();
-    
     auto& value = wrapped().value();
     if (value.isNodeSet()) {
         // FIXME: This looks like it might race, but I'm not sure.
index 75369d6..7f3fea6 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "ContainerNodeAlgorithms.h"
 
+#include "CommonVM.h"
 #include "HTMLFrameOwnerElement.h"
 #include "InspectorInstrumentation.h"
 #include "NoEventDispatchAssertion.h"
@@ -101,6 +102,8 @@ void notifyChildNodeInserted(ContainerNode& insertionPoint, Node& node, NodeVect
         notifyNodeInsertedIntoDocument(insertionPoint, node, postInsertionNotificationTargets);
     else if (is<ContainerNode>(node))
         notifyNodeInsertedIntoTree(insertionPoint, downcast<ContainerNode>(node), postInsertionNotificationTargets);
+
+    writeBarrierOpaqueRoot([&insertionPoint] () -> void* { return insertionPoint.opaqueRoot(); });
 }
 
 void notifyNodeRemovedFromDocument(ContainerNode& insertionPoint, Node& node)
@@ -152,6 +155,8 @@ void notifyNodeRemovedFromTree(ContainerNode& insertionPoint, ContainerNode& nod
 
 void notifyChildNodeRemoved(ContainerNode& insertionPoint, Node& child)
 {
+    writeBarrierOpaqueRoot([&child] () -> void* { return &child; });
+
     if (!child.inDocument()) {
         if (is<ContainerNode>(child))
             notifyNodeRemovedFromTree(insertionPoint, downcast<ContainerNode>(child));