From f79962099856a7ab1b4e17fa12688345c297814f Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Mon, 31 Jul 2023 11:43:39 -0700 Subject: [PATCH] MarkedVector::fill should register itself as a root https://bugs.webkit.org/show_bug.cgi?id=255951 rdar://108261913 Reviewed by Alexey Shvayka and Justin Michaud. 1. MarkedVector::fill is not registering itself as a strong root of GC. This patch fixes it with m_markSet->add. 2. Initialize buffer with empty value in MarkedVector::fill. This buffer can be scanned via GC when GC is invoked from a passed lambda. * JSTests/stress/marked-buffer-fill-should-be-gc-aware.js: Added. (foo): * Source/JavaScriptCore/llint/LLIntSlowPaths.cpp: (JSC::LLInt::handleVarargsCheckpoint): * Source/JavaScriptCore/runtime/ArgList.h: (JSC::MarkedVector::fill): Originally-landed-as: 259548.690@safari-7615-branch (b05050e0cc00). rdar://108261913 Canonical link: https://commits.webkit.org/266449@main --- .../stress/marked-buffer-fill-should-be-gc-aware.js | 10 ++++++++++ Source/JavaScriptCore/llint/LLIntSlowPaths.cpp | 2 +- Source/JavaScriptCore/runtime/ArgList.h | 11 +++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 JSTests/stress/marked-buffer-fill-should-be-gc-aware.js diff --git a/JSTests/stress/marked-buffer-fill-should-be-gc-aware.js b/JSTests/stress/marked-buffer-fill-should-be-gc-aware.js new file mode 100644 index 0000000000000..8bb791d131cf5 --- /dev/null +++ b/JSTests/stress/marked-buffer-fill-should-be-gc-aware.js @@ -0,0 +1,10 @@ +//@ runDefault("--slowPathAllocsBetweenGCs=10", "--jitPolicyScale=0") +let a = new BigUint64Array(1000); + +function foo(a0) { + ~a0; +} + +for (let i = 0; i < 1000; i++) { + foo.apply(null, a); +} diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index d31f9cde5de29..40a660eeaecd1 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -2315,7 +2315,7 @@ static void handleVarargsCheckpoint(VM& vm, CallFrame* callFrame, JSGlobalObject unsigned firstVarArg = bytecode.m_firstVarArg; MarkedArgumentBuffer args; - args.fill(argumentCountIncludingThis - 1, [&] (JSValue* buffer) { + args.fill(vm, argumentCountIncludingThis - 1, [&](JSValue* buffer) { loadVarargs(globalObject, buffer, callFrame->r(bytecode.m_arguments).jsValue(), firstVarArg, argumentCountIncludingThis - 1); }); if (args.hasOverflowed()) { diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h index 07632263266b4..bc5bd9ce4180b 100644 --- a/Source/JavaScriptCore/runtime/ArgList.h +++ b/Source/JavaScriptCore/runtime/ArgList.h @@ -205,14 +205,21 @@ class MarkedVector : public OverflowHandler, public MarkedVectorBase { } template - void fill(size_t count, const Functor& func) + void fill(VM& vm, size_t count, const Functor& func) { ASSERT(!m_size); ensureCapacity(count); if (OverflowHandler::hasOverflowed()) return; + if (LIKELY(!m_markSet)) { + m_markSet = &vm.heap.markListSet(); + m_markSet->add(this); + } m_size = count; - func(reinterpret_cast(&slotFor(0))); + auto* buffer = reinterpret_cast(&slotFor(0)); + for (unsigned i = 0; i < count; ++i) + buffer[i] = JSValue(); + func(buffer); } private: