Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (209765 => 209766)
--- trunk/Source/_javascript_Core/ChangeLog 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-12-13 19:54:15 UTC (rev 209766)
@@ -1,3 +1,60 @@
+2016-12-13 Filip Pizlo <[email protected]>
+
+ Make opaque root scanning truly constraint-based
+ https://bugs.webkit.org/show_bug.cgi?id=165760
+
+ Reviewed by Saam Barati.
+
+ We have bugs when visitChildren() changes its mind about what opaque root to add, since
+ we don't have barriers on opaque roots. This supposedly once worked for generational GC,
+ and I started adding more barriers to support concurrent GC. But I think that the real
+ bug here is that we want the JSObject->OpaqueRoot to be evaluated as a constraint that
+ participates in the fixpoint. A constraint is different from the normal visiting in that
+ the GC will not wait for a barrier to rescan the object.
+
+ So, it's now possible for any visitChildren() method to become a constraint by calling
+ slotVisitor.rescanAsConstraint(). Because opaque roots are constraints, addOpaqueRoot()
+ does rescanAsConstraint() for you.
+
+ The constraint set is simply a HashSet<JSCell*> that accumulates with every
+ rescanAsConstraint() call and is only cleared at the start of full GC. This trivially
+ resolves most classes of GC bugs that would have arisen from opaque roots being changed
+ in a way that the GC did not anticipate.
+
+ Looks like this is perf-neutral.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::markToFixpoint):
+ (JSC::Heap::setMutatorShouldBeFenced):
+ (JSC::Heap::writeBarrierOpaqueRootSlow): Deleted.
+ (JSC::Heap::addMutatorShouldBeFencedCache): Deleted.
+ * heap/Heap.h:
+ * heap/HeapInlines.h:
+ (JSC::Heap::writeBarrierOpaqueRoot): Deleted.
+ * heap/MarkedSpace.cpp:
+ (JSC::MarkedSpace::visitWeakSets):
+ * heap/MarkedSpace.h:
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::visitChildren):
+ (JSC::SlotVisitor::visitSubsequently):
+ (JSC::SlotVisitor::drain):
+ (JSC::SlotVisitor::addOpaqueRoot):
+ (JSC::SlotVisitor::rescanAsConstraint):
+ (JSC::SlotVisitor::mergeIfNecessary):
+ (JSC::SlotVisitor::mergeOpaqueRootsAndConstraints):
+ (JSC::SlotVisitor::mergeOpaqueRootsIfNecessary): Deleted.
+ * heap/SlotVisitor.h:
+ * heap/SlotVisitorInlines.h:
+ (JSC::SlotVisitor::reportExtraMemoryVisited):
+ (JSC::SlotVisitor::reportExternalMemoryVisited):
+ (JSC::SlotVisitor::didNotRace):
+ * heap/WeakBlock.cpp:
+ (JSC::WeakBlock::specializedVisit):
+ (JSC::WeakBlock::visit):
+ * heap/WeakBlock.h:
+ * heap/WeakSet.h:
+ (JSC::WeakSet::visit):
+
2016-12-13 Commit Queue <[email protected]>
Unreviewed, rolling out r209725.
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -519,6 +519,7 @@
if (m_collectionScope == CollectionScope::Full) {
m_opaqueRoots.clear();
+ m_constraints.clear();
m_collectorSlotVisitor->clearMarkStacks();
m_mutatorMarkStack->clear();
}
@@ -617,11 +618,15 @@
m_jitStubRoutines->traceMarkedStubRoutines(*m_collectorSlotVisitor);
- m_collectorSlotVisitor->mergeOpaqueRootsIfNecessary();
+ m_collectorSlotVisitor->mergeIfNecessary();
for (auto& parallelVisitor : m_parallelSlotVisitors)
- parallelVisitor->mergeOpaqueRootsIfNecessary();
+ parallelVisitor->mergeIfNecessary();
+
+ for (JSCell* cell : m_constraints)
+ m_collectorSlotVisitor->visitSubsequently(cell);
+ m_collectorSlotVisitor->mergeIfNecessary();
- m_objectSpace.visitWeakSets(heapRootVisitor);
+ size_t weakSetCount = m_objectSpace.visitWeakSets(heapRootVisitor);
harvestWeakReferences();
visitCompilerWorklistWeakReferences();
DFG::markCodeBlocks(*m_vm, *m_collectorSlotVisitor);
@@ -628,7 +633,7 @@
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(), " ");
+ 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(), " ");
}
// We want to do this to conservatively ensure that we rescan any code blocks that are
@@ -2220,27 +2225,10 @@
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
Modified: trunk/Source/_javascript_Core/heap/Heap.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/Heap.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -127,8 +127,6 @@
WriteBarrierBuffer& writeBarrierBuffer() { return m_writeBarrierBuffer; }
void flushWriteBarrierBuffer(JSCell*);
- void writeBarrierOpaqueRoot(void*);
-
Heap(VM*, HeapType);
~Heap();
void lastChanceToFinalize();
@@ -352,8 +350,6 @@
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);
@@ -497,8 +493,6 @@
void forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>&);
- JS_EXPORT_PRIVATE void writeBarrierOpaqueRootSlow(void*);
-
void setMutatorShouldBeFenced(bool value);
const HeapType m_heapType;
@@ -559,7 +553,6 @@
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;
@@ -603,7 +596,8 @@
bool m_parallelMarkersShouldExit { false };
Lock m_opaqueRootsMutex;
- HashSet<void*> m_opaqueRoots;
+ HashSet<const void*> m_opaqueRoots;
+ HashSet<JSCell*> m_constraints;
static const size_t s_blockFragmentLength = 32;
Modified: trunk/Source/_javascript_Core/heap/HeapInlines.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/HeapInlines.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/HeapInlines.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -370,10 +370,4 @@
stopIfNecessarySlow();
}
-inline void Heap::writeBarrierOpaqueRoot(void* root)
-{
- if (mutatorShouldBeFenced())
- writeBarrierOpaqueRootSlow(root);
-}
-
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.cpp (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -359,10 +359,11 @@
m_allocatorForEmptyAllocation = m_firstAllocator;
}
-void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
+size_t MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
{
+ size_t count = 0;
auto visit = [&] (WeakSet* weakSet) {
- weakSet->visit(heapRootVisitor);
+ count += weakSet->visit(heapRootVisitor);
};
m_newActiveWeakSets.forEach(visit);
@@ -369,6 +370,7 @@
if (m_heap->collectionScope() == CollectionScope::Full)
m_activeWeakSets.forEach(visit);
+ return count;
}
void MarkedSpace::reapWeakSets()
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -129,7 +129,7 @@
void prepareForAllocation();
- void visitWeakSets(HeapRootVisitor&);
+ size_t visitWeakSets(HeapRootVisitor&);
void reapWeakSets();
MarkedBlockSet& blocks() { return m_blocks; }
Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.cpp (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/SlotVisitor.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -356,8 +356,8 @@
if (false) {
dataLog("Visiting ", RawPointer(cell));
- if (m_isVisitingMutatorStack)
- dataLog(" (mutator)");
+ if (!m_isFirstVisit)
+ dataLog(" (subsequent)");
dataLog("\n");
}
@@ -391,11 +391,17 @@
}
if (UNLIKELY(m_heapSnapshotBuilder)) {
- if (!m_isVisitingMutatorStack)
+ if (m_isFirstVisit)
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
@@ -465,7 +471,7 @@
updateMutatorIsStopped(locker);
if (!m_collectorStack.isEmpty()) {
m_collectorStack.refill();
- m_isVisitingMutatorStack = false;
+ m_isFirstVisit = true;
for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_collectorStack.canRemoveLast() && countdown--;)
visitChildren(m_collectorStack.removeLast());
} else if (!m_mutatorStack.isEmpty()) {
@@ -473,7 +479,7 @@
// 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_isVisitingMutatorStack = true;
+ m_isFirstVisit = false;
for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_mutatorStack.canRemoveLast() && countdown--;)
visitChildren(m_mutatorStack.removeLast());
}
@@ -481,7 +487,7 @@
donateKnownParallel();
}
- mergeOpaqueRootsIfNecessary();
+ mergeIfNecessary();
}
bool SlotVisitor::didReachTermination()
@@ -597,6 +603,7 @@
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
@@ -603,8 +610,19 @@
// 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
{
ASSERT(!m_isInParallelMode);
@@ -621,13 +639,13 @@
return MixedTriState;
}
-void SlotVisitor::mergeOpaqueRootsIfNecessary()
+void SlotVisitor::mergeIfNecessary()
{
- if (m_opaqueRoots.isEmpty())
+ if (m_opaqueRoots.isEmpty() && m_constraints.isEmpty())
return;
- mergeOpaqueRoots();
+ mergeOpaqueRootsAndConstraints();
}
-
+
void SlotVisitor::mergeOpaqueRootsIfProfitable()
{
if (static_cast<unsigned>(m_opaqueRoots.size()) < Options::opaqueRootMergeThreshold())
@@ -660,6 +678,19 @@
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);
Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/SlotVisitor.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -85,7 +85,18 @@
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;
@@ -108,6 +119,8 @@
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.
@@ -127,8 +140,6 @@
HeapVersion markingVersion() const { return m_markingVersion; }
- void mergeOpaqueRootsIfNecessary();
-
bool mutatorIsStopped() const { return m_mutatorIsStopped; }
Lock& rightToRun() { return m_rightToRun; }
@@ -167,7 +178,9 @@
void noteLiveAuxiliaryCell(HeapCell*);
- JS_EXPORT_PRIVATE void mergeOpaqueRoots();
+ void mergeOpaqueRoots();
+ void mergeOpaqueRootsAndConstraints();
+
void mergeOpaqueRootsIfProfitable();
void visitChildren(const JSCell*);
@@ -181,6 +194,7 @@
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;
@@ -192,7 +206,7 @@
HeapSnapshotBuilder* m_heapSnapshotBuilder { nullptr };
JSCell* m_currentCell { nullptr };
- bool m_isVisitingMutatorStack { false };
+ bool m_isFirstVisit { false };
bool m_mutatorIsStopped { false };
bool m_canOptimizeForStoppedMutator { false };
Lock m_rightToRun;
Modified: trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -95,7 +95,7 @@
inline void SlotVisitor::reportExtraMemoryVisited(size_t size)
{
- if (!m_isVisitingMutatorStack)
+ if (m_isFirstVisit)
heap()->reportExtraMemoryVisited(size);
}
@@ -102,7 +102,7 @@
#if ENABLE(RESOURCE_USAGE)
inline void SlotVisitor::reportExternalMemoryVisited(size_t size)
{
- if (!m_isVisitingMutatorStack)
+ if (m_isFirstVisit)
heap()->reportExternalMemoryVisited(size);
}
#endif
@@ -127,7 +127,7 @@
if (ASSERT_DISABLED)
return;
- if (!m_isVisitingMutatorStack) {
+ if (m_isFirstVisit) {
// This is the first visit so we don't need to remove anything.
return;
}
Modified: trunk/Source/_javascript_Core/heap/WeakBlock.cpp (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/WeakBlock.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/WeakBlock.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -97,13 +97,14 @@
}
template<typename ContainerType>
-void WeakBlock::specializedVisit(ContainerType& container, HeapRootVisitor& heapRootVisitor)
+size_t WeakBlock::specializedVisit(ContainerType& container, HeapRootVisitor& heapRootVisitor)
{
SlotVisitor& visitor = heapRootVisitor.visitor();
HeapVersion markingVersion = visitor.markingVersion();
- for (size_t i = 0; i < weakImplCount(); ++i) {
+ size_t count = weakImplCount();
+ for (size_t i = 0; i < count; ++i) {
WeakImpl* weakImpl = &weakImpls()[i];
if (weakImpl->state() != WeakImpl::Live)
continue;
@@ -121,21 +122,22 @@
heapRootVisitor.visit(&const_cast<JSValue&>(jsValue));
}
+
+ return count;
}
-void WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
+size_t WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
{
// If a block is completely empty, a visit won't have any effect.
if (isEmpty())
- return;
+ return 0;
// If this WeakBlock doesn't belong to a CellContainer, we won't even be here.
ASSERT(m_container);
if (m_container.isLargeAllocation())
- specializedVisit(m_container.largeAllocation(), heapRootVisitor);
- else
- specializedVisit(m_container.markedBlock(), heapRootVisitor);
+ return specializedVisit(m_container.largeAllocation(), heapRootVisitor);
+ return specializedVisit(m_container.markedBlock(), heapRootVisitor);
}
void WeakBlock::reap()
Modified: trunk/Source/_javascript_Core/heap/WeakBlock.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/WeakBlock.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/WeakBlock.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -63,7 +63,7 @@
void sweep();
SweepResult takeSweepResult();
- void visit(HeapRootVisitor&);
+ size_t visit(HeapRootVisitor&);
void reap();
void lastChanceToFinalize();
@@ -73,7 +73,7 @@
static FreeCell* asFreeCell(WeakImpl*);
template<typename ContainerType>
- void specializedVisit(ContainerType&, HeapRootVisitor&);
+ size_t specializedVisit(ContainerType&, HeapRootVisitor&);
explicit WeakBlock(CellContainer);
void finalize(WeakImpl*);
Modified: trunk/Source/_javascript_Core/heap/WeakSet.h (209765 => 209766)
--- trunk/Source/_javascript_Core/heap/WeakSet.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/_javascript_Core/heap/WeakSet.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -53,7 +53,7 @@
bool isEmpty() const;
- unsigned visit(HeapRootVisitor&);
+ size_t visit(HeapRootVisitor&);
void reap();
void sweep();
void shrink();
@@ -106,13 +106,11 @@
block->lastChanceToFinalize();
}
-inline unsigned WeakSet::visit(HeapRootVisitor& visitor)
+inline size_t WeakSet::visit(HeapRootVisitor& visitor)
{
- unsigned count = 0;
- for (WeakBlock* block = m_blocks.head(); block; block = block->next()) {
- count++;
- block->visit(visitor);
- }
+ size_t count = 0;
+ for (WeakBlock* block = m_blocks.head(); block; block = block->next())
+ count += block->visit(visitor);
return count;
}
Modified: trunk/Source/WebCore/ChangeLog (209765 => 209766)
--- trunk/Source/WebCore/ChangeLog 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/ChangeLog 2016-12-13 19:54:15 UTC (rev 209766)
@@ -1,3 +1,51 @@
+2016-12-13 Filip Pizlo <[email protected]>
+
+ Make opaque root scanning truly constraint-based
+ https://bugs.webkit.org/show_bug.cgi?id=165760
+
+ Reviewed by Saam Barati.
+
+ No new tests yet. I think that writing tests for this is a big investigation:
+ https://bugs.webkit.org/show_bug.cgi?id=165808
+
+ Remove the previous advancing wavefront DOM write barrier. I don't think this will scale
+ very well. It's super confusing.
+
+ This change makes it so that visitChildren can become a GC constraint that executes as
+ part of the fixpoint. This changes all WebCore visitChildren methods that do opaque
+ roots into constraints.
+
+ * bindings/js/CommonVM.cpp:
+ (WebCore::commonVMSlow):
+ (WebCore::writeBarrierOpaqueRootSlow): Deleted.
+ * bindings/js/CommonVM.h:
+ (WebCore::writeBarrierOpaqueRoot): Deleted.
+ * bindings/js/JSAttrCustom.cpp:
+ (WebCore::JSAttr::visitAdditionalChildren):
+ * bindings/js/JSDOMWindowCustom.cpp:
+ (WebCore::JSDOMWindow::visitAdditionalChildren):
+ * bindings/js/JSIDBCursorCustom.cpp:
+ (WebCore::JSIDBCursor::visitAdditionalChildren):
+ * bindings/js/JSMessageChannelCustom.cpp:
+ (WebCore::JSMessageChannel::visitAdditionalChildren):
+ * bindings/js/JSMessagePortCustom.cpp:
+ (WebCore::JSMessagePort::visitAdditionalChildren):
+ * bindings/js/JSNodeIteratorCustom.cpp:
+ (WebCore::JSNodeIterator::visitAdditionalChildren):
+ * bindings/js/JSTextTrackCueCustom.cpp:
+ (WebCore::JSTextTrackCue::visitAdditionalChildren):
+ * bindings/js/JSTreeWalkerCustom.cpp:
+ (WebCore::JSTreeWalker::visitAdditionalChildren):
+ * bindings/js/JSWorkerGlobalScopeCustom.cpp:
+ (WebCore::JSWorkerGlobalScope::visitAdditionalChildren):
+ * bindings/js/JSXMLHttpRequestCustom.cpp:
+ (WebCore::JSXMLHttpRequest::visitAdditionalChildren):
+ * bindings/js/JSXPathResultCustom.cpp:
+ (WebCore::JSXPathResult::visitAdditionalChildren):
+ * dom/ContainerNodeAlgorithms.cpp:
+ (WebCore::notifyChildNodeInserted):
+ (WebCore::notifyChildNodeRemoved):
+
2016-12-12 Sam Weinig <[email protected]>
[WebIDL] Remove use of Dictionary in ApplePaySession
Modified: trunk/Source/WebCore/bindings/js/CommonVM.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/CommonVM.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/CommonVM.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -38,7 +38,6 @@
namespace WebCore {
VM* g_commonVMOrNull;
-bool g_opaqueRootWriteBarrierEnabled;
VM& commonVMSlow()
{
@@ -56,7 +55,6 @@
#endif
g_commonVMOrNull->setGlobalConstRedeclarationShouldThrow(Settings::globalConstRedeclarationShouldThrow());
- g_commonVMOrNull->heap.addMutatorShouldBeFencedCache(g_opaqueRootWriteBarrierEnabled);
initNormalWorldClientData(g_commonVMOrNull);
@@ -63,11 +61,5 @@
return *g_commonVMOrNull;
}
-void writeBarrierOpaqueRootSlow(void* root)
-{
- if (VM* vm = g_commonVMOrNull)
- vm->heap.writeBarrierOpaqueRoot(root);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/CommonVM.h (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/CommonVM.h 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/CommonVM.h 2016-12-13 19:54:15 UTC (rev 209766)
@@ -32,10 +32,8 @@
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()
{
@@ -44,12 +42,5 @@
return commonVMSlow();
}
-template<typename Func>
-void writeBarrierOpaqueRoot(const Func& rootThunk)
-{
- if (g_opaqueRootWriteBarrierEnabled)
- writeBarrierOpaqueRootSlow(rootThunk());
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/JSAttrCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSAttrCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSAttrCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -35,6 +35,7 @@
void JSAttr::visitAdditionalChildren(JSC::SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
if (Element* element = wrapped().ownerElement())
visitor.addOpaqueRoot(root(element));
}
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -51,6 +51,7 @@
void JSDOMWindow::visitAdditionalChildren(SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
if (Frame* frame = wrapped().frame())
visitor.addOpaqueRoot(frame);
}
Modified: trunk/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSIDBCursorCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -39,6 +39,7 @@
void JSIDBCursor::visitAdditionalChildren(SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
auto& cursor = wrapped();
if (auto* request = cursor.request())
visitor.addOpaqueRoot(request);
Modified: trunk/Source/WebCore/bindings/js/JSMessageChannelCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSMessageChannelCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSMessageChannelCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -35,6 +35,8 @@
void JSMessageChannel::visitAdditionalChildren(JSC::SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
+
if (MessagePort* port = wrapped().port1())
visitor.addOpaqueRoot(port);
Modified: trunk/Source/WebCore/bindings/js/JSMessagePortCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSMessagePortCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSMessagePortCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -33,6 +33,8 @@
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);
Modified: trunk/Source/WebCore/bindings/js/JSNodeIteratorCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSNodeIteratorCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSNodeIteratorCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -27,6 +27,8 @@
void JSNodeIterator::visitAdditionalChildren(JSC::SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
+
if (NodeFilter* filter = wrapped().filter())
visitor.addOpaqueRoot(filter);
}
Modified: trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -77,6 +77,8 @@
void JSTextTrackCue::visitAdditionalChildren(SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
+
if (TextTrack* textTrack = wrapped().track())
visitor.addOpaqueRoot(root(textTrack));
}
Modified: trunk/Source/WebCore/bindings/js/JSTreeWalkerCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSTreeWalkerCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSTreeWalkerCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -27,6 +27,8 @@
void JSTreeWalker::visitAdditionalChildren(JSC::SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
+
if (NodeFilter* filter = wrapped().filter())
visitor.addOpaqueRoot(filter);
}
Modified: trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -36,6 +36,8 @@
void JSWorkerGlobalScope::visitAdditionalChildren(SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
+
if (auto* location = wrapped().optionalLocation())
visitor.addOpaqueRoot(location);
if (auto* navigator = wrapped().optionalNavigator())
Modified: trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -58,6 +58,8 @@
void JSXMLHttpRequest::visitAdditionalChildren(SlotVisitor& visitor)
{
+ visitor.rescanAsConstraint();
+
if (XMLHttpRequestUpload* upload = wrapped().optionalUpload())
visitor.addOpaqueRoot(upload);
Modified: trunk/Source/WebCore/bindings/js/JSXPathResultCustom.cpp (209765 => 209766)
--- trunk/Source/WebCore/bindings/js/JSXPathResultCustom.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/bindings/js/JSXPathResultCustom.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -33,6 +33,8 @@
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.
Modified: trunk/Source/WebCore/dom/ContainerNodeAlgorithms.cpp (209765 => 209766)
--- trunk/Source/WebCore/dom/ContainerNodeAlgorithms.cpp 2016-12-13 19:44:06 UTC (rev 209765)
+++ trunk/Source/WebCore/dom/ContainerNodeAlgorithms.cpp 2016-12-13 19:54:15 UTC (rev 209766)
@@ -26,7 +26,6 @@
#include "config.h"
#include "ContainerNodeAlgorithms.h"
-#include "CommonVM.h"
#include "HTMLFrameOwnerElement.h"
#include "InspectorInstrumentation.h"
#include "NoEventDispatchAssertion.h"
@@ -102,8 +101,6 @@
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)
@@ -155,8 +152,6 @@
void notifyChildNodeRemoved(ContainerNode& insertionPoint, Node& child)
{
- writeBarrierOpaqueRoot([&child] () -> void* { return &child; });
-
if (!child.inDocument()) {
if (is<ContainerNode>(child))
notifyNodeRemovedFromTree(insertionPoint, downcast<ContainerNode>(child));