Title: [250184] trunk
Revision
250184
Author
tzaga...@apple.com
Date
2019-09-21 11:30:29 -0700 (Sat, 21 Sep 2019)

Log Message

AccessCase should strongly visit its dependencies while on stack
https://bugs.webkit.org/show_bug.cgi?id=201986
<rdar://problem/55521953>

Reviewed by Saam Barati and Yusuke Suzuki.

JSTests:

* stress/ftl-put-by-id-setter-exception-interesting-live-state-2.js: Added.
(foo):
(warmup):

Source/_javascript_Core:

AccessCase::doesCalls is responsible for specifying the cells it depends on, so that
MarkingGCAwareJITStubRoutine can strongly visit them while the stub is on stack. However,
it was missing most of its dependencies, which led to it being collected while on stack.
This manifested in the flaky test stress/ftl-put-by-id-setter-exception-interesting-live-state.js
as the PolymorphicAccess being collected and removing its exception handler from the code
block, which led to exception propagating past the try/catch.

In order to fix this, we abstract the dependency gathering logic from AccessCase into
forEachDependentCell and use it to implement visitWeak as well as doesCalls in order to
guarantee that their implementation is consistent.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::visitWeak const):
* bytecode/AccessCase.h:
* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::lastSeenCallee const):
(JSC::CallLinkInfo::haveLastSeenCallee const):
(JSC::CallLinkInfo::lastSeenCallee): Deleted.
(JSC::CallLinkInfo::haveLastSeenCallee): Deleted.
* bytecode/CallLinkInfo.h:
(JSC::CallLinkInfo::isDirect const):
(JSC::CallLinkInfo::isLinked const):
(JSC::CallLinkInfo::stub const):
(JSC::CallLinkInfo::forEachDependentCell const):
(JSC::CallLinkInfo::isLinked): Deleted.
(JSC::CallLinkInfo::stub): Deleted.
* bytecode/ObjectPropertyCondition.cpp:
(JSC::ObjectPropertyCondition::isStillLive const):
* bytecode/ObjectPropertyCondition.h:
(JSC::ObjectPropertyCondition::forEachDependentCell const):
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::ObjectPropertyConditionSet::areStillLive const):
* bytecode/ObjectPropertyConditionSet.h:
(JSC::ObjectPropertyConditionSet::forEachDependentCell const):
* bytecode/PropertyCondition.cpp:
(JSC::PropertyCondition::isStillLive const):
* bytecode/PropertyCondition.h:
(JSC::PropertyCondition::forEachDependentCell const):
* jit/PolymorphicCallStubRoutine.cpp:
(JSC::PolymorphicCallStubRoutine::visitWeak):
* jit/PolymorphicCallStubRoutine.h:
(JSC::PolymorphicCallStubRoutine::forEachDependentCell):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (250183 => 250184)


--- trunk/JSTests/ChangeLog	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/JSTests/ChangeLog	2019-09-21 18:30:29 UTC (rev 250184)
@@ -1,3 +1,15 @@
+2019-09-21  Tadeu Zagallo  <tzaga...@apple.com>
+
+        AccessCase should strongly visit its dependencies while on stack
+        https://bugs.webkit.org/show_bug.cgi?id=201986
+        <rdar://problem/55521953>
+
+        Reviewed by Saam Barati and Yusuke Suzuki.
+
+        * stress/ftl-put-by-id-setter-exception-interesting-live-state-2.js: Added.
+        (foo):
+        (warmup):
+
 2019-09-20  Saam Barati  <sbar...@apple.com>
 
         Unreviewed. Make toctou-having-a-bad-time-new-array.js run for less time because it's timing out on the debug bots.

Added: trunk/JSTests/stress/ftl-put-by-id-setter-exception-interesting-live-state-2.js (0 => 250184)


--- trunk/JSTests/stress/ftl-put-by-id-setter-exception-interesting-live-state-2.js	                        (rev 0)
+++ trunk/JSTests/stress/ftl-put-by-id-setter-exception-interesting-live-state-2.js	2019-09-21 18:30:29 UTC (rev 250184)
@@ -0,0 +1,40 @@
+function foo(o, p) {
+    var x = 100;
+    var result = 101;
+    var pf = p.g;
+    try {
+        x = 102;
+        pf++;
+        o.f = x + pf;
+        o = 104;
+        pf++;
+        x = 106;
+    } catch (e) {
+        return {outcome: "exception", values: [o, pf, x]};
+    }
+    return {outcome: "return", values: [o, pf, x]};
+}
+
+noInline(foo);
+
+function warmup() {
+    var o = {};
+    o.__defineSetter__("f", function(value) {
+        this._f = value;
+    });
+    if (i & 1)
+        o["i" + i] = i; // Make it polymorphic.
+    var result = foo(o, {g:200});
+}
+noInline(warmup);
+
+// Warm up foo() with polymorphic objects and getters.
+for (var i = 0; i < 100000; ++i) {
+    warmup();
+}
+
+var o = {};
+o.__defineSetter__("f", function() {
+    throw "Error42";
+});
+var result = foo(o, {g:300});

