Heap::isMarked and friends should be instance methods
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Mar 2019 22:40:58 +0000 (22:40 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Mar 2019 22:40:58 +0000 (22:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179988

Reviewed by Saam Barati.

Almost all the callers of Heap::isMarked have VM& reference. We should make Heap::isMarked instance function instead of static function
so that we do not need to look up Heap from the cell.

* API/JSAPIWrapperObject.mm:
(JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
* API/JSMarkingConstraintPrivate.cpp:
(JSC::isMarked):
* API/glib/JSAPIWrapperObjectGLib.cpp:
(JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::finalizeUnconditionally):
* bytecode/AccessCase.cpp:
(JSC::AccessCase::visitWeak const):
(JSC::AccessCase::propagateTransitions const):
* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::visitWeak):
* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::finalize):
* bytecode/CallLinkStatus.h:
* bytecode/CallVariant.cpp:
(JSC::CallVariant::finalize):
* bytecode/CallVariant.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shouldJettisonDueToWeakReference):
(JSC::CodeBlock::shouldJettisonDueToOldAge):
(JSC::shouldMarkTransition):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::determineLiveness):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::jettison):
* bytecode/CodeBlock.h:
* bytecode/ExecutableToCodeBlockEdge.cpp:
(JSC::ExecutableToCodeBlockEdge::visitChildren):
(JSC::ExecutableToCodeBlockEdge::finalizeUnconditionally):
(JSC::ExecutableToCodeBlockEdge::runConstraint):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::finalize):
* bytecode/GetByIdStatus.h:
* bytecode/GetByIdVariant.cpp:
(JSC::GetByIdVariant::finalize):
* bytecode/GetByIdVariant.h:
* bytecode/InByIdStatus.cpp:
(JSC::InByIdStatus::finalize):
* bytecode/InByIdStatus.h:
* bytecode/InByIdVariant.cpp:
(JSC::InByIdVariant::finalize):
* bytecode/InByIdVariant.h:
* bytecode/ObjectPropertyCondition.cpp:
(JSC::ObjectPropertyCondition::isStillLive const):
* bytecode/ObjectPropertyCondition.h:
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::ObjectPropertyConditionSet::areStillLive const):
* bytecode/ObjectPropertyConditionSet.h:
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::visitWeak const):
* bytecode/PropertyCondition.cpp:
(JSC::PropertyCondition::isStillLive const):
* bytecode/PropertyCondition.h:
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::finalize):
* bytecode/PutByIdStatus.h:
* bytecode/PutByIdVariant.cpp:
(JSC::PutByIdVariant::finalize):
* bytecode/PutByIdVariant.h:
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::finalizeWithoutDeleting):
(JSC::RecordedStatuses::finalize):
* bytecode/RecordedStatuses.h:
* bytecode/StructureSet.cpp:
(JSC::StructureSet::isStillAlive const):
* bytecode/StructureSet.h:
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::visitWeakReferences):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::finalizeInGC):
(JSC::DFG::Plan::isKnownToBeLiveDuringGC):
* heap/GCIncomingRefCounted.h:
* heap/GCIncomingRefCountedInlines.h:
(JSC::GCIncomingRefCounted<T>::filterIncomingReferences):
* heap/GCIncomingRefCountedSet.h:
* heap/GCIncomingRefCountedSetInlines.h:
(JSC::GCIncomingRefCountedSet<T>::lastChanceToFinalize):
(JSC::GCIncomingRefCountedSet<T>::sweep):
(JSC::GCIncomingRefCountedSet<T>::removeAll): Deleted.
(JSC::GCIncomingRefCountedSet<T>::removeDead): Deleted.
* heap/Heap.cpp:
(JSC::Heap::addToRememberedSet):
(JSC::Heap::runEndPhase):
(JSC::Heap::sweepArrayBuffers):
(JSC::Heap::addCoreConstraints):
* heap/Heap.h:
* heap/HeapInlines.h:
(JSC::Heap::isMarked):
* heap/HeapSnapshotBuilder.cpp:
(JSC::HeapSnapshotBuilder::appendNode):
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::appendToMarkStack):
(JSC::SlotVisitor::visitChildren):
* jit/PolymorphicCallStubRoutine.cpp:
(JSC::PolymorphicCallStubRoutine::visitWeak):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finalizeUnconditionally):
* runtime/InferredValueInlines.h:
(JSC::InferredValue::finalizeUnconditionally):
* runtime/StackFrame.h:
(JSC::StackFrame::isMarked const):
* runtime/Structure.cpp:
(JSC::Structure::isCheapDuringGC):
(JSC::Structure::markIfCheap):
* runtime/Structure.h:
* runtime/TypeProfiler.cpp:
(JSC::TypeProfiler::invalidateTypeSetCache):
* runtime/TypeProfiler.h:
* runtime/TypeSet.cpp:
(JSC::TypeSet::invalidateCache):
* runtime/TypeSet.h:
* runtime/WeakMapImpl.cpp:
(JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::visitOutputConstraints):
* runtime/WeakMapImplInlines.h:
(JSC::WeakMapImpl<WeakMapBucket>::finalizeUnconditionally):

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

60 files changed:
Source/JavaScriptCore/API/JSAPIWrapperObject.mm
Source/JavaScriptCore/API/JSMarkingConstraintPrivate.cpp
Source/JavaScriptCore/API/glib/JSAPIWrapperObjectGLib.cpp
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
Source/JavaScriptCore/bytecode/AccessCase.cpp
Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
Source/JavaScriptCore/bytecode/CallLinkStatus.h
Source/JavaScriptCore/bytecode/CallVariant.cpp
Source/JavaScriptCore/bytecode/CallVariant.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/ExecutableToCodeBlockEdge.cpp
Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
Source/JavaScriptCore/bytecode/GetByIdStatus.h
Source/JavaScriptCore/bytecode/GetByIdVariant.cpp
Source/JavaScriptCore/bytecode/GetByIdVariant.h
Source/JavaScriptCore/bytecode/InByIdStatus.cpp
Source/JavaScriptCore/bytecode/InByIdStatus.h
Source/JavaScriptCore/bytecode/InByIdVariant.cpp
Source/JavaScriptCore/bytecode/InByIdVariant.h
Source/JavaScriptCore/bytecode/ObjectPropertyCondition.cpp
Source/JavaScriptCore/bytecode/ObjectPropertyCondition.h
Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp
Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
Source/JavaScriptCore/bytecode/PropertyCondition.cpp
Source/JavaScriptCore/bytecode/PropertyCondition.h
Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
Source/JavaScriptCore/bytecode/PutByIdStatus.h
Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
Source/JavaScriptCore/bytecode/PutByIdVariant.h
Source/JavaScriptCore/bytecode/RecordedStatuses.cpp
Source/JavaScriptCore/bytecode/RecordedStatuses.h
Source/JavaScriptCore/bytecode/StructureSet.cpp
Source/JavaScriptCore/bytecode/StructureSet.h
Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/heap/GCIncomingRefCounted.h
Source/JavaScriptCore/heap/GCIncomingRefCountedInlines.h
Source/JavaScriptCore/heap/GCIncomingRefCountedSet.h
Source/JavaScriptCore/heap/GCIncomingRefCountedSetInlines.h
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/HeapInlines.h
Source/JavaScriptCore/heap/HeapSnapshotBuilder.cpp
Source/JavaScriptCore/heap/SlotVisitor.cpp
Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp
Source/JavaScriptCore/runtime/ErrorInstance.cpp
Source/JavaScriptCore/runtime/InferredValueInlines.h
Source/JavaScriptCore/runtime/StackFrame.h
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/TypeProfiler.cpp
Source/JavaScriptCore/runtime/TypeProfiler.h
Source/JavaScriptCore/runtime/TypeSet.cpp
Source/JavaScriptCore/runtime/TypeSet.h
Source/JavaScriptCore/runtime/WeakMapImpl.cpp
Source/JavaScriptCore/runtime/WeakMapImplInlines.h

index 8a84bf7..58b74e7 100644 (file)
@@ -63,7 +63,7 @@ bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::
     // the same Objective-C object in multiple global objects keeps all of the global objects alive.
     if (!wrapperObject->wrappedObject())
         return false;
