From e01012bf0a7348c6d3e94e19acd3c52e3b1f9080 Mon Sep 17 00:00:00 2001 From: Victor Gomes Date: Mon, 19 May 2025 16:03:16 +0200 Subject: [PATCH 1/2] deps: V8: cherry-pick 657d8de27427 Original commit message: [maglev] Fix throwing node inside eager inlining This commit refactors the exception handling logic to correctly identify and associate nodes with their respective `catch` blocks, even when multiple levels of inlining are involved. Previously, the check `!IsInsideTryBlock() && !is_eager_inline()` was insufficient to determine if catch block inside `CatchDetails` was already created. Specifically, consider the case where: 1. Function `bar` is non-eagerly inlined into `foo`. 2. `foo` contains a `catch` block. 3. `bar` calls `in_bar`, which is eagerly inlined. 4. A node within `in_bar` can `throw`. In this scenario, `is_eager_inline` would be true when compiling `in_bar`, leading to an incorrect assumption that the catch block didn't exist yet. This change addresses the issue by propagating a boolean value via `CatchDetails`. This boolean accurately indicates whether a `catch` block is present in the call chain, allowing for correct exception handling regardless of inlining depth or eagerness. Fixed: 417768368 Change-Id: Ic52f72f302b4dc644bdcad939addf98111bc525b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6563500 Commit-Queue: Victor Gomes Reviewed-by: Darius Mercadier Cr-Commit-Position: refs/heads/main@{#100380} Refs: https://github.com/v8/v8/commit/657d8de274276c940d07203ee43d3cf4c732cebd --- deps/v8/src/maglev/maglev-graph-builder.h | 9 ++++-- deps/v8/test/mjsunit/regress-417768368.js | 36 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 deps/v8/test/mjsunit/regress-417768368.js diff --git a/deps/v8/src/maglev/maglev-graph-builder.h b/deps/v8/src/maglev/maglev-graph-builder.h index 8da2b8e86671ce..f55261ae6f395c 100644 --- a/deps/v8/src/maglev/maglev-graph-builder.h +++ b/deps/v8/src/maglev/maglev-graph-builder.h @@ -178,6 +178,7 @@ NodeType StaticTypeForNode(compiler::JSHeapBroker* broker, struct CatchBlockDetails { BasicBlockRef* ref = nullptr; bool exception_handler_was_used = false; + bool block_already_exists = false; int deopt_frame_distance = 0; }; @@ -1220,7 +1221,8 @@ class MaglevGraphBuilder { } DCHECK_IMPLIES(!IsInsideTryBlock(), is_inline()); - if (!IsInsideTryBlock() && !is_eager_inline()) { + if (catch_block.block_already_exists) { + DCHECK(!IsInsideTryBlock()); // If we are inlining a function non-eagerly and we are not inside a // try block, then the catch block already exists. new (node->exception_handler_info()) ExceptionHandlerInfo( @@ -1276,7 +1278,7 @@ class MaglevGraphBuilder { // Inside a try-block. int offset = catch_block_stack_.top().handler; return {&jump_targets_[offset], - merge_states_[offset]->exception_handler_was_used(), 0}; + merge_states_[offset]->exception_handler_was_used(), false, 0}; } if (!is_inline()) { return CatchBlockDetails{}; @@ -1286,7 +1288,8 @@ class MaglevGraphBuilder { CatchBlockDetails GetTryCatchBlockFromInfo(ExceptionHandlerInfo* info) { if (IsInsideTryBlock()) { - return {info->catch_block_ref_address(), !info->ShouldLazyDeopt(), 0}; + return {info->catch_block_ref_address(), !info->ShouldLazyDeopt(), true, + 0}; } if (!is_inline()) { return CatchBlockDetails{}; diff --git a/deps/v8/test/mjsunit/regress-417768368.js b/deps/v8/test/mjsunit/regress-417768368.js new file mode 100644 index 00000000000000..5abb69497c7145 --- /dev/null +++ b/deps/v8/test/mjsunit/regress-417768368.js @@ -0,0 +1,36 @@ +// Copyright 2025 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 + +function bar(a) { + function in_bar(a, b) { + a % b; // This emit a generic mod that can throw. + return a; + } + %PrepareFunctionForOptimization(in_bar); + in_bar({}); + if (a) { + throw_before_this_function_is_not_defined(); + } +} + +function foo() { + try { + function const_42() { + return 42; + } + %PrepareFunctionForOptimization(const_42); + const_42(); + bar(true); + } catch { + } +} + +%PrepareFunctionForOptimization(bar); +%PrepareFunctionForOptimization(foo); +foo(); + +%OptimizeMaglevOnNextCall(foo); +foo(); From e515ce4b57e3c8a8a0196d51ae226f58feb613e5 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Thu, 16 Apr 2026 18:20:26 -0700 Subject: [PATCH 2/2] deps: V8: update embedder string to -node.49 --- common.gypi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.gypi b/common.gypi index 576d5057d988fc..c103b94bb1116a 100644 --- a/common.gypi +++ b/common.gypi @@ -38,7 +38,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.48', + 'v8_embedder_string': '-node.49', ##### V8 defaults for Node.js #####