Modified: trunk/Source/_javascript_Core/ChangeLog (250183 => 250184)


--- trunk/Source/_javascript_Core/ChangeLog	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-09-21 18:30:29 UTC (rev 250184)
@@ -1,3 +1,56 @@
+2019-09-21  Tadeu Zagallo  <tzaga...@apple.com>
+
+        AccessCase should strongly visit its dependencies while on stack
+        https://bugs.webkit.org/show_bug.cgi?id=201986
+        <rdar://problem/55521953>
+
+        Reviewed by Saam Barati and Yusuke Suzuki.
+
+        AccessCase::doesCalls is responsible for specifying the cells it depends on, so that
+        MarkingGCAwareJITStubRoutine can strongly visit them while the stub is on stack. However,
+        it was missing most of its dependencies, which led to it being collected while on stack.
+        This manifested in the flaky test stress/ftl-put-by-id-setter-exception-interesting-live-state.js
+        as the PolymorphicAccess being collected and removing its exception handler from the code
+        block, which led to exception propagating past the try/catch.
+
+        In order to fix this, we abstract the dependency gathering logic from AccessCase into
+        forEachDependentCell and use it to implement visitWeak as well as doesCalls in order to
+        guarantee that their implementation is consistent.
+
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::forEachDependentCell const):
+        (JSC::AccessCase::doesCalls const):
+        (JSC::AccessCase::visitWeak const):
+        * bytecode/AccessCase.h:
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::lastSeenCallee const):
+        (JSC::CallLinkInfo::haveLastSeenCallee const):
+        (JSC::CallLinkInfo::lastSeenCallee): Deleted.
+        (JSC::CallLinkInfo::haveLastSeenCallee): Deleted.
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::isDirect const):
+        (JSC::CallLinkInfo::isLinked const):
+        (JSC::CallLinkInfo::stub const):
+        (JSC::CallLinkInfo::forEachDependentCell const):
+        (JSC::CallLinkInfo::isLinked): Deleted.
+        (JSC::CallLinkInfo::stub): Deleted.
+        * bytecode/ObjectPropertyCondition.cpp:
+        (JSC::ObjectPropertyCondition::isStillLive const):
+        * bytecode/ObjectPropertyCondition.h:
+        (JSC::ObjectPropertyCondition::forEachDependentCell const):
+        * bytecode/ObjectPropertyConditionSet.cpp:
+        (JSC::ObjectPropertyConditionSet::areStillLive const):
+        * bytecode/ObjectPropertyConditionSet.h:
+        (JSC::ObjectPropertyConditionSet::forEachDependentCell const):
+        * bytecode/PropertyCondition.cpp:
+        (JSC::PropertyCondition::isStillLive const):
+        * bytecode/PropertyCondition.h:
+        (JSC::PropertyCondition::forEachDependentCell const):
+        * jit/PolymorphicCallStubRoutine.cpp:
+        (JSC::PolymorphicCallStubRoutine::visitWeak):
+        * jit/PolymorphicCallStubRoutine.h:
+        (JSC::PolymorphicCallStubRoutine::forEachDependentCell):
+
 2019-09-21  David Kilzer  <ddkil...@apple.com>
 
         clang-tidy: Fix unnecessary copy/ref churn of for loop variables in WTF/_javascript_Core

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2019-09-21 18:30:29 UTC (rev 250184)
@@ -203,27 +203,109 @@
     }
 }
 