-    return JSC::Heap::isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
+    return visitor.vm().heap.isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
 }
 
 namespace JSC {
index dd4bab7..d9ee674 100644 (file)
@@ -40,12 +40,12 @@ struct Marker : JSMarker {
     SlotVisitor* visitor;
 };
 
-bool isMarked(JSMarkerRef, JSObjectRef objectRef)
+bool isMarked(JSMarkerRef markerRef, JSObjectRef objectRef)
 {
     if (!objectRef)
         return true; // Null is an immortal object.
     
-    return Heap::isMarked(toJS(objectRef));
+    return static_cast<Marker*>(markerRef)->visitor->vm().heap.isMarked(toJS(objectRef));
 }
 
 void mark(JSMarkerRef markerRef, JSObjectRef objectRef)
index 87d198c..867fd42 100644 (file)
@@ -62,7 +62,7 @@ bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::
     // the same wrapped object in multiple global objects keeps all of the global objects alive.
     if (!wrapperObject->wrappedObject())
         return false;
-    return JSC::Heap::isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
+    return visitor.vm().heap.isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
 }
 
 namespace JSC {
index 53f8a9e..3e729ce 100644 (file)
@@ -1,3 +1,132 @@
+2019-03-25  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        Heap::isMarked and friends should be instance methods
+        https://bugs.webkit.org/show_bug.cgi?id=179988
+
+        Reviewed by Saam Barati.
+
+        Almost all the callers of Heap::isMarked have VM& reference. We should make Heap::isMarked instance function instead of static function
+        so that we do not need to look up Heap from the cell.
+
+        * API/JSAPIWrapperObject.mm:
+        (JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
+        * API/JSMarkingConstraintPrivate.cpp:
+        (JSC::isMarked):
+        * API/glib/JSAPIWrapperObjectGLib.cpp:
+        (JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::finalizeUnconditionally):
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::visitWeak const):
+        (JSC::AccessCase::propagateTransitions const):
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::finalize):
+        * bytecode/CallLinkStatus.h:
+        * bytecode/CallVariant.cpp:
+        (JSC::CallVariant::finalize):
+        * bytecode/CallVariant.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::shouldJettisonDueToWeakReference):
+        (JSC::CodeBlock::shouldJettisonDueToOldAge):
+        (JSC::shouldMarkTransition):
+        (JSC::CodeBlock::propagateTransitions):
+        (JSC::CodeBlock::determineLiveness):
+        (JSC::CodeBlock::finalizeLLIntInlineCaches):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::jettison):
+        * bytecode/CodeBlock.h:
+        * bytecode/ExecutableToCodeBlockEdge.cpp:
+        (JSC::ExecutableToCodeBlockEdge::visitChildren):
+        (JSC::ExecutableToCodeBlockEdge::finalizeUnconditionally):
+        (JSC::ExecutableToCodeBlockEdge::runConstraint):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::finalize):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/GetByIdVariant.cpp:
+        (JSC::GetByIdVariant::finalize):
+        * bytecode/GetByIdVariant.h:
+        * bytecode/InByIdStatus.cpp:
+        (JSC::InByIdStatus::finalize):
+        * bytecode/InByIdStatus.h:
+        * bytecode/InByIdVariant.cpp:
+        (JSC::InByIdVariant::finalize):
+        * bytecode/InByIdVariant.h:
+        * bytecode/ObjectPropertyCondition.cpp:
+        (JSC::ObjectPropertyCondition::isStillLive const):
+        * bytecode/ObjectPropertyCondition.h:
+        * bytecode/ObjectPropertyConditionSet.cpp:
+        (JSC::ObjectPropertyConditionSet::areStillLive const):
+        * bytecode/ObjectPropertyConditionSet.h:
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::PolymorphicAccess::visitWeak const):
+        * bytecode/PropertyCondition.cpp:
+        (JSC::PropertyCondition::isStillLive const):
+        * bytecode/PropertyCondition.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::finalize):
+        * bytecode/PutByIdStatus.h:
+        * bytecode/PutByIdVariant.cpp:
+        (JSC::PutByIdVariant::finalize):
+        * bytecode/PutByIdVariant.h:
+        * bytecode/RecordedStatuses.cpp:
+        (JSC::RecordedStatuses::finalizeWithoutDeleting):
+        (JSC::RecordedStatuses::finalize):
+        * bytecode/RecordedStatuses.h:
+        * bytecode/StructureSet.cpp:
+        (JSC::StructureSet::isStillAlive const):
+        * bytecode/StructureSet.h:
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::visitWeakReferences):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::finalizeInGC):
+        (JSC::DFG::Plan::isKnownToBeLiveDuringGC):
+        * heap/GCIncomingRefCounted.h:
+        * heap/GCIncomingRefCountedInlines.h:
+        (JSC::GCIncomingRefCounted<T>::filterIncomingReferences):
+        * heap/GCIncomingRefCountedSet.h:
+        * heap/GCIncomingRefCountedSetInlines.h:
+        (JSC::GCIncomingRefCountedSet<T>::lastChanceToFinalize):
+        (JSC::GCIncomingRefCountedSet<T>::sweep):
+        (JSC::GCIncomingRefCountedSet<T>::removeAll): Deleted.
+        (JSC::GCIncomingRefCountedSet<T>::removeDead): Deleted.
+        * heap/Heap.cpp:
+        (JSC::Heap::addToRememberedSet):
+        (JSC::Heap::runEndPhase):
+        (JSC::Heap::sweepArrayBuffers):
+        (JSC::Heap::addCoreConstraints):
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::isMarked):
+        * heap/HeapSnapshotBuilder.cpp:
+        (JSC::HeapSnapshotBuilder::appendNode):
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::appendToMarkStack):
+        (JSC::SlotVisitor::visitChildren):
+        * jit/PolymorphicCallStubRoutine.cpp:
+        (JSC::PolymorphicCallStubRoutine::visitWeak):
+        * runtime/ErrorInstance.cpp:
+        (JSC::ErrorInstance::finalizeUnconditionally):
+        * runtime/InferredValueInlines.h:
+        (JSC::InferredValue::finalizeUnconditionally):
+        * runtime/StackFrame.h:
+        (JSC::StackFrame::isMarked const):
+        * runtime/Structure.cpp:
+        (JSC::Structure::isCheapDuringGC):
+        (JSC::Structure::markIfCheap):
+        * runtime/Structure.h:
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::invalidateTypeSetCache):
+        * runtime/TypeProfiler.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::invalidateCache):
+        * runtime/TypeSet.h:
+        * runtime/WeakMapImpl.cpp:
+        (JSC::WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::visitOutputConstraints):
+        * runtime/WeakMapImplInlines.h:
+        (JSC::WeakMapImpl<WeakMapBucket>::finalizeUnconditionally):
+
 2019-03-25  Keith Miller  <keith_miller@apple.com>
 
         ASSERTION FAILED: m_op == CompareStrictEq in JSC::DFG::Node::convertToCompareEqPtr(JSC::DFG::FrozenValue *, JSC::DFG::Edge)
index 84baccc..4830a56 100644 (file)
@@ -262,7 +262,7 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S
 void BuiltinExecutables::finalizeUnconditionally()
 {
     for (auto*& unlinkedExecutable : m_unlinkedExecutables) {
-        if (unlinkedExecutable && !Heap::isMarked(unlinkedExecutable))
+        if (unlinkedExecutable && !m_vm.heap.isMarked(unlinkedExecutable))
             unlinkedExecutable = nullptr;
     }
 }
