Browse Source

chore: cherry-pick 3 changes from 5-M131 (#45157)

chore: [31-x-y] cherry-pick 3 changes from 5-M131

* e1b6fb924221 from v8
* 0d3c44362eea from v8
* f3300abe2fcd from chromium

Co-authored-by: Charles Kerr <[email protected]>
Pedro Pontes 3 months ago
parent
commit
3b1cdbb563

+ 1 - 0
patches/chromium/.patches

@@ -145,3 +145,4 @@ cherry-pick-923797bac925.patch
 cherry-pick-e699ac35ac6c.patch
 cherry-pick-3a6ff45cc3f4.patch
 cherry-pick-a51e7ebb7663.patch
+cherry-pick-f3300abe2fcd.patch

+ 255 - 0
patches/chromium/cherry-pick-f3300abe2fcd.patch

@@ -0,0 +1,255 @@
+From f3300abe2fcd0164794d7a782cc221d10c17f322 Mon Sep 17 00:00:00 2001
+From: Yoshisato Yanagisawa <[email protected]>
+Date: Mon, 06 Jan 2025 05:34:49 -0800
+Subject: [PATCH] [M130] Make AcceptLanguagesWatcher a weak persistent object
+
+DedicatedWorkerOrSharedWorkerFetchContext keeps on having a pointer
+to the AcceptLanguagesWatcher as a raw_ptr.  Even if the implementing
+object gets garbage-collected, the pointer is kept.  Therefore,
+DedicatedWorkerOrSharedWorkerFetchContext may use it after the GC.
+
+This CL revised the raw_ptr to AcceptLanguagesWatcher to use
+WeakPersistent so that the users of the object won't access it
+after it gets GCed.
+
+(cherry picked from commit 9e7b77da977401361ef3bc9ad0f43e7563f49657)
+
+Bug: 379869752
+Change-Id: Ic3997fcf17aa93f45507241e0fc18a486efc1932
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6038980
+Reviewed-by: Michael Lippautz <[email protected]>
+Auto-Submit: Yoshisato Yanagisawa <[email protected]>
+Commit-Queue: Yoshisato Yanagisawa <[email protected]>
+Cr-Original-Commit-Position: refs/heads/main@{#1390151}
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6148168
+Reviewed-by: Erhu Akpobaro <[email protected]>
+Commit-Queue: Daniel Yip <[email protected]>
+Auto-Submit: Daniel Yip <[email protected]>
+Owners-Override: Daniel Yip <[email protected]>
+Cr-Commit-Position: refs/branch-heads/6723@{#2761}
+Cr-Branched-From: 985f2961df230630f9cbd75bd6fe463009855a11-refs/heads/main@{#1356013}
+---
+
+diff --git a/third_party/blink/public/platform/web_worker_fetch_context.h b/third_party/blink/public/platform/web_worker_fetch_context.h
+index 6f2a2e9..cf8bfce4 100644
+--- a/third_party/blink/public/platform/web_worker_fetch_context.h
++++ b/third_party/blink/public/platform/web_worker_fetch_context.h
+@@ -33,19 +33,12 @@
+ 
+ namespace blink {
+ 
++class AcceptLanguagesWatcher;
+ class WebDocumentSubresourceFilter;
+ class URLLoaderFactory;
+ class WebURLRequest;
+ class URLLoaderThrottle;
+ 
+-// Helper class allowing DedicatedOrSharedWorkerFetchContextImpl to notify blink
+-// upon an accept languages update. This class will be extended by
+-// WorkerNavigator.
+-class AcceptLanguagesWatcher {
+- public:
+-  virtual void NotifyUpdate() = 0;
+-};
+-
+ // WebWorkerFetchContext is a per-worker object created on the main thread,
+ // passed to a worker (dedicated, shared and service worker) and initialized on
+ // the worker thread by InitializeOnWorkerThread(). It contains information
+diff --git a/third_party/blink/renderer/core/workers/worker_navigator.cc b/third_party/blink/renderer/core/workers/worker_navigator.cc
+index 344382b..a4159a4 100644
+--- a/third_party/blink/renderer/core/workers/worker_navigator.cc
++++ b/third_party/blink/renderer/core/workers/worker_navigator.cc
+@@ -61,4 +61,9 @@
+       *Event::Create(event_type_names::kLanguagechange));
+ }
+ 
++void WorkerNavigator::Trace(Visitor* visitor) const {
++  NavigatorBase::Trace(visitor);
++  AcceptLanguagesWatcher::Trace(visitor);
++}
++
+ }  // namespace blink
+diff --git a/third_party/blink/renderer/core/workers/worker_navigator.h b/third_party/blink/renderer/core/workers/worker_navigator.h
+index ea07a96..ab622f8e 100644
+--- a/third_party/blink/renderer/core/workers/worker_navigator.h
++++ b/third_party/blink/renderer/core/workers/worker_navigator.h
+@@ -29,6 +29,7 @@
+ #include "third_party/blink/public/platform/web_worker_fetch_context.h"
+ #include "third_party/blink/renderer/core/core_export.h"
+ #include "third_party/blink/renderer/core/execution_context/navigator_base.h"
++#include "third_party/blink/renderer/platform/accept_languages_watcher.h"
+ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+ 
+ namespace blink {
+@@ -46,6 +47,9 @@
+ 
+   // AcceptLanguagesWatcher override
+   void NotifyUpdate() override;
++
++  // Both NavigatorLanguage and AcceptLanguagesWatcher override
++  void Trace(Visitor* visitor) const override;
+ };
+ 
+ }  // namespace blink
+diff --git a/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc b/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc
+index 0815877..4930962 100644
+--- a/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc
++++ b/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc
+@@ -18,6 +18,7 @@
+ #include "third_party/blink/public/platform/url_loader_throttle_provider.h"
+ #include "third_party/blink/public/platform/web_url_request_extra_data.h"
+ #include "third_party/blink/public/platform/websocket_handshake_throttle_provider.h"
++#include "third_party/blink/renderer/platform/accept_languages_watcher.h"
+ #include "third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_factory.h"
+ #include "third_party/blink/renderer/platform/loader/internet_disconnected_url_loader.h"
+ 
+@@ -226,9 +227,12 @@
+ 
+ void WebServiceWorkerFetchContextImpl::NotifyUpdate(
+     const RendererPreferences& new_prefs) {
+-  DCHECK(accept_languages_watcher_);
+-  if (renderer_preferences_.accept_languages != new_prefs.accept_languages)
+-    accept_languages_watcher_->NotifyUpdate();
++  // Reserving `watcher` on the stack ensures it is not GC'd within this scope.
++  auto* watcher = accept_languages_watcher_.Get();
++  if (watcher &&
++      renderer_preferences_.accept_languages != new_prefs.accept_languages) {
++    watcher->NotifyUpdate();
++  }
+   renderer_preferences_ = new_prefs;
+ }
+ 
+diff --git a/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.h b/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.h
+index a7c897de..c2f1c9d 100644
+--- a/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.h
++++ b/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.h
+@@ -6,16 +6,16 @@
+ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_WEB_SERVICE_WORKER_FETCH_CONTEXT_IMPL_H_
+ 
+ #include "base/memory/raw_ptr.h"
++#include "base/task/single_thread_task_runner.h"
+ #include "mojo/public/cpp/bindings/pending_receiver.h"
+ #include "mojo/public/cpp/bindings/receiver.h"
+ #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
+ #include "third_party/blink/public/mojom/renderer_preference_watcher.mojom-blink.h"
+ #include "third_party/blink/public/mojom/service_worker/service_worker.mojom-forward.h"
+ #include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom-blink.h"
+-
+-#include "base/task/single_thread_task_runner.h"
+ #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_fetch_context.h"
+ #include "third_party/blink/public/platform/web_common.h"
++#include "third_party/blink/renderer/platform/heap/persistent.h"
+ #include "third_party/blink/renderer/platform/weborigin/kurl.h"
+ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+ #include "third_party/blink/renderer/platform/wtf/vector.h"
+@@ -135,7 +135,7 @@
+   // This is owned by ThreadedMessagingProxyBase on the main thread.
+   raw_ptr<base::WaitableEvent> terminate_sync_load_event_ = nullptr;
+ 
+-  raw_ptr<AcceptLanguagesWatcher> accept_languages_watcher_ = nullptr;
++  WeakPersistent<AcceptLanguagesWatcher> accept_languages_watcher_;
+ 
+   Vector<String> cors_exempt_header_list_;
+   bool is_offline_mode_ = false;
+diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
+index 5b8e391..12da20f 100644
+--- a/third_party/blink/renderer/platform/BUILD.gn
++++ b/third_party/blink/renderer/platform/BUILD.gn
+@@ -341,6 +341,7 @@
+   output_name = "blink_platform"
+ 
+   sources = [
++    "accept_languages_watcher.h",
+     "animation/animation_translation_util.cc",
+     "animation/animation_translation_util.h",
+     "animation/compositor_animation.cc",
+diff --git a/third_party/blink/renderer/platform/accept_languages_watcher.h b/third_party/blink/renderer/platform/accept_languages_watcher.h
+new file mode 100644
+index 0000000..7fd5de07f
+--- /dev/null
++++ b/third_party/blink/renderer/platform/accept_languages_watcher.h
+@@ -0,0 +1,22 @@
++// Copyright 2024 The Chromium Authors
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_ACCEPT_LANGUAGES_WATCHER_H_
++#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_ACCEPT_LANGUAGES_WATCHER_H_
++
++#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
++
++namespace blink {
++
++// Helper class allowing DedicatedOrSharedWorkerFetchContextImpl to notify blink
++// upon an accept languages update. This class will be extended by
++// WorkerNavigator.
++class AcceptLanguagesWatcher : public GarbageCollectedMixin {
++ public:
++  virtual void NotifyUpdate() = 0;
++};
++
++}  // namespace blink
++
++#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_ACCEPT_LANGUAGES_WATCHER_H_
+diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS b/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS
+index c8a92c06..7886b02 100644
+--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS
++++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS
+@@ -28,4 +28,7 @@
+     "web_url_loader_unittest.cc": [
+         "+net/test/cert_test_util.h"
+     ],
++    "dedicated_or_shared_worker_fetch_context_impl.cc": [
++        "+third_party/blink/renderer/platform/accept_languages_watcher.h",
++    ],
+ }
+diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc
+index cc1954f6..c9f96ff 100644
+--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc
++++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc
+@@ -28,6 +28,7 @@
+ #include "third_party/blink/public/platform/web_security_origin.h"
+ #include "third_party/blink/public/platform/web_url_request_extra_data.h"
+ #include "third_party/blink/public/platform/websocket_handshake_throttle_provider.h"
++#include "third_party/blink/renderer/platform/accept_languages_watcher.h"
+ #include "third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader.h"
+ #include "third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_factory.h"
+ #include "url/url_constants.h"
+@@ -605,9 +606,13 @@
+ 
+ void DedicatedOrSharedWorkerFetchContextImpl::NotifyUpdate(
+     const RendererPreferences& new_prefs) {
+-  if (accept_languages_watcher_ &&
+-      renderer_preferences_.accept_languages != new_prefs.accept_languages)
+-    accept_languages_watcher_->NotifyUpdate();
++  // Reserving `accept_languages_watcher` on the stack ensures it is not GC'd
++  // within this scope.
++  auto* accept_languages_watcher = accept_languages_watcher_.Get();
++  if (accept_languages_watcher &&
++      renderer_preferences_.accept_languages != new_prefs.accept_languages) {
++    accept_languages_watcher->NotifyUpdate();
++  }
+   renderer_preferences_ = new_prefs;
+   for (auto& watcher : child_preference_watchers_)
+     watcher->NotifyUpdate(new_prefs);
+diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.h
+index b95a25fe..d0387cf 100644
+--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.h
++++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.h
+@@ -23,6 +23,7 @@
+ #include "third_party/blink/public/platform/web_common.h"
+ #include "third_party/blink/public/platform/web_dedicated_or_shared_worker_fetch_context.h"
+ #include "third_party/blink/public/platform/web_string.h"
++#include "third_party/blink/renderer/platform/heap/persistent.h"
+ #include "third_party/blink/renderer/platform/wtf/casting.h"
+ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+ #include "third_party/blink/renderer/platform/wtf/vector.h"
+@@ -301,7 +302,7 @@
+   std::unique_ptr<WeakWrapperResourceLoadInfoNotifier>
+       weak_wrapper_resource_load_info_notifier_;
+ 
+-  raw_ptr<AcceptLanguagesWatcher> accept_languages_watcher_ = nullptr;
++  WeakPersistent<AcceptLanguagesWatcher> accept_languages_watcher_;
+ };
+ 
+ template <>

+ 3 - 0
patches/v8/.patches

@@ -16,3 +16,6 @@ merged_wasm_do_not_inline_wrappers_with_ref_extern_parameter.patch
 merged_wasm_fix_default_externref_exnref_reference.patch
 m126-lts_liftoff_fix_clobbered_scratch_register.patch
 cherry-pick-aad648bd2af9.patch
+merged_wasm_arm_tail-call_free_scratch_register_earlier.patch
+merged_turboshaft_wasm_wasmgctypeanalyzer_fix_phi_input_for.patch
+merged_turboshaft_wasm_wasmgctypeanalyzer_fix_single-block_loops.patch

+ 1 - 1
patches/v8/m126-lts_liftoff_fix_clobbered_scratch_register.patch

@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Clemens Backes <[email protected]>
 Date: Fri, 15 Nov 2024 16:00:15 +0100
-Subject: [M126-LTS][liftoff] Fix clobbered scratch register
+Subject: Fix clobbered scratch register
 
 `GetMemOp` returns an `Operand` which can contain `kScratchRegister`. We
 should hence not clobber that register until after the last use of the

+ 83 - 0
patches/v8/merged_turboshaft_wasm_wasmgctypeanalyzer_fix_phi_input_for.patch

@@ -0,0 +1,83 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jakob Kummerow <[email protected]>
+Date: Mon, 16 Dec 2024 20:34:29 +0100
+Subject: Merged: [turboshaft][wasm] WasmGCTypeAnalyzer: Fix phi input for
+ single-block loops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixed: 383356864
+(cherry picked from commit f231d83cb3c08754413b3ee1aa249cebd4d5445f)
+
+Change-Id: I3247f6071a9a27eaef49ae8981b7eea93f83dc55
+Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6097632
+Reviewed-by: Eva Herencsárová <[email protected]>
+Auto-Submit: Jakob Kummerow <[email protected]>
+Commit-Queue: Eva Herencsárová <[email protected]>
+Commit-Queue: Jakob Kummerow <[email protected]>
+Cr-Commit-Position: refs/branch-heads/13.0@{#45}
+Cr-Branched-From: 4be854bd71ea878a25b236a27afcecffa2e29360-refs/heads/13.0.245@{#1}
+Cr-Branched-From: 1f5183f7ad6cca21029fd60653d075730c644432-refs/heads/main@{#96103}
+
+diff --git a/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc b/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
+index d4ab8ae842d1718ba2ed7b8e9c9d0e131d6fd91f..0a9cfb178f7a0acb2228fe7e8e943a65a95f672a 100644
+--- a/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
++++ b/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
+@@ -257,6 +257,28 @@ void WasmGCTypeAnalyzer::ProcessAllocateStruct(
+                       wasm::ValueType::Ref(type_index));
+ }
+ 
++wasm::ValueType WasmGCTypeAnalyzer::GetTypeForPhiInput(const PhiOp& phi,
++                                                       int input_index) {
++  OpIndex phi_id = graph_.Index(phi);
++  OpIndex input = ResolveAliases(phi.input(input_index));
++  // If the input of the phi is in the same block as the phi and appears
++  // before the phi, don't use the predecessor value.
++
++  if (current_block_->begin().id() <= input.id() && input.id() < phi_id.id()) {
++    // Phi instructions have to be at the beginning of the block, so this can
++    // only happen for inputs that are also phis. Furthermore, this is only
++    // possible in loop headers of loops with a single block (endless loops) and
++    // only for the backedge-input.
++    DCHECK(graph_.Get(input).Is<PhiOp>());
++    DCHECK(current_block_->IsLoop());
++    DCHECK(current_block_->HasBackedge(graph_));
++    DCHECK_EQ(current_block_->LastPredecessor(), current_block_);
++    DCHECK_EQ(input_index, 1);
++    return types_table_.Get(input);
++  }
++  return types_table_.GetPredecessorValue(input, input_index);
++}
++
+ void WasmGCTypeAnalyzer::ProcessPhi(const PhiOp& phi) {
+   // The result type of a phi is the union of all its input types.
+   // If any of the inputs is the default value ValueType(), there isn't any type
+@@ -269,12 +291,10 @@ void WasmGCTypeAnalyzer::ProcessPhi(const PhiOp& phi) {
+     RefineTypeKnowledge(graph_.Index(phi), GetResolvedType((phi.input(0))));
+     return;
+   }
+-  wasm::ValueType union_type =
+-      types_table_.GetPredecessorValue(ResolveAliases(phi.input(0)), 0);
++  wasm::ValueType union_type = GetTypeForPhiInput(phi, 0);
+   if (union_type == wasm::ValueType()) return;
+   for (int i = 1; i < phi.input_count; ++i) {
+-    wasm::ValueType input_type =
+-        types_table_.GetPredecessorValue(ResolveAliases(phi.input(i)), i);
++    wasm::ValueType input_type = GetTypeForPhiInput(phi, i);
+     if (input_type == wasm::ValueType()) return;
+     // <bottom> types have to be skipped as an unreachable predecessor doesn't
+     // change our type knowledge.
+diff --git a/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h b/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h
+index 260aedc4769fd150d14615afd7869ada44a1b4ad..d8c016673861acb62c40ec6481ee78d3b88ee07b 100644
+--- a/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h
++++ b/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h
+@@ -79,6 +79,8 @@ class WasmGCTypeAnalyzer {
+   void ProcessPhi(const PhiOp& phi);
+   void ProcessTypeAnnotation(const WasmTypeAnnotationOp& type_annotation);
+ 
++  wasm::ValueType GetTypeForPhiInput(const PhiOp& phi, int input_index);
++
+   void CreateMergeSnapshot(const Block& block);
+   bool CreateMergeSnapshot(base::Vector<const Snapshot> predecessors,
+                            base::Vector<const bool> reachable);

+ 85 - 0
patches/v8/merged_turboshaft_wasm_wasmgctypeanalyzer_fix_single-block_loops.patch

@@ -0,0 +1,85 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jakob Kummerow <[email protected]>
+Date: Mon, 16 Dec 2024 20:41:57 +0100
+Subject: Merged: [turboshaft][wasm] WasmGCTypeAnalyzer: Fix single-block loops
+ properly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+While https://crrev.com/c/6087921 fixed a bug where the type in the
+loop header revisit was reflecting "older" knowledge, it didn't address
+the general issue of loop phis dependencies in single block loops where
+it might require many iterations until all type information has
+stabilized.
+
+The fix linked above also introduce too specific DCHECKs, as even
+outside of single-block loops we can end up with phis where a phi input
+appears in the same block before the phi itself.
+The binaryen fuzzer found the following pattern:
+  v113 = Phi(v26, v113)
+  v114 = Phi(v26, v113)
+
+In follow-up changes it should be ensured that the useless phi v113
+doesn't get emitted, then v114 wouldn't have that issue (and it could
+also be removed.)
+
+(cherry picked from commit c84e01e92bfd61d29541c59e378b9a15ba6fc891)
+
+Fixed: 383356864
+Bug: 383814042
+Change-Id: I222dc493bf0a2613d14ebb7df2bdeca931c8daa6
+Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6097772
+Auto-Submit: Jakob Kummerow <[email protected]>
+Commit-Queue: Eva Herencsárová <[email protected]>
+Reviewed-by: Eva Herencsárová <[email protected]>
+Commit-Queue: Jakob Kummerow <[email protected]>
+Cr-Commit-Position: refs/branch-heads/13.0@{#47}
+Cr-Branched-From: 4be854bd71ea878a25b236a27afcecffa2e29360-refs/heads/13.0.245@{#1}
+Cr-Branched-From: 1f5183f7ad6cca21029fd60653d075730c644432-refs/heads/main@{#96103}
+
+diff --git a/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc b/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
+index 0a9cfb178f7a0acb2228fe7e8e943a65a95f672a..eae36b35e0e04242b2ac6f7e017127aa38440f93 100644
+--- a/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
++++ b/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
+@@ -45,9 +45,23 @@ void WasmGCTypeAnalyzer::Run() {
+         // defines more precise types than the previous iteration).
+         if (needs_revisit) {
+           block_to_snapshot_[loop_header.index()] = MaybeSnapshot(snapshot);
+-          // This will push the successors of the loop header to the iterator
+-          // stack, so the loop body will be visited in the next iteration.
+-          iterator.MarkLoopForRevisitSkipHeader();
++          if (block.index() != loop_header.index()) {
++            // This will push the successors of the loop header to the iterator
++            // stack, so the loop body will be visited in the next iteration.
++            iterator.MarkLoopForRevisitSkipHeader();
++          } else {
++            // A single-block loop doesn't have any successors which would be
++            // re-evaluated and which might trigger another re-evaluation of the
++            // loop header.
++            // TODO(mliedtke): This is not a great design: We don't just
++            // schedule revisiting the loop header but afterwards we revisit it
++            // once again to evaluate whether we need to revisit it more times,
++            // so for single block loops the revisitation count will always be a
++            // multiple of 2. While this is inefficient, single-block loops are
++            // rare and are either endless loops or need to trigger an exception
++            // (e.g. a wasm trap) to terminate.
++            iterator.MarkLoopForRevisit();
++          }
+         }
+       }
+     }
+@@ -267,12 +281,9 @@ wasm::ValueType WasmGCTypeAnalyzer::GetTypeForPhiInput(const PhiOp& phi,
+   if (current_block_->begin().id() <= input.id() && input.id() < phi_id.id()) {
+     // Phi instructions have to be at the beginning of the block, so this can
+     // only happen for inputs that are also phis. Furthermore, this is only
+-    // possible in loop headers of loops with a single block (endless loops) and
+-    // only for the backedge-input.
++    // possible in loop headers of loops and only for the backedge-input.
+     DCHECK(graph_.Get(input).Is<PhiOp>());
+     DCHECK(current_block_->IsLoop());
+-    DCHECK(current_block_->HasBackedge(graph_));
+-    DCHECK_EQ(current_block_->LastPredecessor(), current_block_);
+     DCHECK_EQ(input_index, 1);
+     return types_table_.Get(input);
+   }

+ 65 - 0
patches/v8/merged_wasm_arm_tail-call_free_scratch_register_earlier.patch

@@ -0,0 +1,65 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Thibaud Michaud <[email protected]>
+Date: Wed, 18 Dec 2024 12:14:14 +0100
+Subject: Merged: [wasm][arm][tail-call] Free scratch register earlier
+
+In Liftoff's PrepareTailCall, we kept the UseScratchRegisterScope open
+for longer than necessary. Close the scope earlier to ensure that we
+don't run out of scratch registers in the last "sub" instruction if it
+needs one.
+
[email protected]
+
+Fixed: 384565015
+(cherry picked from commit 7c9e628fd07a457635db098483f7a956ecfa385a)
+
+Change-Id: I0100569d5276aa9188ccbc3c7ee409a9dd49be31
+Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6148448
+Reviewed-by: Daniel Lehmann <[email protected]>
+Commit-Queue: Thibaud Michaud <[email protected]>
+Cr-Commit-Position: refs/branch-heads/13.0@{#49}
+Cr-Branched-From: 4be854bd71ea878a25b236a27afcecffa2e29360-refs/heads/13.0.245@{#1}
+Cr-Branched-From: 1f5183f7ad6cca21029fd60653d075730c644432-refs/heads/main@{#96103}
+
+diff --git a/src/wasm/baseline/arm/liftoff-assembler-arm-inl.h b/src/wasm/baseline/arm/liftoff-assembler-arm-inl.h
+index 959dbf3b1c36e32c473b233a95f0bb149ceebaff..cb95a6f03aa4873525da2ff2eab3f9573372e3b8 100644
+--- a/src/wasm/baseline/arm/liftoff-assembler-arm-inl.h
++++ b/src/wasm/baseline/arm/liftoff-assembler-arm-inl.h
+@@ -486,21 +486,23 @@ void LiftoffAssembler::CallFrameSetupStub(int declared_function_index) {
+ 
+ void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
+                                        int stack_param_delta) {
+-  UseScratchRegisterScope temps(this);
+-  Register scratch = temps.Acquire();
++  {
++    UseScratchRegisterScope temps(this);
++    Register scratch = temps.Acquire();
+ 
+-  // Push the return address and frame pointer to complete the stack frame.
+-  sub(sp, sp, Operand(8));
+-  ldr(scratch, MemOperand(fp, 4));
+-  str(scratch, MemOperand(sp, 4));
+-  ldr(scratch, MemOperand(fp, 0));
+-  str(scratch, MemOperand(sp, 0));
+-
+-  // Shift the whole frame upwards.
+-  int slot_count = num_callee_stack_params + 2;
+-  for (int i = slot_count - 1; i >= 0; --i) {
+-    ldr(scratch, MemOperand(sp, i * 4));
+-    str(scratch, MemOperand(fp, (i - stack_param_delta) * 4));
++    // Push the return address and frame pointer to complete the stack frame.
++    sub(sp, sp, Operand(8));
++    ldr(scratch, MemOperand(fp, 4));
++    str(scratch, MemOperand(sp, 4));
++    ldr(scratch, MemOperand(fp, 0));
++    str(scratch, MemOperand(sp, 0));
++
++    // Shift the whole frame upwards.
++    int slot_count = num_callee_stack_params + 2;
++    for (int i = slot_count - 1; i >= 0; --i) {
++      ldr(scratch, MemOperand(sp, i * 4));
++      str(scratch, MemOperand(fp, (i - stack_param_delta) * 4));
++    }
+   }
+ 
+   // Set the new stack and frame pointer.