-bool AccessCase::doesCalls(Vector<JSCell*>* cellsToMark) const
+template<typename Functor>
+void AccessCase::forEachDependentCell(const Functor& functor) const
 {
+    m_conditionSet.forEachDependentCell(functor);
+    if (m_structure)
+        functor(m_structure.get());
+    if (m_polyProtoAccessChain) {
+        for (Structure* structure : m_polyProtoAccessChain->chain())
+            functor(structure);
+    }
+
     switch (type()) {
     case Getter:
+    case Setter: {
+        auto& accessor = this->as<GetterSetterAccessCase>();
+        if (accessor.callLinkInfo())
+            accessor.callLinkInfo()->forEachDependentCell(functor);
+        break;
+    }
+    case CustomValueGetter:
+    case CustomValueSetter: {
+        auto& accessor = this->as<GetterSetterAccessCase>();
+        if (accessor.customSlotBase())
+            functor(accessor.customSlotBase());
+        break;
+    }
+    case IntrinsicGetter: {
+        auto& intrinsic = this->as<IntrinsicGetterAccessCase>();
+        if (intrinsic.intrinsicFunction())
+            functor(intrinsic.intrinsicFunction());
+        break;
+    }
+    case ModuleNamespaceLoad: {
+        auto& accessCase = this->as<ModuleNamespaceAccessCase>();
+        if (accessCase.moduleNamespaceObject())
+            functor(accessCase.moduleNamespaceObject());
+        if (accessCase.moduleEnvironment())
+            functor(accessCase.moduleEnvironment());
+        break;
+    }
+    case InstanceOfHit:
+    case InstanceOfMiss:
+        if (as<InstanceOfAccessCase>().prototype())
+            functor(as<InstanceOfAccessCase>().prototype());
+        break;
+    case CustomAccessorGetter:
+    case CustomAccessorSetter:
+    case Load:
+    case Transition:
+    case Replace:
+    case Miss:
+    case GetGetter:
+    case InHit:
+    case InMiss:
+    case ArrayLength:
+    case StringLength:
+    case DirectArgumentsLength:
+    case ScopedArgumentsLength:
+    case InstanceOfGeneric:
+        break;
+    }
+}
+
+bool AccessCase::doesCalls(Vector<JSCell*>* cellsToMarkIfDoesCalls) const
+{
+    bool doesCalls;
+    switch (type()) {
+    case Transition:
+        doesCalls = newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity() && structure()->couldHaveIndexingHeader();
+        break;
+    case Getter:
     case Setter:
     case CustomValueGetter:
     case CustomAccessorGetter:
     case CustomValueSetter:
     case CustomAccessorSetter:
-        return true;
-    case Transition:
-        if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()
-            && structure()->couldHaveIndexingHeader()) {
-            if (cellsToMark)
-                cellsToMark->append(newStructure());
-            return true;
-        }
-        return false;
-    default:
-        return false;
+        doesCalls = true;
+        break;
+    case Load:
+    case Replace:
+    case Miss:
+    case GetGetter:
+    case IntrinsicGetter:
+    case InHit:
+    case InMiss:
+    case ArrayLength:
+    case StringLength:
+    case DirectArgumentsLength:
+    case ScopedArgumentsLength:
+    case ModuleNamespaceLoad:
+    case InstanceOfHit:
+    case InstanceOfMiss:
+    case InstanceOfGeneric:
+        doesCalls = false;
+        break;
     }
+
+    if (doesCalls && cellsToMarkIfDoesCalls) {
+        forEachDependentCell([&](JSCell* cell) {
+            cellsToMarkIfDoesCalls->append(cell);
+        });
+    }
+    return doesCalls;
 }
 
 bool AccessCase::couldStillSucceed() const
@@ -321,38 +403,17 @@
 
 bool AccessCase::visitWeak(VM& vm) const
 {
-    if (m_structure && !vm.heap.isMarked(m_structure.get()))
-        return false;
-    if (m_polyProtoAccessChain) {
-        for (Structure* structure : m_polyProtoAccessChain->chain()) {
-            if (!vm.heap.isMarked(structure))
-                return false;
-        }
-    }
-    if (!m_conditionSet.areStillLive(vm))
-        return false;
     if (isAccessor()) {
         auto& accessor = this->as<GetterSetterAccessCase>();
         if (accessor.callLinkInfo())
             accessor.callLinkInfo()->visitWeak(vm);
-        if (accessor.customSlotBase() && !vm.heap.isMarked(accessor.customSlotBase()))
-            return false;
-    } else if (type() == IntrinsicGetter) {
-        auto& intrinsic = this->as<IntrinsicGetterAccessCase>();
-        if (intrinsic.intrinsicFunction() && !vm.heap.isMarked(intrinsic.intrinsicFunction()))
-            return false;
-    } else if (type() == ModuleNamespaceLoad) {
-        auto& accessCase = this->as<ModuleNamespaceAccessCase>();
-        if (accessCase.moduleNamespaceObject() && !vm.heap.isMarked(accessCase.moduleNamespaceObject()))
-            return false;
-        if (accessCase.moduleEnvironment() && !vm.heap.isMarked(accessCase.moduleEnvironment()))
-            return false;
-    } else if (type() == InstanceOfHit || type() == InstanceOfMiss) {
-        if (as<InstanceOfAccessCase>().prototype() && !vm.heap.isMarked(as<InstanceOfAccessCase>().prototype()))
-            return false;
     }
 
-    return true;
+    bool isValid = true;
+    forEachDependentCell([&](JSCell* cell) {
+        isValid &= vm.heap.isMarked(cell);
+    });
+    return isValid;
 }
 
 bool AccessCase::propagateTransitions(SlotVisitor& visitor) const

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.h (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.h	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.h	2019-09-21 18:30:29 UTC (rev 250184)
@@ -219,6 +219,9 @@
     friend class CodeBlock;
     friend class PolymorphicAccess;
 
+    template<typename Functor>
+    void forEachDependentCell(const Functor&) const;
+
     bool visitWeak(VM&) const;
     bool propagateTransitions(SlotVisitor&) const;
 

Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp	2019-09-21 18:30:29 UTC (rev 250184)
@@ -166,13 +166,13 @@
     m_lastSeenCalleeOrExecutable.clear();
 }
 