index 1877231..9059811 100644 (file)
@@ -323,34 +323,34 @@ void AccessCase::dump(PrintStream& out) const
 
 bool AccessCase::visitWeak(VM& vm) const
 {
-    if (m_structure && !Heap::isMarked(m_structure.get()))
+    if (m_structure && !vm.heap.isMarked(m_structure.get()))
         return false;
     if (m_polyProtoAccessChain) {
         for (Structure* structure : m_polyProtoAccessChain->chain()) {
-            if (!Heap::isMarked(structure))
+            if (!vm.heap.isMarked(structure))
                 return false;
         }
     }
-    if (!m_conditionSet.areStillLive())
+    if (!m_conditionSet.areStillLive(vm))
         return false;
     if (isAccessor()) {
         auto& accessor = this->as<GetterSetterAccessCase>();
         if (accessor.callLinkInfo())
             accessor.callLinkInfo()->visitWeak(vm);
-        if (accessor.customSlotBase() && !Heap::isMarked(accessor.customSlotBase()))
+        if (accessor.customSlotBase() && !vm.heap.isMarked(accessor.customSlotBase()))
             return false;
     } else if (type() == IntrinsicGetter) {
         auto& intrinsic = this->as<IntrinsicGetterAccessCase>();
-        if (intrinsic.intrinsicFunction() && !Heap::isMarked(intrinsic.intrinsicFunction()))
+        if (intrinsic.intrinsicFunction() && !vm.heap.isMarked(intrinsic.intrinsicFunction()))
             return false;
     } else if (type() == ModuleNamespaceLoad) {
         auto& accessCase = this->as<ModuleNamespaceAccessCase>();
-        if (accessCase.moduleNamespaceObject() && !Heap::isMarked(accessCase.moduleNamespaceObject()))
+        if (accessCase.moduleNamespaceObject() && !vm.heap.isMarked(accessCase.moduleNamespaceObject()))
             return false;
-        if (accessCase.moduleEnvironment() && !Heap::isMarked(accessCase.moduleEnvironment()))
+        if (accessCase.moduleEnvironment() && !vm.heap.isMarked(accessCase.moduleEnvironment()))
             return false;
     } else if (type() == InstanceOfHit || type() == InstanceOfMiss) {
-        if (as<InstanceOfAccessCase>().prototype() && !Heap::isMarked(as<InstanceOfAccessCase>().prototype()))
+        if (as<InstanceOfAccessCase>().prototype() && !vm.heap.isMarked(as<InstanceOfAccessCase>().prototype()))
             return false;
     }
 
@@ -371,7 +371,7 @@ bool AccessCase::propagateTransitions(SlotVisitor& visitor) const
 
     switch (m_type) {
     case Transition:
-        if (Heap::isMarked(m_structure->previousID()))
+        if (visitor.vm().heap.isMarked(m_structure->previousID()))
             visitor.appendUnbarriered(m_structure.get());
         else
             result = false;
index c0a3778..deae383 100644 (file)
@@ -210,7 +210,7 @@ void CallLinkInfo::setMaxNumArguments(unsigned value)
 void CallLinkInfo::visitWeak(VM& vm)
 {
     auto handleSpecificCallee = [&] (JSFunction* callee) {
-        if (Heap::isMarked(callee->executable()))
+        if (vm.heap.isMarked(callee->executable()))
             m_hasSeenClosure = true;
         else
             m_clearedByGC = true;
@@ -228,7 +228,7 @@ void CallLinkInfo::visitWeak(VM& vm)
                 unlink(vm);
                 m_clearedByGC = true;
             }
-        } else if (!Heap::isMarked(m_calleeOrCodeBlock.get())) {
+        } else if (!vm.heap.isMarked(m_calleeOrCodeBlock.get())) {
             if (isDirect()) {
                 if (Options::verboseOSR()) {
                     dataLog(
@@ -252,7 +252,7 @@ void CallLinkInfo::visitWeak(VM& vm)
                 }
             }
             unlink(vm);
-        } else if (isDirect() && !Heap::isMarked(m_lastSeenCalleeOrExecutable.get())) {
+        } else if (isDirect() && !vm.heap.isMarked(m_lastSeenCalleeOrExecutable.get())) {
             if (Options::verboseOSR()) {
                 dataLog(
                     "Clearing call to ", RawPointer(executable()),
@@ -264,7 +264,7 @@ void CallLinkInfo::visitWeak(VM& vm)
             m_lastSeenCalleeOrExecutable.clear();
         }
     }
-    if (!isDirect() && haveLastSeenCallee() && !Heap::isMarked(lastSeenCallee())) {
+    if (!isDirect() && haveLastSeenCallee() && !vm.heap.isMarked(lastSeenCallee())) {
         if (lastSeenCallee()->type() == JSFunctionType)
             handleSpecificCallee(jsCast<JSFunction*>(lastSeenCallee()));
         else
index 157a271..32aa6ca 100644 (file)
@@ -418,10 +418,10 @@ void CallLinkStatus::makeClosureCall()
     m_variants = despecifiedVariantList(m_variants);
 }
 
-bool CallLinkStatus::finalize()
+bool CallLinkStatus::finalize(VM& vm)
 {
     for (CallVariant& variant : m_variants) {
-        if (!variant.finalize())
+        if (!variant.finalize(vm))
             return false;
     }
     return true;
index 3a40c92..f0ed407 100644 (file)
@@ -106,7 +106,7 @@ public:
     
     unsigned maxNumArguments() const { return m_maxNumArguments; }
     
-    bool finalize();
+    bool finalize(VM&);
     
     void merge(const CallLinkStatus&);
     
index d20ea93..7169786 100644 (file)
@@ -31,9 +31,9 @@
 
 namespace JSC {
 
-bool CallVariant::finalize()
+bool CallVariant::finalize(VM& vm)
 {
-    if (m_callee && !Heap::isMarked(m_callee))
+    if (m_callee && !vm.heap.isMarked(m_callee))
         return false;
     return true;
 }
index 8cedae6..5a1c55c 100644 (file)
@@ -137,7 +137,7 @@ public:
         return nullptr;
     }
     
-    bool finalize();
+    bool finalize(VM&);
     
     bool merge(const CallVariant&);
     
index 6289a56..b5949b1 100644 (file)
@@ -998,11 +998,11 @@ bool CodeBlock::shouldVisitStrongly(const ConcurrentJSLocker& locker)
     return false;
 }
 
-bool CodeBlock::shouldJettisonDueToWeakReference()
+bool CodeBlock::shouldJettisonDueToWeakReference(VM& vm)
 {
     if (!JITCode::isOptimizingJIT(jitType()))
         return false;
-    return !Heap::isMarked(this);
+    return !vm.heap.isMarked(this);
 }
 
 static Seconds timeToLive(JITCode::JITType jitType)
@@ -1040,7 +1040,7 @@ static Seconds timeToLive(JITCode::JITType jitType)
 
 bool CodeBlock::shouldJettisonDueToOldAge(const ConcurrentJSLocker&)
 {
-    if (Heap::isMarked(this))
+    if (m_vm->heap.isMarked(this))
         return false;
 
     if (UNLIKELY(Options::forceCodeBlockToJettisonDueToOldAge()))
@@ -1053,12 +1053,12 @@ bool CodeBlock::shouldJettisonDueToOldAge(const ConcurrentJSLocker&)
 }
 
 #if ENABLE(DFG_JIT)
-static bool shouldMarkTransition(DFG::WeakReferenceTransition& transition)
+static bool shouldMarkTransition(VM& vm, DFG::WeakReferenceTransition& transition)
 {
-    if (transition.m_codeOrigin && !Heap::isMarked(transition.m_codeOrigin.get()))
+    if (transition.m_codeOrigin && !vm.heap.isMarked(transition.m_codeOrigin.get()))
         return false;
     
-    if (!Heap::isMarked(transition.m_from.get()))
+    if (!vm.heap.isMarked(transition.m_from.get()))
         return false;
     
     return true;
@@ -1086,7 +1086,7 @@ void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, SlotVisitor& vis
                     vm.heap.structureIDTable().get(oldStructureID);
                 Structure* newStructure =
                     vm.heap.structureIDTable().get(newStructureID);
-                if (Heap::isMarked(oldStructure))
+                if (vm.heap.isMarked(oldStructure))
                     visitor.appendUnbarriered(newStructure);
                 continue;
             }
@@ -1112,7 +1112,7 @@ void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, SlotVisitor& vis
             weakReference->markIfCheap(visitor);
 
         for (auto& transition : dfgCommon->transitions) {
-            if (shouldMarkTransition(transition)) {
+            if (shouldMarkTransition(vm, transition)) {
                 // If the following three things are live, then the target of the
                 // transition is also live:
                 //
@@ -1144,7 +1144,8 @@ void CodeBlock::determineLiveness(const ConcurrentJSLocker&, SlotVisitor& visito
     UNUSED_PARAM(visitor);
     
 #if ENABLE(DFG_JIT)
-    if (Heap::isMarked(this))
+    VM& vm = *m_vm;
+    if (vm.heap.isMarked(this))
         return;
     
     // In rare and weird cases, this could be called on a baseline CodeBlock. One that I found was
@@ -1160,15 +1161,15 @@ void CodeBlock::determineLiveness(const ConcurrentJSLocker&, SlotVisitor& visito
     bool allAreLiveSoFar = true;
     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
         JSCell* reference = dfgCommon->weakReferences[i].get();
-        ASSERT(!jsDynamicCast<CodeBlock*>(*reference->vm(), reference));
-        if (!Heap::isMarked(reference)) {
+        ASSERT(!jsDynamicCast<CodeBlock*>(vm, reference));
+        if (!vm.heap.isMarked(reference)) {
             allAreLiveSoFar = false;
             break;
         }
     }
     if (allAreLiveSoFar) {
         for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) {
-            if (!Heap::isMarked(dfgCommon->weakStructureReferences[i].get())) {
+            if (!vm.heap.isMarked(dfgCommon->weakStructureReferences[i].get())) {
                 allAreLiveSoFar = false;
                 break;
             }
@@ -1191,13 +1192,13 @@ void CodeBlock::finalizeLLIntInlineCaches()
     VM& vm = *m_vm;
     const Vector<InstructionStream::Offset>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
 
-    auto handleGetPutFromScope = [](auto& metadata) {
+    auto handleGetPutFromScope = [&] (auto& metadata) {
         GetPutInfo getPutInfo = metadata.m_getPutInfo;
         if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks 
             || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
             return;
         WriteBarrierBase<Structure>& structure = metadata.m_structure;
-        if (!structure || Heap::isMarked(structure.get()))
+        if (!structure || vm.heap.isMarked(structure.get()))
             return;
         if (Options::verboseOSR())
             dataLogF("Clearing scope access with structure %p.\n", structure.get());
@@ -1213,7 +1214,7 @@ void CodeBlock::finalizeLLIntInlineCaches()
             if (metadata.m_mode != GetByIdMode::Default)
                 break;
             StructureID oldStructureID = metadata.m_modeMetadata.defaultMode.structureID;
-            if (!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
+            if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
                 break;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt property access.\n");
@@ -1223,7 +1224,7 @@ void CodeBlock::finalizeLLIntInlineCaches()
         case op_get_by_id_direct: {
             auto& metadata = curInstruction->as<OpGetByIdDirect>().metadata(this);
             StructureID oldStructureID = metadata.m_structureID;
-            if (!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
+            if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
                 break;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt property access.\n");
@@ -1236,9 +1237,9 @@ void CodeBlock::finalizeLLIntInlineCaches()
             StructureID oldStructureID = metadata.m_oldStructureID;
             StructureID newStructureID = metadata.m_newStructureID;
             StructureChain* chain = metadata.m_structureChain.get();
-            if ((!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
-                && (!newStructureID || Heap::isMarked(vm.heap.structureIDTable().get(newStructureID)))
-                && (!chain || Heap::isMarked(chain)))
+            if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
+                && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))
+                && (!chain || vm.heap.isMarked(chain)))
                 break;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt put transition.\n");
@@ -1254,7 +1255,7 @@ void CodeBlock::finalizeLLIntInlineCaches()
             break;
         case op_to_this: {
             auto& metadata = curInstruction->as<OpToThis>().metadata(this);
-            if (!metadata.m_cachedStructure || Heap::isMarked(metadata.m_cachedStructure.get()))
+            if (!metadata.m_cachedStructure || vm.heap.isMarked(metadata.m_cachedStructure.get()))
                 break;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt to_this with structure %p.\n", metadata.m_cachedStructure.get());
@@ -1268,7 +1269,7 @@ void CodeBlock::finalizeLLIntInlineCaches()
             if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
                 break;
             JSCell* cachedFunction = cacheWriteBarrier.get();
-            if (Heap::isMarked(cachedFunction))
+            if (vm.heap.isMarked(cachedFunction))
                 break;
             if (Options::verboseOSR())
                 dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction);
@@ -1281,7 +1282,7 @@ void CodeBlock::finalizeLLIntInlineCaches()
             // to the symbol table strongly. But it's nice to be on the safe side.
             auto& metadata = curInstruction->as<OpResolveScope>().metadata(this);
             WriteBarrierBase<SymbolTable>& symbolTable = metadata.m_symbolTable;
-            if (!symbolTable || Heap::isMarked(symbolTable.get()))
+            if (!symbolTable || vm.heap.isMarked(symbolTable.get()))
                 break;
             if (Options::verboseOSR())
                 dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get());
@@ -1314,11 +1315,11 @@ void CodeBlock::finalizeLLIntInlineCaches()
             return true;
         };
 
-        if (!Heap::isMarked(std::get<0>(pair.key)))
+        if (!vm.heap.isMarked(std::get<0>(pair.key)))
             return clear();
 
         for (const LLIntPrototypeLoadAdaptiveStructureWatchpoint* watchpoint : pair.value) {
-            if (!watchpoint->key().isStillLive())
+            if (!watchpoint->key().isStillLive(vm))
                 return clear();
         }
 
@@ -1326,12 +1327,12 @@ void CodeBlock::finalizeLLIntInlineCaches()
     });
 
     forEachLLIntCallLinkInfo([&](LLIntCallLinkInfo& callLinkInfo) {
-        if (callLinkInfo.isLinked() && !Heap::isMarked(callLinkInfo.callee.get())) {
+        if (callLinkInfo.isLinked() && !vm.heap.isMarked(callLinkInfo.callee.get())) {
             if (Options::verboseOSR())
                 dataLog("Clearing LLInt call from ", *this, "\n");
             callLinkInfo.unlink();
         }
-        if (!!callLinkInfo.lastSeenCallee && !Heap::isMarked(callLinkInfo.lastSeenCallee.get()))
+        if (!!callLinkInfo.lastSeenCallee && !vm.heap.isMarked(callLinkInfo.lastSeenCallee.get()))
             callLinkInfo.lastSeenCallee.clear();
     });
 }
@@ -1356,8 +1357,10 @@ void CodeBlock::finalizeBaselineJITInlineCaches()
 }
 #endif
 
-void CodeBlock::finalizeUnconditionally(VM&)
+void CodeBlock::finalizeUnconditionally(VM& vm)
 {
+    UNUSED_PARAM(vm);
+
     updateAllPredictions();
     
     if (JITCode::couldBeInterpreted(jitType()))
@@ -1371,7 +1374,7 @@ void CodeBlock::finalizeUnconditionally(VM&)
 #if ENABLE(DFG_JIT)
     if (JITCode::isOptimizingJIT(jitType())) {
         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
-        dfgCommon->recordedStatuses.finalize();
+        dfgCommon->recordedStatuses.finalize(vm);
     }
 #endif // ENABLE(DFG_JIT)
 
@@ -1952,6 +1955,8 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
     UNUSED_PARAM(mode);
     UNUSED_PARAM(detail);
 #endif
+
+    VM& vm = *m_vm;
     
     CODEBLOCK_LOG_EVENT(this, "jettison", ("due to ", reason, ", counting = ", mode == CountReoptimization, ", detail = ", pointerDump(detail)));
 
@@ -1976,13 +1981,13 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
                 JSCell* origin = transition.m_codeOrigin.get();
                 JSCell* from = transition.m_from.get();
                 JSCell* to = transition.m_to.get();
-                if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from))
+                if ((!origin || vm.heap.isMarked(origin)) && vm.heap.isMarked(from))
                     continue;
                 dataLog("    Transition under ", RawPointer(origin), ", ", RawPointer(from), " -> ", RawPointer(to), ".\n");
             }
             for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
                 JSCell* weak = dfgCommon->weakReferences[i].get();
-                if (Heap::isMarked(weak))
+                if (vm.heap.isMarked(weak))
                     continue;
                 dataLog("    Weak reference ", RawPointer(weak), ".\n");
             }
@@ -1990,7 +1995,6 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
     }
 #endif // ENABLE(DFG_JIT)
 
-    VM& vm = *m_vm;
     DeferGCForAWhile deferGC(*heap());
     
     // We want to accomplish two things here:
@@ -2010,7 +2014,7 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
         // This accomplishes (1), and does its own book-keeping about whether it has already happened.
         if (!jitCode()->dfgCommon()->invalidate()) {
             // We've already been invalidated.
-            RELEASE_ASSERT(this != replacement() || (vm.heap.isCurrentThreadBusy() && !Heap::isMarked(ownerExecutable())));
+            RELEASE_ASSERT(this != replacement() || (vm.heap.isCurrentThreadBusy() && !vm.heap.isMarked(ownerExecutable())));
             return;
         }
     }
@@ -2042,7 +2046,7 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
 
     // Jettison can happen during GC. We don't want to install code to a dead executable
     // because that would add a dead object to the remembered set.
-    if (vm.heap.isCurrentThreadBusy() && !Heap::isMarked(ownerExecutable()))
+    if (vm.heap.isCurrentThreadBusy() && !vm.heap.isMarked(ownerExecutable()))
         return;
 
     // This accomplishes (2).
index 5eecb77..52d01ba 100644 (file)
@@ -919,7 +919,7 @@ private:
     }
 
     bool shouldVisitStrongly(const ConcurrentJSLocker&);
-    bool shouldJettisonDueToWeakReference();
+    bool shouldJettisonDueToWeakReference(VM&);
     bool shouldJettisonDueToOldAge(const ConcurrentJSLocker&);
     
     void propagateTransitions(const ConcurrentJSLocker&, SlotVisitor&);
index 14d2d36..fc37783 100644 (file)
@@ -75,7 +75,7 @@ void ExecutableToCodeBlockEdge::visitChildren(JSCell* cell, SlotVisitor& visitor
     if (codeBlock->shouldVisitStrongly(locker))
         visitor.appendUnbarriered(codeBlock);
     
-    if (!Heap::isMarked(codeBlock))
+    if (!vm.heap.isMarked(codeBlock))
         vm.executableToCodeBlockEdgesWithFinalizers.add(edge);
     
     if (JITCode::isOptimizingJIT(codeBlock->jitType())) {
@@ -125,8 +125,8 @@ void ExecutableToCodeBlockEdge::finalizeUnconditionally(VM& vm)
 {
     CodeBlock* codeBlock = m_codeBlock.get();
     
-    if (!Heap::isMarked(codeBlock)) {
-        if (codeBlock->shouldJettisonDueToWeakReference())
+    if (!vm.heap.isMarked(codeBlock)) {
+        if (codeBlock->shouldJettisonDueToWeakReference(vm))
             codeBlock->jettison(Profiler::JettisonDueToWeakReference);
         else
             codeBlock->jettison(Profiler::JettisonDueToOldAge);
@@ -189,7 +189,7 @@ void ExecutableToCodeBlockEdge::runConstraint(const ConcurrentJSLocker& locker,
     codeBlock->propagateTransitions(locker, visitor);
     codeBlock->determineLiveness(locker, visitor);
     
-    if (Heap::isMarked(codeBlock))
+    if (vm.heap.isMarked(codeBlock))
         vm.executableToCodeBlockEdgesWithConstraints.remove(this);
 }
 
index 558bb24..26bcd5f 100644 (file)
@@ -476,15 +476,15 @@ void GetByIdStatus::markIfCheap(SlotVisitor& visitor)
         variant.markIfCheap(visitor);
 }
 
-bool GetByIdStatus::finalize()
+bool GetByIdStatus::finalize(VM& vm)
 {
     for (GetByIdVariant& variant : m_variants) {
-        if (!variant.finalize())
+        if (!variant.finalize(vm))
             return false;
     }
-    if (m_moduleNamespaceObject && !Heap::isMarked(m_moduleNamespaceObject))
+    if (m_moduleNamespaceObject && !vm.heap.isMarked(m_moduleNamespaceObject))
         return false;
-    if (m_moduleEnvironment && !Heap::isMarked(m_moduleEnvironment))
+    if (m_moduleEnvironment && !vm.heap.isMarked(m_moduleEnvironment))
         return false;
     return true;
 }
index 19dd067..47675b7 100644 (file)
@@ -141,7 +141,7 @@ public:
     ScopeOffset scopeOffset() const { return m_scopeOffset; }
     
     void markIfCheap(SlotVisitor&);
-    bool finalize(); // Return true if this gets to live.
+    bool finalize(VM&); // Return true if this gets to live.
     
     void dump(PrintStream&) const;
     
index ee25e7f..fc1f460 100644 (file)
@@ -149,15 +149,15 @@ void GetByIdVariant::markIfCheap(SlotVisitor& visitor)
     m_structureSet.markIfCheap(visitor);
 }
 
-bool GetByIdVariant::finalize()
+bool GetByIdVariant::finalize(VM& vm)
 {
-    if (!m_structureSet.isStillAlive())
+    if (!m_structureSet.isStillAlive(vm))
         return false;
-    if (!m_conditionSet.areStillLive())
+    if (!m_conditionSet.areStillLive(vm))
         return false;
-    if (m_callLinkStatus && !m_callLinkStatus->finalize())
+    if (m_callLinkStatus && !m_callLinkStatus->finalize(vm))
         return false;
-    if (m_intrinsicFunction && !Heap::isMarked(m_intrinsicFunction))
+    if (m_intrinsicFunction && !vm.heap.isMarked(m_intrinsicFunction))
         return false;
     return true;
 }
index bfa3112..8d6af00 100644 (file)
@@ -74,7 +74,7 @@ public:
     bool attemptToMerge(const GetByIdVariant& other);
     
     void markIfCheap(SlotVisitor&);
-    bool finalize();
+    bool finalize(VM&);
     
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
index 6399cec..b4588b5 100644 (file)
@@ -258,10 +258,10 @@ void InByIdStatus::markIfCheap(SlotVisitor& visitor)
         variant.markIfCheap(visitor);
 }
 
-bool InByIdStatus::finalize()
+bool InByIdStatus::finalize(VM& vm)
 {
     for (InByIdVariant& variant : m_variants) {
-        if (!variant.finalize())
+        if (!variant.finalize(vm))
             return false;
     }
     return true;
index 57ab9ed..f686d2c 100644 (file)
@@ -106,7 +106,7 @@ public:
     void filter(const StructureSet&);
     
     void markIfCheap(SlotVisitor&);
-    bool finalize();
+    bool finalize(VM&);
 
     void dump(PrintStream&) const;
 
index e2e8fa6..0b37f53 100644 (file)
@@ -72,11 +72,11 @@ void InByIdVariant::markIfCheap(SlotVisitor& visitor)
     m_structureSet.markIfCheap(visitor);
 }
 
-bool InByIdVariant::finalize()
+bool InByIdVariant::finalize(VM& vm)
 {
-    if (!m_structureSet.isStillAlive())
+    if (!m_structureSet.isStillAlive(vm))
         return false;
-    if (!m_conditionSet.areStillLive())
+    if (!m_conditionSet.areStillLive(vm))
         return false;
     return true;
 }
index dd20911..429a1f5 100644 (file)
@@ -57,7 +57,7 @@ public:
     bool attemptToMerge(const InByIdVariant& other);
     
     void markIfCheap(SlotVisitor&);
-    bool finalize();
+    bool finalize(VM&);
 
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
index 3aad094..f3e3a7c 100644 (file)
@@ -142,15 +142,15 @@ bool ObjectPropertyCondition::isWatchable(PropertyCondition::WatchabilityEffort
     return isWatchable(m_object->structure(), effort);
 }
 
-bool ObjectPropertyCondition::isStillLive() const
+bool ObjectPropertyCondition::isStillLive(VM& vm) const
 {
     if (!*this)
         return false;
     
-    if (!Heap::isMarked(m_object))
+    if (!vm.heap.isMarked(m_object))
         return false;
     
-    return m_condition.isStillLive();
+    return m_condition.isStillLive(vm);
 }
 
 void ObjectPropertyCondition::validateReferences(const TrackedReferences& tracked) const
index d0331a0..68934df 100644 (file)
@@ -244,7 +244,7 @@ public:
     }
     
     // This means that the objects involved in this are still live.
-    bool isStillLive() const;
+    bool isStillLive(VM&) const;
     
     void validateReferences(const TrackedReferences&) const;
 
index 2d1963a..2c60d6b 100644 (file)
@@ -141,10 +141,10 @@ bool ObjectPropertyConditionSet::needImpurePropertyWatchpoint() const
     return false;
 }
 
-bool ObjectPropertyConditionSet::areStillLive() const
+bool ObjectPropertyConditionSet::areStillLive(VM& vm) const
 {
     for (const ObjectPropertyCondition& condition : *this) {
-        if (!condition.isStillLive())
+        if (!condition.isStillLive(vm))
             return false;
     }
     return true;
index 8e53a1b..054290c 100644 (file)
@@ -111,7 +111,7 @@ public:
     bool structuresEnsureValidityAssumingImpurePropertyWatchpoint() const;
     
     bool needImpurePropertyWatchpoint() const;
-    bool areStillLive() const;
+    bool areStillLive(VM&) const;
     
     void dumpInContext(PrintStream&, DumpContext*) const;
     void dump(PrintStream&) const;
index b68089d..dbc3923 100644 (file)
@@ -324,7 +324,7 @@ bool PolymorphicAccess::visitWeak(VM& vm) const
     }
     if (Vector<WriteBarrier<JSCell>>* weakReferences = m_weakReferences.get()) {
         for (WriteBarrier<JSCell>& weakReference : *weakReferences) {
-            if (!Heap::isMarked(weakReference.get()))
+            if (!vm.heap.isMarked(weakReference.get()))
                 return false;
         }
     }
index 8b1a4cc..a3296ad 100644 (file)
@@ -352,15 +352,15 @@ bool PropertyCondition::isWatchable(
         && isWatchableWhenValid(structure, effort);
 }
 
-bool PropertyCondition::isStillLive() const
+bool PropertyCondition::isStillLive(VM& vm) const
 {
-    if (hasPrototype() && prototype() && !Heap::isMarked(prototype()))
+    if (hasPrototype() && prototype() && !vm.heap.isMarked(prototype()))
         return false;
     
     if (hasRequiredValue()
         && requiredValue()
         && requiredValue().isCell()
-        && !Heap::isMarked(requiredValue().asCell()))
+        && !vm.heap.isMarked(requiredValue().asCell()))
         return false;
     
     return true;
index 8acb119..db59de3 100644 (file)
@@ -297,7 +297,7 @@ public:
     }
     
     // This means that the objects involved in this are still live.
-    bool isStillLive() const;
+    bool isStillLive(VM&) const;
     
     void validateReferences(const TrackedReferences&) const;
 
index 4db8bd1..c2d9532 100644 (file)
@@ -386,10 +386,10 @@ void PutByIdStatus::markIfCheap(SlotVisitor& visitor)
         variant.markIfCheap(visitor);
 }
 
-bool PutByIdStatus::finalize()
+bool PutByIdStatus::finalize(VM& vm)
 {
     for (PutByIdVariant& variant : m_variants) {
-        if (!variant.finalize())
+        if (!variant.finalize(vm))
             return false;
     }
     return true;
index 4c45785..19b978a 100644 (file)
@@ -116,7 +116,7 @@ public:
     const PutByIdVariant& operator[](size_t index) const { return at(index); }
     
     void markIfCheap(SlotVisitor&);
-    bool finalize();
+    bool finalize(VM&);
     
     void merge(const PutByIdStatus&);
     
index 88dee07..5d6b290 100644 (file)
@@ -270,15 +270,15 @@ void PutByIdVariant::markIfCheap(SlotVisitor& visitor)
         m_newStructure->markIfCheap(visitor);
 }
 
-bool PutByIdVariant::finalize()
+bool PutByIdVariant::finalize(VM& vm)
 {
-    if (!m_oldStructure.isStillAlive())
+    if (!m_oldStructure.isStillAlive(vm))
         return false;
-    if (m_newStructure && !Heap::isMarked(m_newStructure))
+    if (m_newStructure && !vm.heap.isMarked(m_newStructure))
         return false;
-    if (!m_conditionSet.areStillLive())
+    if (!m_conditionSet.areStillLive(vm))
         return false;
-    if (m_callLinkStatus && !m_callLinkStatus->finalize())
+    if (m_callLinkStatus && !m_callLinkStatus->finalize(vm))
         return false;
     return true;
 }
index 3636c8c..caadd32 100644 (file)
@@ -132,7 +132,7 @@ public:
     bool attemptToMerge(const PutByIdVariant& other);
     
     void markIfCheap(SlotVisitor&);
-    bool finalize();
+    bool finalize(VM&);
     
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
index 3d7e13e..96d22ec 100644 (file)
@@ -85,28 +85,28 @@ void RecordedStatuses::markIfCheap(SlotVisitor& slotVisitor)
         pair.second->markIfCheap(slotVisitor);
 }
 
-void RecordedStatuses::finalizeWithoutDeleting()
+void RecordedStatuses::finalizeWithoutDeleting(VM& vm)
 {
     // This variant of finalize gets called from within graph safepoints -- so there may be DFG IR in
     // some compiler thread that points to the statuses. That thread is stopped at a safepoint so
     // it's OK to edit its data structure, but it's not OK to delete them. Hence we don't remove
     // anything from the vector or delete the unique_ptrs.
     
-    auto finalize = [] (auto& vector) {
+    auto finalize = [&] (auto& vector) {
         for (auto& pair : vector) {
-            if (!pair.second->finalize())
+            if (!pair.second->finalize(vm))
                 *pair.second = { };
         }
     };
     forEachVector(finalize);
 }
 
-void RecordedStatuses::finalize()
+void RecordedStatuses::finalize(VM& vm)
 {
-    auto finalize = [] (auto& vector) {
+    auto finalize = [&] (auto& vector) {
         vector.removeAllMatching(
             [&] (auto& pair) -> bool {
-                return !*pair.second || !pair.second->finalize();
+                return !*pair.second || !pair.second->finalize(vm);
             });
         vector.shrinkToFit();
     };
index fc03bd2..a03b4f6 100644 (file)
@@ -50,8 +50,8 @@ struct RecordedStatuses {
     
     void markIfCheap(SlotVisitor& slotVisitor);
     
-    void finalizeWithoutDeleting();
-    void finalize();
+    void finalizeWithoutDeleting(VM&);
+    void finalize(VM&);
     
     void shrinkToFit();
     
index 20e616f..928b82c 100644 (file)
@@ -37,10 +37,10 @@ void StructureSet::markIfCheap(SlotVisitor& visitor) const
         structure->markIfCheap(visitor);
 }
 
-bool StructureSet::isStillAlive() const
+bool StructureSet::isStillAlive(VM& vm) const
 {
     for (Structure* structure : *this) {
-        if (!Heap::isMarked(structure))
+        if (!vm.heap.isMarked(structure))
             return false;
     }
     return true;
index 39a8f02..9f8f104 100644 (file)
@@ -55,7 +55,7 @@ public:
     }
 
     void markIfCheap(SlotVisitor&) const;
-    bool isStillAlive() const;
+    bool isStillAlive(VM&) const;
     
     void dumpInContext(PrintStream&, DumpContext*) const;
     void dump(PrintStream&) const;
index 354ccf4..77f2c2a 100644 (file)
@@ -272,14 +272,14 @@ void StructureStubInfo::visitWeakReferences(CodeBlock* codeBlock)
     
     bufferedStructures.genericFilter(
         [&] (Structure* structure) -> bool {
-            return Heap::isMarked(structure);
+            return vm.heap.isMarked(structure);
         });
 
     switch (cacheType) {
     case CacheType::GetByIdSelf:
     case CacheType::PutByIdReplace:
     case CacheType::InByIdSelf:
-        if (Heap::isMarked(u.byIdSelf.baseObjectStructure.get()))
+        if (vm.heap.isMarked(u.byIdSelf.baseObjectStructure.get()))
             return;
         break;
     case CacheType::Stub:
index 94caefb..900a61f 100644 (file)
@@ -664,18 +664,19 @@ void Plan::checkLivenessAndVisitChildren(SlotVisitor& visitor)
 
 void Plan::finalizeInGC()
 {
-    m_recordedStatuses.finalizeWithoutDeleting();
+    ASSERT(m_vm);
+    m_recordedStatuses.finalizeWithoutDeleting(*m_vm);
 }
 
 bool Plan::isKnownToBeLiveDuringGC()
 {
     if (m_stage == Cancelled)
         return false;
-    if (!Heap::isMarked(m_codeBlock->ownerExecutable()))
+    if (!m_vm->heap.isMarked(m_codeBlock->ownerExecutable()))
         return false;
-    if (!Heap::isMarked(m_codeBlock->alternative()))
+    if (!m_vm->heap.isMarked(m_codeBlock->alternative()))
         return false;
-    if (!!m_profiledDFGCodeBlock && !Heap::isMarked(m_profiledDFGCodeBlock))
+    if (!!m_profiledDFGCodeBlock && !m_vm->heap.isMarked(m_profiledDFGCodeBlock))
         return false;
     return true;
 }
index 1d336bf..0fe6b8a 100644 (file)
@@ -82,7 +82,7 @@ public:
     // to use this with a filter function that can return false unless
     // you're also walking the GC's list.
     template<typename FilterFunctionType>
-    bool filterIncomingReferences(FilterFunctionType&);
+    bool filterIncomingReferences(FilterFunctionType&&);
     
 private:
     static uintptr_t singletonFlag() { return 1; }
index a1a91e2..35d4199 100644 (file)
@@ -57,7 +57,7 @@ bool GCIncomingRefCounted<T>::addIncomingReference(JSCell* cell)
 
 template<typename T>
 template<typename FilterFunctionType>
-bool GCIncomingRefCounted<T>::filterIncomingReferences(FilterFunctionType& filterFunction)
+bool GCIncomingRefCounted<T>::filterIncomingReferences(FilterFunctionType&& filterFunction)
 {
     const bool verbose = false;
     
index 0b43519..c73a897 100644 (file)
@@ -41,14 +41,11 @@ public:
     // Returns true if the native object is new to this set.
     bool addReference(JSCell*, T*);
     
-    void sweep();
+    void sweep(VM&);
     
     size_t size() const { return m_bytes; };
     
 private:
-    static bool removeAll(JSCell*);
-    static bool removeDead(JSCell*);
-    
     Vector<T*> m_vector;
     size_t m_bytes;
 };
index b10972d..33ef4d0 100644 (file)
@@ -40,7 +40,7 @@ template<typename T>
 void GCIncomingRefCountedSet<T>::lastChanceToFinalize()
 {
     for (size_t i = m_vector.size(); i--;)
-        m_vector[i]->filterIncomingReferences(removeAll);
+        m_vector[i]->filterIncomingReferences([] (JSCell*) { return false; });
 }
 
 template<typename T>
@@ -59,14 +59,14 @@ bool GCIncomingRefCountedSet<T>::addReference(JSCell* cell, T* object)
 }
 
 template<typename T>
-void GCIncomingRefCountedSet<T>::sweep()
+void GCIncomingRefCountedSet<T>::sweep(VM& vm)
 {
     for (size_t i = 0; i < m_vector.size(); ++i) {
         T* object = m_vector[i];
         size_t size = object->gcSizeEstimateInBytes();
         ASSERT(object->isDeferred());
         ASSERT(object->numberOfIncomingReferences());
-        if (!object->filterIncomingReferences(removeDead))
+        if (!object->filterIncomingReferences([&] (JSCell* cell) { return vm.heap.isMarked(cell); }))
             continue;
         m_bytes -= size;
         m_vector[i--] = m_vector.last();
@@ -74,16 +74,4 @@ void GCIncomingRefCountedSet<T>::sweep()
     }
 }
 
-template<typename T>
-bool GCIncomingRefCountedSet<T>::removeAll(JSCell*)
-{
-    return false;
-}
-
-template<typename T>
-bool GCIncomingRefCountedSet<T>::removeDead(JSCell* cell)
-{
-    return Heap::isMarked(cell);
-}
-
 } // namespace JSC
index 7fdb72a..9ddd137 100644 (file)
@@ -1010,7 +1010,7 @@ void Heap::addToRememberedSet(const JSCell* constCell)
             return;
         }
     } else
-        ASSERT(Heap::isMarked(cell));
+        ASSERT(isMarked(cell));
     // It could be that the object was *just* marked. This means that the collector may set the
     // state to DefinitelyGrey and then to PossiblyOldOrBlack at any time. It's OK for us to
     // race with the collector here. If we win then this is accurate because the object _will_
@@ -1494,7 +1494,7 @@ NEVER_INLINE bool Heap::runEndPhase(GCConductor conn)
     }
         
     if (vm()->typeProfiler())
