From 06a5eaf6bf3473ac41ce7fc289d463e925db40b8 Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Tue, 28 Nov 2023 17:10:38 -0800 Subject: [PATCH] PolymorphicCallNode should unchain itself first in unlink https://bugs.webkit.org/show_bug.cgi?id=265475 rdar://118893186 Reviewed by Mark Lam. PolymorphicCallNode::unlinkImpl calls m_callLinkInfo->unlink. But it is possible that this CallLinkInfo is holding PolymorphicCallNode's owner stub and it may clear stub. Previously, we are always deferring this stub destruction until JITStubRoutineSet destroys it. But now, it is possible that they get deleted immediately when owner CodeBlock is dead. This means that after calling m_callLinkInfo->unlink, it is possible that PolymorphicCallNode |this| is already destroyed. This patch reorders unlink's operation in PolymorphicCallNode so that we first unlink it from linked-list. This is OK since we are not expecting that this is in the linked-list in unlink calls. So after m_callLinkInfo->unlink, we no longer touch anything in PolymorphicCallNode. * Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp: (JSC::PolymorphicCallNode::unlinkImpl): Canonical link: https://commits.webkit.org/271246@main --- Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp b/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp index 4115ba25ced16..e8d714635371f 100644 --- a/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp +++ b/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp @@ -45,13 +45,16 @@ PolymorphicCallNode::~PolymorphicCallNode() void PolymorphicCallNode::unlink(VM& vm) { + // We first remove itself from the linked-list before unlinking m_callLinkInfo. + // The reason is that m_callLinkInfo can potentially link PolymorphicCallNode's stub itself, and it may destroy |this| (the other CallLinkInfo + // does not do it since it is not chained in PolymorphicCallStubRoutine). + if (isOnList()) + remove(); + if (m_callLinkInfo) { dataLogLnIf(Options::dumpDisassembly(), "Unlinking polymorphic call at ", m_callLinkInfo->doneLocation(), ", bc#", m_callLinkInfo->codeOrigin().bytecodeIndex()); m_callLinkInfo->unlink(vm); } - - if (isOnList()) - remove(); } void PolymorphicCallNode::clearCallLinkInfo()