-JSObject* CallLinkInfo::lastSeenCallee()
+JSObject* CallLinkInfo::lastSeenCallee() const
 {
     RELEASE_ASSERT(!isDirect());
     return jsCast<JSObject*>(m_lastSeenCalleeOrExecutable.get());
 }
 
-bool CallLinkInfo::haveLastSeenCallee()
+bool CallLinkInfo::haveLastSeenCallee() const
 {
     RELEASE_ASSERT(!isDirect());
     return !!m_lastSeenCalleeOrExecutable;

Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h	2019-09-21 18:30:29 UTC (rev 250184)
@@ -134,7 +134,7 @@
         return callModeFor(static_cast<CallType>(m_callType));
     }
 
-    bool isDirect()
+    bool isDirect() const
     {
         return isDirect(static_cast<CallType>(m_callType));
     }
@@ -154,7 +154,7 @@
         return isVarargsCallType(static_cast<CallType>(m_callType));
     }
 
-    bool isLinked() { return m_stub || m_calleeOrCodeBlock; }
+    bool isLinked() const { return m_stub || m_calleeOrCodeBlock; }
     void unlink(VM&);
 
     void setUpCall(CallType callType, CodeOrigin codeOrigin, GPRReg calleeGPR)
@@ -201,8 +201,8 @@
 
     void setLastSeenCallee(VM&, const JSCell* owner, JSObject* callee);
     void clearLastSeenCallee();
-    JSObject* lastSeenCallee();
-    bool haveLastSeenCallee();
+    JSObject* lastSeenCallee() const;
+    bool haveLastSeenCallee() const;
     
     void setExecutableDuringCompilation(ExecutableBase*);
     ExecutableBase* executable();
@@ -215,7 +215,7 @@
 
     void clearStub();
 
-    PolymorphicCallStubRoutine* stub()
+    PolymorphicCallStubRoutine* stub() const
     {
         return m_stub.get();
     }
@@ -332,6 +332,22 @@
         return m_codeOrigin;
     }
 
+    template<typename Functor>
+    void forEachDependentCell(const Functor& functor) const
+    {
+        if (isLinked()) {
+            if (stub())
+                stub()->forEachDependentCell(functor);
+            else {
+                functor(m_calleeOrCodeBlock.get());
+                if (isDirect())
+                    functor(m_lastSeenCalleeOrExecutable.get());
+            }
+        }
+        if (!isDirect() && haveLastSeenCallee())
+            functor(lastSeenCallee());
+    }
+
     void visitWeak(VM&);
 
     void setFrameShuffleData(const CallFrameShuffleData&);

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.cpp (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.cpp	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.cpp	2019-09-21 18:30:29 UTC (rev 250184)
@@ -147,10 +147,11 @@
     if (!*this)
         return false;
     
-    if (!vm.heap.isMarked(m_object))
-        return false;
-    
-    return m_condition.isStillLive(vm);
+    bool isStillLive = true;
+    forEachDependentCell([&](JSCell* cell) {
+        isStillLive &= vm.heap.isMarked(cell);
+    });
+    return isStillLive;
 }
 
 void ObjectPropertyCondition::validateReferences(const TrackedReferences& tracked) const

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.h (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.h	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.h	2019-09-21 18:30:29 UTC (rev 250184)
@@ -242,6 +242,13 @@
     {
         return condition().watchingRequiresReplacementWatchpoint();
     }
+
+    template<typename Functor>
+    void forEachDependentCell(const Functor& functor) const
+    {
+        functor(m_object);
+        m_condition.forEachDependentCell(functor);
+    }
     
     // This means that the objects involved in this are still live.
     bool isStillLive(VM&) const;

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp	2019-09-21 18:30:29 UTC (rev 250184)
@@ -143,11 +143,11 @@
 
 bool ObjectPropertyConditionSet::areStillLive(VM& vm) const
 {
-    for (const ObjectPropertyCondition& condition : *this) {
-        if (!condition.isStillLive(vm))
-            return false;
-    }
-    return true;
+    bool stillLive = true;
+    forEachDependentCell([&](JSCell* cell) {
+        stillLive &= vm.heap.isMarked(cell);
+    });
+    return stillLive;
 }
 
 void ObjectPropertyConditionSet::dumpInContext(PrintStream& out, DumpContext* context) const

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h	2019-09-21 18:30:29 UTC (rev 250184)
@@ -111,6 +111,14 @@
     bool structuresEnsureValidityAssumingImpurePropertyWatchpoint() const;
     
     bool needImpurePropertyWatchpoint() const;
+
+    template<typename Functor>
+    void forEachDependentCell(const Functor& functor) const
+    {
+        for (const ObjectPropertyCondition& condition : *this)
+            condition.forEachDependentCell(functor);
+    }
+
     bool areStillLive(VM&) const;
     
     void dumpInContext(PrintStream&, DumpContext*) const;

Modified: trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp	2019-09-21 18:30:29 UTC (rev 250184)
@@ -351,20 +351,6 @@
         && isWatchableWhenValid(structure, effort);
 }
 