-        vm()->typeProfiler()->invalidateTypeSetCache();
+        vm()->typeProfiler()->invalidateTypeSetCache(*vm());
 
     reapWeakHandles();
     pruneStaleEntriesFromWeakGCMaps();
@@ -2212,7 +2212,7 @@ void Heap::pruneStaleEntriesFromWeakGCMaps()
 
 void Heap::sweepArrayBuffers()
 {
-    m_arrayBuffers.sweep();
+    m_arrayBuffers.sweep(*vm());
 }
 
 void Heap::snapshotUnswept()
@@ -2833,7 +2833,7 @@ void Heap::addCoreConstraints()
             iterateExecutingAndCompilingCodeBlocksWithoutHoldingLocks(
                 [&] (CodeBlock* codeBlock) {
                     // Visit the CodeBlock as a constraint only if it's black.
-                    if (Heap::isMarked(codeBlock)
+                    if (isMarked(codeBlock)
                         && codeBlock->cellState() == CellState::PossiblyBlack)
                         slotVisitor.visitAsConstraint(codeBlock);
                 });
index 86ade6e..38f5321 100644 (file)
@@ -123,7 +123,7 @@ public:
     // our scan to run faster. 
     static const unsigned s_timeCheckResolution = 16;
 
-    static bool isMarked(const void*);
+    bool isMarked(const void*);
     static bool testAndSetMarked(HeapVersion, const void*);
     
     static size_t cellSize(const void*);
index f5b0d49..f8d3c12 100644 (file)
@@ -68,15 +68,13 @@ inline bool Heap::worldIsStopped() const
     return m_worldIsStopped;
 }
 
