Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in V8
DescriptionInappropriate implementation in V8
ComponentV8
Bug ClassLogic Error
Tracker484527367
Fix commitb54c7841e2cd (v8/v8) +44/-11
CISA KEVNot listed
CreditedGoogle
Disclosed2026-04-07

Changed Functions

FunctionChangeNotes
if
src/maglev/maglev-graph-builder.cc
modified

Files Changed

  • src/maglev/maglev-graph-builder.cc
  • src/maglev/maglev-graph-builder.h
  • test/mjsunit/turbolev/regress-484527367.js
From b54c7841e2cdb2c3a8c7c315daa41ca99ecd7329 Mon Sep 17 00:00:00 2001
From: Darius Mercadier <dmercadier@chromium.org>
Date: Mon, 23 Feb 2026 16:14:11 +0100
Subject: [PATCH] [*lev] Correctly update use counts for nested builtin continuations

Fixed: 484527367
Change-Id: I4cda8c1bbb2788fca06b564eae509511aec0957e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7593054
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#105381}
---

diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
index 3718e10..832ec14 100644
--- a/src/maglev/maglev-graph-builder.cc
+++ b/src/maglev/maglev-graph-builder.cc
@@ -1542,19 +1542,19 @@
   return caller_details_->deopt_frame;
 }
 
-namespace {
-DeoptFrame* RecursivelyWrapDeoptFrameWithContinuations(
-    Zone* zone, const DeoptFrame& frame,
+DeoptFrame* MaglevGraphBuilder::RecursivelyWrapDeoptFrameWithContinuations(
+    const DeoptFrame& frame,
     const MaglevGraphBuilder::LazyDeoptFrameScope* parent_scope) {
   if (!parent_scope) {
-    return zone->New<DeoptFrame>(frame);
+    return zone()->New<DeoptFrame>(frame);
   }
 
-  return zone->New<DeoptFrame>(parent_scope->data(),
-                               RecursivelyWrapDeoptFrameWithContinuations(
-                                   zone, frame, parent_scope->parent()));
+  AddDeoptUseToScopeData(parent_scope->data());
+
+  return zone()->New<DeoptFrame>(parent_scope->data(),
+                                 RecursivelyWrapDeoptFrameWithContinuations(
+                                     frame, parent_scope->parent()));
 }
-}  // namespace
 
 DeoptFrame* MaglevGraphBuilder::GetLatestCheckpointedFrame() {
   if (in_prologue_) {
@@ -1581,7 +1581,7 @@
       latest_checkpointed_frame_ = zone()->New<DeoptFrame>(
           deopt_scope->data(),
           RecursivelyWrapDeoptFrameWithContinuations(
-              zone(), *latest_checkpointed_frame_, deopt_scope->parent()));
+              *latest_checkpointed_frame_, deopt_scope->parent()));
     }
   }
   return latest_checkpointed_frame_;
@@ -1603,7 +1603,8 @@
                          result_location, result_size);
 }
 
-void MaglevGraphBuilder::AddDeoptUseToScopeData(DeoptFrame::FrameData& data) {
+void MaglevGraphBuilder::AddDeoptUseToScopeData(
+    const DeoptFrame::FrameData& data) {
   switch (data.tag()) {
     case DeoptFrame::FrameType::kInterpretedFrame:
     case DeoptFrame::FrameType::kInlinedArgumentsFrame:
diff --git a/src/maglev/maglev-graph-builder.h b/src/maglev/maglev-graph-builder.h
index b2d9328..223e447 100644
--- a/src/maglev/maglev-graph-builder.h
+++ b/src/maglev/maglev-graph-builder.h
@@ -1511,7 +1511,11 @@
   void AddDeoptUse(VirtualObject* alloc);
   void AddNonEscapingUses(InlinedAllocation* allocation, int use_count);
 
-  void AddDeoptUseToScopeData(DeoptFrame::FrameData& data);
+  void AddDeoptUseToScopeData(const DeoptFrame::FrameData& data);
+
+  DeoptFrame* RecursivelyWrapDeoptFrameWithContinuations(
+      const DeoptFrame& frame,
+      const MaglevGraphBuilder::LazyDeoptFrameScope* parent_scope);
 
   std::optional<VirtualObject*> TryGetNonEscapingArgumentsObject(
       ValueNode* value);
diff --git a/test/mjsunit/turbolev/regress-484527367.js b/test/mjsunit/turbolev/regress-484527367.js
new file mode 100644
index 0000000..5766d96
--- /dev/null
+++ b/test/mjsunit/turbolev/regress-484527367.js
@@ -0,0 +1,28 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --turbolev
+
+function __wrapTC(f, permissive = true) {
+  try {
+    return f();
+  } catch (e) {
+  }
+}
+
+function foo() {
+  const arr = __wrapTC(() => []);
+  function bar(arr1) {
+    const arr2 = [null,,];
+    arr1.forEach(Array.prototype.forEach, arr2);
+  }
+  __wrapTC(() => bar(arr));
+}
+
+%PrepareFunctionForOptimization(foo);
+foo.apply();
+foo();
+
+%OptimizeFunctionOnNextCall(foo);
+foo();
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/test/mjsunit/turbolev/regress-484527367.js b/test/mjsunit/turbolev/regress-484527367.js
new file mode 100644
index 0000000..5766d96
--- /dev/null
+++ b/test/mjsunit/turbolev/regress-484527367.js
@@ -0,0 +1,28 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --turbolev
+
+function __wrapTC(f, permissive = true) {
+  try {
+    return f();
+  } catch (e) {
+  }
+}
+
+function foo() {
+  const arr = __wrapTC(() => []);
+  function bar(arr1) {
+    const arr2 = [null,,];
+    arr1.forEach(Array.prototype.forEach, arr2);
+  }
+  __wrapTC(() => bar(arr));
+}
+
+%PrepareFunctionForOptimization(foo);
+foo.apply();
+foo();
+
+%OptimizeFunctionOnNextCall(foo);
+foo();
Loading diff…

Original Bug Report

reported by 24...@project.gserviceaccount.com

DCHECK failure in use_count_ > 0 in maglev-ir.h

Detailed Report: https://clusterfuzz.com/testcase?key=5109997302120448

Fuzzer: ochang_js_fuzzer Job Type: linux_asan_d8_v8_arm_dbg Platform Id: linux

Crash Type: DCHECK failure Crash Address: Crash State: use_count_ > 0 in maglev-ir.h

Sanitizer: address (ASAN)

Regressed: https://clusterfuzz.com/revisions?job=linux_asan_d8_v8_arm_dbg&range=105182:105183

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=5109997302120448

Issue filed automatically.

To reproduce this, please build the target in this report and run it against the reproducer testcase. Please use the GN arguments provided at bottom of this report when building the binary.

If you have trouble reproducing, please also export the environment variables listed under “[Environment]” in the crash stacktrace.

If you have any feedback on reproducing test cases, let us know at https://forms.gle/Yh3qCYFveHj6E5jz5 so we can improve.

View on issue tracker