-bool PropertyCondition::isStillLive(VM& vm) const
-{
-    if (hasPrototype() && prototype() && !vm.heap.isMarked(prototype()))
-        return false;
-    
-    if (hasRequiredValue()
-        && requiredValue()
-        && requiredValue().isCell()
-        && !vm.heap.isMarked(requiredValue().asCell()))
-        return false;
-    
-    return true;
-}
-
 void PropertyCondition::validateReferences(const TrackedReferences& tracked) const
 {
     if (hasPrototype())

Modified: trunk/Source/_javascript_Core/bytecode/PropertyCondition.h (250183 => 250184)


--- trunk/Source/_javascript_Core/bytecode/PropertyCondition.h	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/bytecode/PropertyCondition.h	2019-09-21 18:30:29 UTC (rev 250184)
@@ -295,10 +295,17 @@
     {
         return !!*this && m_header.type() == Equivalence;
     }
+
+    template<typename Functor>
+    void forEachDependentCell(const Functor& functor) const
+    {
+        if (hasPrototype() && prototype())
+            functor(prototype());
+
+        if (hasRequiredValue() && requiredValue() && requiredValue().isCell())
+            functor(requiredValue().asCell());
+    }
     
-    // This means that the objects involved in this are still live.
-    bool isStillLive(VM&) const;
-    
     void validateReferences(const TrackedReferences&) const;
 
     static bool isValidValueForAttributes(VM&, JSValue, unsigned attributes);

Modified: trunk/Source/_javascript_Core/jit/PolymorphicCallStubRoutine.cpp (250183 => 250184)


--- trunk/Source/_javascript_Core/jit/PolymorphicCallStubRoutine.cpp	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/jit/PolymorphicCallStubRoutine.cpp	2019-09-21 18:30:29 UTC (rev 250184)
@@ -129,11 +129,11 @@
 
 bool PolymorphicCallStubRoutine::visitWeak(VM& vm)
 {
-    for (auto& variant : m_variants) {
-        if (!vm.heap.isMarked(variant.get()))
-            return false;
-    }
-    return true;
+    bool isStillLive = true;
+    forEachDependentCell([&](JSCell* cell) {
+        isStillLive &= vm.heap.isMarked(cell);
+    });
+    return isStillLive;
 }
 
 void PolymorphicCallStubRoutine::markRequiredObjectsInternal(SlotVisitor& visitor)

Modified: trunk/Source/_javascript_Core/jit/PolymorphicCallStubRoutine.h (250183 => 250184)


--- trunk/Source/_javascript_Core/jit/PolymorphicCallStubRoutine.h	2019-09-21 16:08:34 UTC (rev 250183)
+++ trunk/Source/_javascript_Core/jit/PolymorphicCallStubRoutine.h	2019-09-21 18:30:29 UTC (rev 250184)
@@ -95,6 +95,13 @@
 
     void clearCallNodesFor(CallLinkInfo*);
     
+    template<typename Functor>
+    void forEachDependentCell(const Functor& functor)
+    {
+        for (auto& variant : m_variants)
+            functor(variant.get());
+    }
+
     bool visitWeak(VM&) override;
 
 protected:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to