-// FIXME: This should be an instance method, so that it can get the markingVersion() quickly.
-// https://bugs.webkit.org/show_bug.cgi?id=179988
 ALWAYS_INLINE bool Heap::isMarked(const void* rawCell)
 {
     HeapCell* cell = bitwise_cast<HeapCell*>(rawCell);
     if (cell->isLargeAllocation())
         return cell->largeAllocation().isMarked();
     MarkedBlock& block = cell->markedBlock();
-    return block.isMarked(block.vm()->heap.objectSpace().markingVersion(), cell);
+    return block.isMarked(m_objectSpace.markingVersion(), cell);
 }
 
 ALWAYS_INLINE bool Heap::testAndSetMarked(HeapVersion markingVersion, const void* rawCell)
index a581bb5..5b9ac89 100644 (file)
@@ -80,7 +80,7 @@ void HeapSnapshotBuilder::appendNode(JSCell* cell)
 {
     ASSERT(m_profiler.activeSnapshotBuilder() == this);
 
-    ASSERT(Heap::isMarked(cell));
+    ASSERT(m_profiler.vm().heap.isMarked(cell));
 
     NodeIdentifier identifier;
     if (previousSnapshotHasNodeForCell(cell, identifier))
index 2b03d0a..6ac467a 100644 (file)
@@ -285,7 +285,7 @@ void SlotVisitor::appendToMarkStack(JSCell* cell)
 template<typename ContainerType>
 ALWAYS_INLINE void SlotVisitor::appendToMarkStack(ContainerType& container, JSCell* cell)
 {
-    ASSERT(Heap::isMarked(cell));
+    ASSERT(m_heap.isMarked(cell));
     ASSERT(!cell->isZapped());
     
     container.noteMarked();
@@ -354,7 +354,7 @@ private:
 
 ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell)
 {
-    ASSERT(Heap::isMarked(cell));
+    ASSERT(m_heap.isMarked(cell));
     
     SetCurrentCellScope currentCellScope(*this, cell);
     
index f037c73..7cf74b1 100644 (file)
@@ -130,10 +130,10 @@ void PolymorphicCallStubRoutine::clearCallNodesFor(CallLinkInfo* info)
     }
 }
 
-bool PolymorphicCallStubRoutine::visitWeak(VM&)
+bool PolymorphicCallStubRoutine::visitWeak(VM& vm)
 {
     for (auto& variant : m_variants) {
-        if (!Heap::isMarked(variant.get()))
+        if (!vm.heap.isMarked(variant.get()))
             return false;
     }
     return true;
index 7b09e0a..2da121b 100644 (file)
@@ -212,7 +212,7 @@ void ErrorInstance::finalizeUnconditionally(VM& vm)
     // If we did, we might end up keeping functions (and their global objects) alive that happened to
     // get caught in a trace.
     for (const auto& frame : *m_stackTrace.get()) {
-        if (!frame.isMarked()) {
+        if (!frame.isMarked(vm)) {
             computeErrorInfo(vm);
             return;
         }
index 95114e4..c143687 100644 (file)
@@ -34,7 +34,7 @@ void InferredValue::finalizeUnconditionally(VM& vm)
     JSValue value = m_value.get();
     
     if (value && value.isCell()) {
-        if (Heap::isMarked(value.asCell()))
+        if (vm.heap.isMarked(value.asCell()))
             return;
         
         invalidate(vm, StringFireDetail("InferredValue clean-up during GC"));
index 5eedee6..5daa157 100644 (file)
@@ -58,7 +58,7 @@ public:
     }
     
     void visitChildren(SlotVisitor&);
-    bool isMarked() const { return (!m_callee || Heap::isMarked(m_callee.get())) && (!m_codeBlock || Heap::isMarked(m_codeBlock.get())); }
+    bool isMarked(VM& vm) const { return (!m_callee || vm.heap.isMarked(m_callee.get())) && (!m_codeBlock || vm.heap.isMarked(m_codeBlock.get())); }
 
 private:
     WriteBarrier<JSCell> m_callee { };
index 3ca96ad..ff38bb9 100644 (file)
@@ -1054,20 +1054,21 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
         thisObject->m_propertyTableUnsafe.clear();
 }
 
-bool Structure::isCheapDuringGC()
+bool Structure::isCheapDuringGC(VM& vm)
 {
     // FIXME: We could make this even safer by returning false if this structure's property table
     // has any large property names.
     // https://bugs.webkit.org/show_bug.cgi?id=157334
     
-    return (!m_globalObject || Heap::isMarked(m_globalObject.get()))
-        && (hasPolyProto() || !storedPrototypeObject() || Heap::isMarked(storedPrototypeObject()));
+    return (!m_globalObject || vm.heap.isMarked(m_globalObject.get()))
+        && (hasPolyProto() || !storedPrototypeObject() || vm.heap.isMarked(storedPrototypeObject()));
 }
 
 bool Structure::markIfCheap(SlotVisitor& visitor)
 {
-    if (!isCheapDuringGC())
-        return Heap::isMarked(this);
+    VM& vm = visitor.vm();
+    if (!isCheapDuringGC(vm))
+        return vm.heap.isMarked(this);
     
     visitor.appendUnbarriered(this);
     return true;
index e409b72..4b0d031 100644 (file)
@@ -299,7 +299,7 @@ public:
     // increase in footprint because no other object refers to that global object. This method
     // returns true if all user-controlled (and hence unbounded in size) objects referenced from the
     // Structure are already marked.
-    bool isCheapDuringGC();
+    bool isCheapDuringGC(VM&);
     
     // Returns true if this structure is now marked.
     bool markIfCheap(SlotVisitor&);
index 0f85ef8..8a6d5c0 100644 (file)
@@ -148,13 +148,13 @@ TypeLocation* TypeProfiler::nextTypeLocation()
     return m_typeLocationInfo.add(); 
 }
 
-void TypeProfiler::invalidateTypeSetCache()
+void TypeProfiler::invalidateTypeSetCache(VM& vm)
 {
     for (Bag<TypeLocation>::iterator iter = m_typeLocationInfo.begin(); !!iter; ++iter) {
         TypeLocation* location = *iter;
-        location->m_instructionTypeSet->invalidateCache();
+        location->m_instructionTypeSet->invalidateCache(vm);
         if (location->m_globalTypeSet)
-            location->m_globalTypeSet->invalidateCache();
+            location->m_globalTypeSet->invalidateCache(vm);
     }
 }
 
index 55282ea..a2cb71f 100644 (file)
@@ -124,7 +124,7 @@ public:
     TypeLocation* findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor, VM&);
     GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
     TypeLocation* nextTypeLocation();
-    void invalidateTypeSetCache();
+    void invalidateTypeSetCache(VM&);
     void dumpTypeProfilerData(VM&);
     
 private:
index b8dc6ba..410eb6d 100644 (file)
@@ -79,10 +79,12 @@ void TypeSet::addTypeInformation(RuntimeType type, RefPtr<StructureShape>&& pass
     }
 }
 
-void TypeSet::invalidateCache()
+void TypeSet::invalidateCache(VM& vm)
 {
     ConcurrentJSLocker locker(m_lock);
-    auto keepMarkedStructuresFilter = [] (Structure* structure) -> bool { return Heap::isMarked(structure); };
+    auto keepMarkedStructuresFilter = [&] (Structure* structure) -> bool {
+        return vm.heap.isMarked(structure);
+    };
     m_structureSet.genericFilter(keepMarkedStructuresFilter);
 }
 
index d76ba95..80bb407 100644 (file)
@@ -86,7 +86,7 @@ public:
     static Ref<TypeSet> create() { return adoptRef(*new TypeSet); }
     TypeSet();
     void addTypeInformation(RuntimeType, RefPtr<StructureShape>&&, Structure*, bool sawPolyProtoStructure);
-    void invalidateCache();
+    void invalidateCache(VM&);
     String dumpTypes() const;
     String displayName() const;
     Ref<JSON::ArrayOf<Inspector::Protocol::Runtime::StructureDescription>> allStructureRepresentations() const;
index e7caca9..b8aaa2f 100644 (file)
@@ -64,6 +64,7 @@ void WeakMapImpl<WeakMapBucket<WeakMapBucketDataKey>>::visitOutputConstraints(JS
 template <>
 void WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::visitOutputConstraints(JSCell* cell, SlotVisitor& visitor)
 {
+    VM& vm = visitor.vm();
     auto* thisObject = jsCast<WeakMapImpl*>(cell);
     auto locker = holdLock(thisObject->cellLock());
     auto* buffer = thisObject->buffer();
@@ -71,7 +72,7 @@ void WeakMapImpl<WeakMapBucket<WeakMapBucketDataKeyValue>>::visitOutputConstrain
         auto* bucket = buffer + index;
         if (bucket->isEmpty() || bucket->isDeleted())
             continue;
-        if (!Heap::isMarked(bucket->key()))
+        if (!vm.heap.isMarked(bucket->key()))
             continue;
         bucket->visitAggregate(visitor);
     }
index a7b8b99..997b926 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
 
 // Note that this function can be executed in parallel as long as the mutator stops.
 template<typename WeakMapBucket>
-void WeakMapImpl<WeakMapBucket>::finalizeUnconditionally(VM&)
+void WeakMapImpl<WeakMapBucket>::finalizeUnconditionally(VM& vm)
 {
     auto* buffer = this->buffer();
     for (uint32_t index = 0; index < m_capacity; ++index) {
@@ -39,7 +39,7 @@ void WeakMapImpl<WeakMapBucket>::finalizeUnconditionally(VM&)
         if (bucket->isEmpty() || bucket->isDeleted())
             continue;
 
-        if (Heap::isMarked(bucket->key()))
+        if (vm.heap.isMarked(bucket->key()))
             continue;
 
         bucket->makeDeleted();