Commit 168229ffddf for nodejs

commit 168229ffddf291edca6488f5e6dcfb369dac919e
Author: Node.js GitHub Bot <github-bot@iojs.org>
Date:   Mon Nov 2 19:52:58 2026 -0500

    deps: patch V8 to 15.6.75.33

    Refs: https://github.com/v8/v8/compare/15.6.75.25...15.6.75.33
    PR-URL: https://github.com/nodejs/node/pull/67174
    Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
    Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
    Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>

diff --git a/deps/v8/include/cppgc/heap-consistency.h b/deps/v8/include/cppgc/heap-consistency.h
index 23b5d909945..31858f0a631 100644
--- a/deps/v8/include/cppgc/heap-consistency.h
+++ b/deps/v8/include/cppgc/heap-consistency.h
@@ -146,8 +146,8 @@ class HeapConsistency final {
   }

   /**
-   * Steele-style write barrier that re-processes an object if it has already
-   * been processed.
+   * Steele-style write barrier that processes an object regardless of whether
+   * or not it has already been processed.
    *
    * \param params The parameters retrieved from `GetWriteBarrierType()`.
    * \param object The pointer to the object which must point to an object that
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index f91b6e7018f..11e0def9233 100644
--- a/deps/v8/include/v8-version.h
+++ b/deps/v8/include/v8-version.h
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 15
 #define V8_MINOR_VERSION 6
 #define V8_BUILD_NUMBER 75
-#define V8_PATCH_LEVEL 25
+#define V8_PATCH_LEVEL 33

 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/src/builtins/promise-any.tq b/deps/v8/src/builtins/promise-any.tq
index 427d31c2840..6f3d91f1995 100644
--- a/deps/v8/src/builtins/promise-any.tq
+++ b/deps/v8/src/builtins/promise-any.tq
@@ -26,9 +26,7 @@ extern operator '[]' macro LoadContextElementNoCell(
 // together with the errors array. Since all closures for a single Promise.any
 // call use the same context, we need to store the indices for the individual
 // closures somewhere else (we put them into the identity hash field of the
-// closures), and we also need to have a separate marker for when the closure
-// was called already (we slap the native context onto the closure in that
-// case to mark it's done). See Promise.all which uses the same approach.
+// closures).
 transitioning macro CreatePromiseAnyRejectElementContext(
     implicit context: Context)(capability: PromiseCapability,
     nativeContext: NativeContext): PromiseAnyRejectElementContext {
@@ -75,36 +73,30 @@ transitioning javascript builtin PromiseAnyRejectElementClosure(
     js-implicit context: Context, receiver: JSAny, target: JSFunction)(
     value: JSAny): JSAny {
   // 1. Let F be the active function object.
-
-  // 2. Let alreadyCalled be F.[[AlreadyCalled]].
-
-  // 3. If alreadyCalled.[[Value]] is true, return undefined.
-
-  // We use the function's context as the marker to remember whether this
-  // reject element closure was already called. It points to the reject
-  // element context (which is a FunctionContext) until it was called the
-  // first time, in which case we make it point to the native context here
-  // to mark this reject element closure as done.
-  if (IsNativeContext(context)) deferred {
-      return Undefined;
-    }
-
   dcheck(
       context.length ==
       SmiTag(
           PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength));
   const context = %RawDownCast<PromiseAnyRejectElementContext>(context);

-  // 4. Set alreadyCalled.[[Value]] to true.
-  const nativeContext = LoadNativeContext(context);
-  target.context = nativeContext;
-
   // 5. Let index be F.[[Index]].
   dcheck(kPropertyArrayNoHashSentinel == 0);
   const identityHash = LoadJSReceiverIdentityHash(target) otherwise unreachable;
   dcheck(ChangeUint32ToWord(identityHash) < kSmiMaxValue);
   const index = Signed(ChangeUint32ToWord(identityHash)) - 1;

+  // 8. Let remainingElementsCount be F.[[RemainingElements]].
+  let remainingElementsCount = *ContextSlot(
+      context,
+      PromiseAnyRejectElementContextSlots::
+          kPromiseAnyRejectElementRemainingSlot);
+
+  // If all promises were already rejected, the remaining count will already be
+  // 0.
+  if (remainingElementsCount == 0) deferred {
+      return Undefined;
+    }
+
   // 6. Let errors be F.[[Errors]].
   let errorsRef:&FixedArray = ContextSlot(
       context,
@@ -113,12 +105,6 @@ transitioning javascript builtin PromiseAnyRejectElementClosure(

   // 7. Let promiseCapability be F.[[Capability]].

-  // 8. Let remainingElementsCount be F.[[RemainingElements]].
-  let remainingElementsCount = *ContextSlot(
-      context,
-      PromiseAnyRejectElementContextSlots::
-          kPromiseAnyRejectElementRemainingSlot);
-
   // 9. Set errors[index] to x.

   // The max computation below is an optimization to avoid excessive allocations
@@ -138,11 +124,22 @@ transitioning javascript builtin PromiseAnyRejectElementClosure(
           errors, 0, errors.length_intptr, newCapacity, PromiseHole);
       *errorsRef = errors;
     }
+
+  // 2. Let alreadyCalled be F.[[AlreadyCalled]].
+  // 3. If alreadyCalled.[[Value]] is true, return undefined.
+  // 4. Set alreadyCalled.[[Value]] to true.
+  if (errors.objects[index] != PromiseHole) deferred {
+      return Undefined;
+    }
+
+  // Make sure that we never see the PromiseHole here as a result.
+  check(value != PromiseHole);
   errors.objects[index] = value;

   // 10. Set remainingElementsCount.[[Value]] to
   // remainingElementsCount.[[Value]] - 1.
   remainingElementsCount = remainingElementsCount - 1;
+  check(remainingElementsCount >= 0);
   *ContextSlot(
       context,
       PromiseAnyRejectElementContextSlots::
diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc
index 2affa53f2fb..d32bb061c04 100644
--- a/deps/v8/src/compiler/js-generic-lowering.cc
+++ b/deps/v8/src/compiler/js-generic-lowering.cc
@@ -759,9 +759,6 @@ void JSGenericLowering::LowerJSGetTemplateObject(Node* node) {
   SharedFunctionInfoRef shared = p.shared();
   TemplateObjectDescriptionRef description = p.description();

-  DCHECK_EQ(node->op()->ControlInputCount(), 1);
-  node->RemoveInput(NodeProperties::FirstControlIndex(node));
-
   static_assert(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0);
   node->InsertInput(zone(), 0, jsgraph()->ConstantNoHole(shared, broker()));
   node->InsertInput(zone(), 1,
diff --git a/deps/v8/src/compiler/js-operator.cc b/deps/v8/src/compiler/js-operator.cc
index 5aec87c5ad3..75810fa1a73 100644
--- a/deps/v8/src/compiler/js-operator.cc
+++ b/deps/v8/src/compiler/js-operator.cc
@@ -1614,7 +1614,7 @@ const Operator* JSOperatorBuilder::GetTemplateObject(
   GetTemplateObjectParameters parameters(description, shared, feedback);
   return zone()->New<Operator1<GetTemplateObjectParameters>>(  // --
       IrOpcode::kJSGetTemplateObject,                          // opcode
-      Operator::kEliminatable,                                 // properties
+      Operator::kNoDeopt | Operator::kNoThrow,                 // properties
       "JSGetTemplateObject",                                   // name
       1, 1, 1, 1, 1, 0,                                        // counts
       parameters);                                             // parameter
diff --git a/deps/v8/src/compiler/turboshaft/pipelines.cc b/deps/v8/src/compiler/turboshaft/pipelines.cc
index 3c773aeac12..4aff92cb2a8 100644
--- a/deps/v8/src/compiler/turboshaft/pipelines.cc
+++ b/deps/v8/src/compiler/turboshaft/pipelines.cc
@@ -85,6 +85,21 @@ bool Pipeline::AllocateRegisters(const RegisterConfiguration* config,

   RUN_MAYBE_ABORT(DecideSpillingModePhase);
   RUN_MAYBE_ABORT(AssignSpillSlotsPhase);
+
+  // The prologue grows the frame with a single stack pointer decrement, before
+  // the function entry stack check runs. A frame no larger than the smallest OS
+  // page cannot step over a guard page, so bail out rather than emit an
+  // unchecked stack pointer jump of arbitrary size.
+  // When replacing this bailout with a different strategy, consider doing the
+  // same in Maglev as well.
+  constexpr int kMaxStackSlots = 4 * KB / kSystemPointerSize;
+  if (data_->info()->IsOptimizing() &&
+      data_->frame()->GetTotalFrameSlotCount() > kMaxStackSlots) {
+    data_->info()->AbortOptimization(BailoutReason::kFunctionTooBig);
+    data()->ClearRegisterComponent();
+    return false;
+  }
+
   RUN_MAYBE_ABORT(CommitAssignmentPhase);

   // TODO(chromium:725559): remove this check once
diff --git a/deps/v8/src/heap/cppgc-internal/marker.h b/deps/v8/src/heap/cppgc-internal/marker.h
index 84fec071262..ad96e22f188 100644
--- a/deps/v8/src/heap/cppgc-internal/marker.h
+++ b/deps/v8/src/heap/cppgc-internal/marker.h
@@ -10,6 +10,7 @@
 #include "include/cppgc/heap.h"
 #include "include/cppgc/platform.h"
 #include "include/cppgc/visitor.h"
+#include "src/base/logging.h"
 #include "src/base/macros.h"
 #include "src/base/platform/time.h"
 #include "src/heap/base/incremental-marking-schedule.h"
@@ -238,20 +239,15 @@ class V8_EXPORT_PRIVATE Marker final : public MarkerBase {

 template <MarkerBase::WriteBarrierType type>
 void MarkerBase::WriteBarrierForObject(HeapObjectHeader& header) {
-  // The barrier optimizes for the bailout cases:
-  // - kDijkstra: Marked objects.
-  // - kSteele: Unmarked objects.
-  switch (type) {
-    case MarkerBase::WriteBarrierType::kDijkstra:
-      if (!header.TryMarkAtomic()) {
-        return;
-      }
-      break;
-    case MarkerBase::WriteBarrierType::kSteele:
-      if (!header.IsMarked<AccessMode::kAtomic>()) {
-        return;
-      }
-      break;
+  // The Dijkstra barrier bails out on marked objects.
+  // The Steele barrier marks the object regardless of its current state.
+  // It's important to make sure the object is marked here since unmarking
+  // below for in construction objects expects a marked object.
+  const bool was_already_marked = !header.TryMarkAtomic();
+  if (type == MarkerBase::WriteBarrierType::kDijkstra) {
+    if (was_already_marked) {
+      return;
+    }
   }

   // The barrier fired. Filter out in-construction objects here. This possibly
@@ -267,13 +263,18 @@ void MarkerBase::WriteBarrierForObject(HeapObjectHeader& header) {
     return;
   }

-  switch (type) {
-    case MarkerBase::WriteBarrierType::kDijkstra:
-      mutator_marking_state_.write_barrier_worklist().Push(&header);
-      break;
-    case MarkerBase::WriteBarrierType::kSteele:
-      mutator_marking_state_.retrace_marked_objects_worklist().Push(&header);
-      break;
+  DCHECK_IMPLIES(was_already_marked,
+                 type == MarkerBase::WriteBarrierType::kSteele);
+  if ((type == MarkerBase::WriteBarrierType::kDijkstra) ||
+      !was_already_marked) {
+    // Push previously unmarked objects to the write barrier worklist, even for
+    // the Steele barrier, since popping from that worklist would also update
+    // the marked bytes counter.
+    mutator_marking_state_.write_barrier_worklist().Push(&header);
+  } else {
+    DCHECK((type == MarkerBase::WriteBarrierType::kSteele) &&
+           was_already_marked);
+    mutator_marking_state_.retrace_marked_objects_worklist().Push(&header);
   }
 }

diff --git a/deps/v8/src/maglev/maglev-compiler.cc b/deps/v8/src/maglev/maglev-compiler.cc
index 06dd7c5e301..74236225fc0 100644
--- a/deps/v8/src/maglev/maglev-compiler.cc
+++ b/deps/v8/src/maglev/maglev-compiler.cc
@@ -285,6 +285,8 @@ bool MaglevCompiler::Compile(LocalIsolate* local_isolate,
   // FunctionEntryStackCheck runs. A frame no larger than the smallest OS page
   // cannot step over a guard page, so bail out rather than emit an unchecked
   // stack pointer jump of arbitrary size.
+  // When replacing this bailout with a different strategy, consider doing the
+  // same in Turboshaft as well.
   if (graph->tagged_stack_slots() + graph->untagged_stack_slots() >
       kMaxStackSlots) {
     return false;
diff --git a/deps/v8/src/maglev/maglev-graph-builder.cc b/deps/v8/src/maglev/maglev-graph-builder.cc
index ca199bab0fa..d9ed8b2c9fb 100644
--- a/deps/v8/src/maglev/maglev-graph-builder.cc
+++ b/deps/v8/src/maglev/maglev-graph-builder.cc
@@ -6368,6 +6368,7 @@ void MaglevGraphBuilder::AdvanceThroughContinuationForPolymorphicPropertyLoad(
   while (iterator_.current_offset() < continuation.last_continuation) {
     iterator_.Advance();
     UpdateSourceAndBytecodePosition(iterator_.current_offset());
+    PrewalkBytecode();
   }
 }

diff --git a/deps/v8/src/objects/js-function.cc b/deps/v8/src/objects/js-function.cc
index 585d97d436c..310ed57d8ad 100644
--- a/deps/v8/src/objects/js-function.cc
+++ b/deps/v8/src/objects/js-function.cc
@@ -991,8 +991,9 @@ void JSFunction::EnsureHasInitialMap(Isolate* isolate,
   // system.
   // TODO(leszeks): Figure out if this CHECK is needed.
   CHECK(IsJSReceiver(*prototype));
-  JSFunction::SetInitialMap(isolate, function, map, prototype);
+  // Initialize slack tracking before publishing the map to concurrent readers.
   map->StartInobjectSlackTracking();
+  JSFunction::SetInitialMap(isolate, function, map, prototype);
 }

 namespace {
@@ -1183,11 +1184,12 @@ bool FastInitializeDerivedMap(Isolate* isolate,
       Map::CopyInitialMap(isolate, constructor_initial_map, instance_size,
                           in_object_properties, unused_property_fields);
   map->set_new_target_is_base(false);
+  // Initialize slack tracking before publishing the map to concurrent readers.
+  map->set_construction_counter(Map::kNoSlackTracking);
+  map->StartInobjectSlackTracking();
   DirectHandle<JSReceiver> prototype(new_target->instance_prototype(), isolate);
   JSFunction::SetInitialMap(isolate, new_target, map, prototype, constructor);
   DCHECK(IsJSReceiver(new_target->instance_prototype()));
-  map->set_construction_counter(Map::kNoSlackTracking);
-  map->StartInobjectSlackTracking();
   return true;
 }

diff --git a/deps/v8/src/objects/map-inl.h b/deps/v8/src/objects/map-inl.h
index 1cbddb0d987..63cfe9edd10 100644
--- a/deps/v8/src/objects/map-inl.h
+++ b/deps/v8/src/objects/map-inl.h
@@ -1258,9 +1258,12 @@ void Map::InobjectSlackTrackingStep(Isolate* isolate) {
   DCHECK(IsUndefined(GetBackPointer()));
   if (!this->IsInobjectSlackTrackingInProgress()) return;
   int counter = construction_counter();
-  set_construction_counter(counter - 1);
   if (counter == kSlackTrackingCounterEnd) {
+    // The last decrement must happen under the map_updater_access mutex,
+    // together with the instance size changes.
     MapUpdater::CompleteInobjectSlackTracking(isolate, this);
+  } else {
+    set_construction_counter(counter - 1);
   }
 }

diff --git a/deps/v8/src/objects/map-updater.cc b/deps/v8/src/objects/map-updater.cc
index f1437356d69..84999a3a34d 100644
--- a/deps/v8/src/objects/map-updater.cc
+++ b/deps/v8/src/objects/map-updater.cc
@@ -400,7 +400,9 @@ std::optional<Tagged<Map>> MapUpdater::TryUpdateNoLock(Isolate* isolate,
   ElementsKind to_kind = old_map->elements_kind();

   IntegrityLevelTransitionInfo info(old_map);
-  if (root_map->is_extensible() != old_map->is_extensible()) {
+  if (!root_map->is_extensible() && old_map != root_map) {
+    return {};
+  } else if (root_map->is_extensible() != old_map->is_extensible()) {
     DCHECK(!old_map->is_extensible());
     DCHECK(root_map->is_extensible());
     info = DetectIntegrityLevelTransitions(old_map, isolate, &no_gc, cmode);
@@ -412,7 +414,7 @@ std::optional<Tagged<Map>> MapUpdater::TryUpdateNoLock(Isolate* isolate,
     DCHECK(to_kind == DICTIONARY_ELEMENTS ||
            to_kind == SLOW_STRING_WRAPPER_ELEMENTS ||
            IsTypedArrayOrRabGsabTypedArrayElementsKind(to_kind) ||
-           IsAnyHoleyNonextensibleElementsKind(to_kind));
+           IsAnyNonextensibleElementsKind(to_kind));
     to_kind = info.integrity_level_source_map->elements_kind();
   }
   if (from_kind != to_kind) {
@@ -622,6 +624,8 @@ MapUpdater::State MapUpdater::FindRootMap() {
           direct_handle(root_map_->prototype(), isolate_),
           root_map_->instance_type())) {
     return Normalize("Normalize_NotEquivalent");
+  } else if (!root_map_->is_extensible() && *old_map_ != *root_map_) {
+    return Normalize("Normalize_PrivateSymbolsOnNonExtensible");
   } else if (old_map_->is_extensible() != root_map_->is_extensible()) {
     DCHECK(!old_map_->is_extensible());
     DCHECK(root_map_->is_extensible());
diff --git a/deps/v8/src/objects/map.cc b/deps/v8/src/objects/map.cc
index a6f6a26a945..cdc41455019 100644
--- a/deps/v8/src/objects/map.cc
+++ b/deps/v8/src/objects/map.cc
@@ -603,10 +603,7 @@ MaybeHandle<Map> Map::CopyWithField(Isolate* isolate, DirectHandle<Map> map,
   MaybeObjectDirectHandle wrapped_type = WrapFieldType(type);
   Descriptor d = Descriptor::DataField(name, offset, attributes, constness,
                                        representation, wrapped_type);
-  Handle<Map> new_map = Map::CopyAddDescriptor(isolate, map, &d, flag);
-
-  new_map->AccountAddedPropertyField();
-  return new_map;
+  return Map::CopyAddDescriptor(isolate, map, &d, flag);
 }

 MaybeHandle<Map> Map::CopyWithConstant(Isolate* isolate, DirectHandle<Map> map,
@@ -1615,6 +1612,10 @@ Handle<Map> Map::ShareDescriptor(Isolate* isolate, DirectHandle<Map> map,
     DisallowGarbageCollection no_gc;
     descriptors->Append(descriptor);
     result->InitializeDescriptors(*descriptors);
+    // Account for the field before publishing the transition.
+    if (descriptor->GetDetails().location() == PropertyLocation::kField) {
+      result->AccountAddedPropertyField();
+    }
   }

   DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
@@ -2333,7 +2334,12 @@ Handle<Map> Map::CopyAddDescriptor(Isolate* isolate, DirectHandle<Map> map,
       DescriptorArray::CopyUpTo(isolate, descriptors, nof, 1);
   new_descriptors->Append(descriptor);

-  return CopyReplaceDescriptors(isolate, map, new_descriptors, flag,
+  auto InitMap = [&](DirectHandle<Map> new_map) {
+    if (descriptor->GetDetails().location() == PropertyLocation::kField) {
+      new_map->AccountAddedPropertyField();
+    }
+  };
+  return CopyReplaceDescriptors(isolate, map, new_descriptors, flag, InitMap,
                                 descriptor->GetKey(), "CopyAddDescriptor",
                                 SIMPLE_PROPERTY_TRANSITION);
 }
diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc
index 312f5ddcf90..4a3cfca512d 100644
--- a/deps/v8/src/runtime/runtime-literals.cc
+++ b/deps/v8/src/runtime/runtime-literals.cc
@@ -856,6 +856,14 @@ static bool IsDefaultFunctionPrototype(DirectHandle<JSObject> js_proto,
   // Object function prototype's map.
   Tagged<Map> proto_map = js_proto->map();

+  // Check that the prototype is a plain JSObject with no elements.
+  if (proto_map->instance_type() != JS_OBJECT_TYPE) {
+    return false;
+  }
+  if (js_proto->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
+    return false;
+  }
+
   // Check that given function.prototype object has a default initial state:
   // it's extensible.
   if (!proto_map->is_extensible()) {
@@ -868,13 +876,24 @@ static bool IsDefaultFunctionPrototype(DirectHandle<JSObject> js_proto,
   }

   // it has exactly one "constructor" property installed.
-  if (js_proto->property_dictionary()->NumberOfElements() != 1) {
-    return false;
-  }
-  if (js_proto->property_dictionary()
-          ->FindEntry(isolate, isolate->factory()->constructor_string())
-          .is_not_found()) {
-    return false;
+  if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
+    if (js_proto->property_dictionary_swiss()->NumberOfElements() != 1) {
+      return false;
+    }
+    if (js_proto->property_dictionary_swiss()
+            ->FindEntry(isolate, isolate->factory()->constructor_string())
+            .is_not_found()) {
+      return false;
+    }
+  } else {
+    if (js_proto->property_dictionary()->NumberOfElements() != 1) {
+      return false;
+    }
+    if (js_proto->property_dictionary()
+            ->FindEntry(isolate, isolate->factory()->constructor_string())
+            .is_not_found()) {
+      return false;
+    }
   }

   // its prototype is the original and unmodified Object.prototype object.
@@ -907,7 +926,7 @@ RUNTIME_FUNCTION(Runtime_SetPrototypeProperties) {
   }

   DirectHandle<JSFunction> acc_fun = Cast<JSFunction>(obj);
-  if (!acc_fun->has_prototype_slot()) {
+  if (!acc_fun->has_prototype_slot() || !acc_fun->has_prototype_property()) {
     RETURN_RESULT_OR_FAILURE(
         isolate, SetPrototypePropertiesSlow(isolate, context, obj,
                                             object_boilerplate_description,
@@ -937,18 +956,21 @@ RUNTIME_FUNCTION(Runtime_SetPrototypeProperties) {
                                             feedback_cell_array, current_slot));
   }

-  if (IsSpecialReceiverMap(js_proto->map())) {
-    RETURN_RESULT_OR_FAILURE(
-        isolate, SetPrototypePropertiesSlow(isolate, context, obj,
-                                            object_boilerplate_description,
-                                            feedback_cell_array, current_slot));
-  }
-
-  if (!JSObject::IsExtensible(isolate, js_proto)) {
-    RETURN_RESULT_OR_FAILURE(
-        isolate, SetPrototypePropertiesSlow(isolate, context, obj,
-                                            object_boilerplate_description,
-                                            feedback_cell_array, current_slot));
+  // Use the slow path for exotic receivers, interceptors, or access checks.
+  {
+    Tagged<Map> js_proto_map = js_proto->map();
+    if (IsCustomElementsReceiverMap(js_proto_map) ||
+        IsJSTypedArrayMap(js_proto_map) ||
+        IsAlwaysSharedSpaceJSObjectMap(js_proto_map) ||
+        js_proto_map->is_access_check_needed() ||
+        js_proto_map->has_named_interceptor() ||
+        js_proto_map->has_indexed_interceptor() ||
+        !JSObject::IsExtensible(isolate, js_proto)) {
+      RETURN_RESULT_OR_FAILURE(
+          isolate, SetPrototypePropertiesSlow(
+                       isolate, context, obj, object_boilerplate_description,
+                       feedback_cell_array, current_slot));
+    }
   }

   bool is_default_func_prototype =
@@ -977,13 +999,14 @@ RUNTIME_FUNCTION(Runtime_SetPrototypeProperties) {
         DirectHandle<AccessorInfo> accessor_info =
             isolate->factory()->lazy_closure_accessor();

-        JSObject::SetAccessor(js_proto, name, accessor_info,
-                              PropertyAttributes::NONE)
-            .Check();
+        RETURN_FAILURE_ON_EXCEPTION(
+            isolate, JSObject::SetAccessor(js_proto, name, accessor_info,
+                                           PropertyAttributes::NONE));
       } else {
-        Object::TransitionAndWriteDataProperty(
-            &it, value, NONE, Just(kDontThrow), StoreOrigin::kNamed)
-            .Check();
+        MAYBE_RETURN(
+            Object::TransitionAndWriteDataProperty(
+                &it, value, NONE, Just(kDontThrow), StoreOrigin::kNamed),
+            ReadOnlyRoots(isolate).exception());
       }
       result = value;
     }
@@ -1029,7 +1052,8 @@ RUNTIME_FUNCTION(Runtime_SetPrototypeProperties) {
           current_slot++;
         }
         it.UpdateProtector();
-        Object::SetDataProperty(&it, value).Check();
+        MAYBE_RETURN(Object::SetDataProperty(&it, value),
+                     ReadOnlyRoots(isolate).exception());
       } else {
         value = InstantiateIfSharedFunctionInfo(
             context, isolate, js_proto, value, feedback_cell_array,
@@ -1042,13 +1066,15 @@ RUNTIME_FUNCTION(Runtime_SetPrototypeProperties) {
           // doesn't invalidate protectors, so do it here for e.g. `then` or
           // `next` added to a watched prototype.
           it.UpdateProtector();
-          JSObject::SetAccessor(js_proto, Cast<Name>(key), accessor_info,
-                                PropertyAttributes::NONE)
-              .Check();
+          RETURN_FAILURE_ON_EXCEPTION(
+              isolate,
+              JSObject::SetAccessor(js_proto, Cast<Name>(key), accessor_info,
+                                    PropertyAttributes::NONE));
         } else {
-          Object::TransitionAndWriteDataProperty(
-              &it, value, NONE, Just(kDontThrow), StoreOrigin::kNamed)
-              .Check();
+          MAYBE_RETURN(
+              Object::TransitionAndWriteDataProperty(
+                  &it, value, NONE, Just(kDontThrow), StoreOrigin::kNamed),
+              ReadOnlyRoots(isolate).exception());
         }
       }
       result = value;
diff --git a/deps/v8/test/mjsunit/compiler/regress-574339635.js b/deps/v8/test/mjsunit/compiler/regress-574339635.js
new file mode 100644
index 00000000000..f131352bccf
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-574339635.js
@@ -0,0 +1,37 @@
+// 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: --turbofan --allow-natives-syntax
+
+const P = Array.prototype;
+const Obj = Object;
+let s;
+
+function foo(o, t) {
+  o[0];
+  let r = 0;
+  if (t) r = Obj`hello`;
+  const v = o.x;
+  s = r;
+  return v;
+}
+
+new WeakMap().set(P, 1);
+for (const _ in []) {}
+P[0] = 1;
+P.x = 1;
+Object.defineProperty(P, "x", {value: 1.5, enumerable: false});
+
+%PrepareFunctionForOptimization(foo);
+foo(P, false); foo(P, false); foo(P, false);
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(1.5, foo(P, false));
+
+for (let i = 0; i < 400; i += 3) {
+  P["p" + i] = "x";
+  P["p" + (i + 1)] = "corrupted";
+  P["p" + (i + 2)] = 0;
+}
+
+assertEquals(1.5, foo(P, true));
diff --git a/deps/v8/test/mjsunit/compiler/regress-578688670.js b/deps/v8/test/mjsunit/compiler/regress-578688670.js
new file mode 100644
index 00000000000..b16f0752f28
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-578688670.js
@@ -0,0 +1,56 @@
+// 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
+
+let rejected_error;
+function CustomPromise(executor) {
+  executor(() => {}, (err) => { rejected_error = err; });
+}
+
+let captured_reject_closure;
+CustomPromise.resolve = function(thenable) {
+  return thenable;
+};
+
+const pending_thenables = [
+  { then(resolve, reject) { captured_reject_closure = reject; } },
+  { then() {} },
+  { then() {} },
+];
+
+Promise.any.call(CustomPromise, pending_thenables);
+
+// Store the reject element closure on a constant holder so that inlining
+// invoke_reject_closure into call_reject_closure constant-folds the closure
+// target and its initial FunctionContext.
+const closure_holder = { reject: captured_reject_closure };
+
+function invoke_reject_closure(closure, should_call) {
+  if (should_call) closure('err');
+}
+
+function call_reject_closure(should_call) {
+  invoke_reject_closure(closure_holder.reject, should_call);
+}
+
+// Make the call site inside invoke_reject_closure polymorphic before
+// calling captured_reject_closure so Maglev/TurboFan compile the call without
+// invoking captured_reject_closure during warmup.
+%PrepareFunctionForOptimization(invoke_reject_closure);
+invoke_reject_closure(() => {}, true);
+invoke_reject_closure((x) => x, true);
+
+%PrepareFunctionForOptimization(call_reject_closure);
+call_reject_closure(false);
+%OptimizeFunctionOnNextCall(call_reject_closure);
+call_reject_closure(false);
+
+// Repeated calls to the same reject element closure must be ignored after the
+// first call and must not decrement remainingElementsCount to 0.
+call_reject_closure(true);
+call_reject_closure(true);
+call_reject_closure(true);
+
+assertEquals(undefined, rejected_error);
diff --git a/deps/v8/test/mjsunit/maglev/regress-574021176.js b/deps/v8/test/mjsunit/maglev/regress-574021176.js
new file mode 100644
index 00000000000..780b5b1c8cf
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-574021176.js
@@ -0,0 +1,44 @@
+// 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
+
+let g = () => class {};
+
+function* gen(o) {
+  // Context-allocated, maybe-assigned variable so the function context uses a
+  // ContextCell for `x`.
+  let x = 42;
+  () => x = 0;
+
+  // Polymorphic property load with a call continuation. The class literal
+  // pushes a `CLASS_SCOPE` context (needed for `super.x`) before evaluating
+  // `extends g()` and pops it after defining the class. When `g()` aborts in
+  // every polymorphic arm, skipping the rest of the continuation must still pop
+  // that `CLASS_SCOPE`.
+  o.f(class extends g() {
+    constructor() {
+      super.x;
+    }
+  });
+
+  // In dead code after all polymorphic arms abort, `SuspendGenerator` records
+  // `current_scope_info_` on the `ResumeGenerator` merge state.
+  yield;
+
+  // Loads `x` using the `ScopeInfo` from the resume merge state (which must be
+  // the generator's `FUNCTION_SCOPE` with cells, not the leaked `CLASS_SCOPE`).
+  return x;
+}
+
+const suspended = gen({f() {}});
+suspended.next();
+
+g = class {};
+%PrepareFunctionForOptimization(gen);
+assertThrows(() => gen({f() {}}).next(), TypeError);
+assertThrows(() => gen({a: 1, f() {}}).next(), TypeError);
+
+%OptimizeFunctionOnNextCall(gen);
+assertEquals(42, suspended.next().value);
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/regress-577944790.js b/deps/v8/test/mjsunit/opt-proto-seq/regress-577944790.js
new file mode 100644
index 00000000000..e01a1280d53
--- /dev/null
+++ b/deps/v8/test/mjsunit/opt-proto-seq/regress-577944790.js
@@ -0,0 +1,65 @@
+// 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: --mock-arraybuffer-allocator
+
+// Test exception propagation when a TypedArray prototype rejects a BigInt store.
+(function testLargeTypedArrayStoreException() {
+  let ta;
+  try {
+    ta = new Int8Array(4294967296);
+  } catch (e) {
+    assertInstanceof(e, RangeError);
+    return;
+  }
+
+  assertThrows(() => {
+    function F() {}
+    F.prototype = ta;
+    F.prototype['4294967295'] = 1n;
+    F.prototype.named = 1;
+  }, TypeError);
+
+  assertEquals(undefined, ta.named);
+})();
+
+// Test exception propagation when valueOf throws during a TypedArray store.
+(function testLargeTypedArrayValueOfException() {
+  let ta;
+  try {
+    ta = new Uint8Array(4294967296);
+  } catch (e) {
+    assertInstanceof(e, RangeError);
+    return;
+  }
+
+  const badValue = {
+    valueOf() {
+      throw new URIError();
+    },
+  };
+
+  assertThrows(() => {
+    function F() {}
+    F.prototype = ta;
+    F.prototype['4294967295'] = badValue;
+    F.prototype.named = 2;
+  }, URIError);
+
+  assertEquals(undefined, ta.named);
+})();
+
+// Test exception propagation on a small BigInt64Array prototype.
+(function testBigIntTypedArrayStoreException() {
+  const ta = new BigInt64Array(4);
+
+  assertThrows(() => {
+    function F() {}
+    F.prototype = ta;
+    F.prototype['4294967295'] = 1;
+    F.prototype.named = 3;
+  }, TypeError);
+
+  assertEquals(undefined, ta.named);
+})();
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/regress-578083257.js b/deps/v8/test/mjsunit/opt-proto-seq/regress-578083257.js
new file mode 100644
index 00000000000..30e50a33d98
--- /dev/null
+++ b/deps/v8/test/mjsunit/opt-proto-seq/regress-578083257.js
@@ -0,0 +1,63 @@
+// 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.
+
+// Create a dictionary-mode TypedArray that mimics a default function prototype.
+function makeDictionaryTypedArray() {
+  const ta = new Uint8Array(4);
+  ta.temp = 1;
+  delete ta.temp;
+  ta.constructor = Object;
+  Object.setPrototypeOf(ta, Object.prototype);
+  return ta;
+}
+
+// Test integer indices above kMaxElementIndex on a TypedArray prototype.
+(function testTypedArrayLargeIntegerIndices() {
+  const ta = makeDictionaryTypedArray();
+  function F() {}
+  F.prototype = ta;
+  F.prototype['4294967295'] = 1;
+  F.prototype['4294967296'] = 2;
+  F.prototype.named = 3;
+
+  assertEquals(undefined, Object.getOwnPropertyDescriptor(ta, '4294967295'));
+  assertEquals(undefined, Object.getOwnPropertyDescriptor(ta, '4294967296'));
+  assertEquals(undefined, ta['4294967295']);
+  assertEquals(undefined, ta['4294967296']);
+  assertEquals(3, ta.named);
+})();
+
+// Test canonical numeric index strings on a TypedArray prototype.
+(function testTypedArraySpecialNumericIndices() {
+  const ta = makeDictionaryTypedArray();
+  function F() {}
+  F.prototype = ta;
+  F.prototype['1.5'] = 1;
+  F.prototype['-0'] = 2;
+  F.prototype.named = 3;
+
+  assertEquals(undefined, Object.getOwnPropertyDescriptor(ta, '1.5'));
+  assertEquals(undefined, Object.getOwnPropertyDescriptor(ta, '-0'));
+  assertEquals(undefined, ta['1.5']);
+  assertEquals(undefined, ta['-0']);
+  assertEquals(3, ta.named);
+})();
+
+// Test a dictionary-mode String wrapper as a function prototype.
+(function testStringWrapperPrototype() {
+  const wrapper = new String('abc');
+  wrapper.temp = 1;
+  delete wrapper.temp;
+  wrapper.constructor = Object;
+  Object.setPrototypeOf(wrapper, Object.prototype);
+
+  function F() {}
+  F.prototype = wrapper;
+  F.prototype.first = 10;
+  F.prototype.second = 20;
+
+  assertEquals(10, wrapper.first);
+  assertEquals(20, wrapper.second);
+  assertEquals('a', wrapper[0]);
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-577318603.js b/deps/v8/test/mjsunit/regress/regress-577318603.js
new file mode 100644
index 00000000000..e89da019658
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-577318603.js
@@ -0,0 +1,74 @@
+// 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: --no-js-nonextensible-applies-to-private
+
+class Base {
+  constructor(o) {
+    return o;
+  }
+}
+
+class InstallPrivateField extends Base {
+  #p = 1;
+  static setP(o, v) {
+    o.#p = v;
+  }
+  static getP(o) {
+    return o.#p;
+  }
+}
+
+// Private field added onto a non-extensible root map before Object.seal.
+{
+  const obj = new Date();
+  obj[0] = 1;
+  obj.x = 1;
+
+  Object.preventExtensions(obj);
+  Object.defineProperty(obj, 0, { enumerable: false });
+
+  new InstallPrivateField(obj);
+  Object.seal(obj);
+  InstallPrivateField.setP(obj, 1.5);
+
+  assertEquals(1.5, InstallPrivateField.getP(obj));
+  assertFalse(Object.getOwnPropertyDescriptor(obj, 'x').configurable);
+}
+
+// Object.seal on a non-extensible root map before adding a private field.
+{
+  const obj = new Date();
+  obj[0] = 1;
+  obj.x = 1;
+
+  Object.preventExtensions(obj);
+  Object.defineProperty(obj, 0, { enumerable: false });
+
+  Object.seal(obj);
+  new InstallPrivateField(obj);
+  InstallPrivateField.setP(obj, 1.5);
+
+  assertEquals(1.5, InstallPrivateField.getP(obj));
+  assertFalse(Object.getOwnPropertyDescriptor(obj, 'x').configurable);
+}
+
+// Constness generalization of a root-map property after Object.seal on a
+// non-extensible dictionary-elements root map must not drop the seal
+// transition.
+{
+  const obj = new Date();
+  obj[0] = 1;
+  obj.x = 1;
+
+  Object.preventExtensions(obj);
+  Object.defineProperty(obj, 0, { enumerable: false });
+
+  Object.seal(obj);
+  obj.x = 2;
+
+  assertEquals(2, obj.x);
+  assertTrue(Object.isSealed(obj));
+  assertFalse(Object.getOwnPropertyDescriptor(obj, 'x').configurable);
+}
diff --git a/deps/v8/test/mjsunit/turboshaft/regress-574660146.js b/deps/v8/test/mjsunit/turboshaft/regress-574660146.js
new file mode 100644
index 00000000000..bc82a2684ba
--- /dev/null
+++ b/deps/v8/test/mjsunit/turboshaft/regress-574660146.js
@@ -0,0 +1,41 @@
+// 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 --turbofan --no-maglev
+
+function cb() {
+  return arguments.length;
+}
+%NeverOptimizeFunction(cb);
+
+// Passing `kArgCount` distinct expressions to a non-inlined call keeps all of
+// them live simultaneously at the call site, requiring > 1024 stack slots
+// (> 4KB on both 32-bit and 64-bit targets) while keeping the bytecode small
+// enough to be compiled.
+const kArgCount = 1100;
+const args = Array.from({length: kArgCount}, (_, k) => `p ^ ${k + 1}`);
+
+function buildWideFrame(osr) {
+  return Function('x', 'cb', 'p', `
+    let result = 0;
+    for (let i = 0; i < 10; ++i) {
+      ${osr ? 'if (i === 5) %OptimizeOsr();' : ''}
+      if (x < 0) return cb(${args});
+      result = (x + i) | 0;
+    }
+    return result;
+  `);
+}
+
+const wide = buildWideFrame(false);
+%PrepareFunctionForOptimization(wide);
+assertEquals(kArgCount, wide(-1, cb, 1));
+assertEquals(10, wide(1, cb, 1));
+%OptimizeFunctionOnNextCall(wide);
+assertEquals(10, wide(1, cb, 1));
+
+const wideOsr = buildWideFrame(true);
+%PrepareFunctionForOptimization(wideOsr);
+assertEquals(kArgCount, wideOsr(-1, cb, 1));
+assertEquals(10, wideOsr(1, cb, 1));
diff --git a/deps/v8/test/unittests/heap/cppgc/write-barrier-unittest.cc b/deps/v8/test/unittests/heap/cppgc/write-barrier-unittest.cc
index 9df26a108ca..bfe99ffa50e 100644
--- a/deps/v8/test/unittests/heap/cppgc/write-barrier-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc/write-barrier-unittest.cc
@@ -476,11 +476,11 @@ TEST_F(WriteBarrierTest, SteeleWriteBarrierTriggersWhenMarkingIsOn) {
   }
 }

-TEST_F(WriteBarrierTest, SteeleWriteBarrierBailoutIfNotMarked) {
+TEST_F(WriteBarrierTest, SteeleWriteBarrierTriggersEvenIfNotMarked) {
   auto* object1 = MakeGarbageCollected<GCed>(GetAllocationHandle());
   auto* object2 = MakeGarbageCollected<GCed>(GetAllocationHandle(), object1);
   {
-    ExpectNoWriteBarrierFires scope(marker(), {object1});
+    ExpectWriteBarrierFires scope(marker(), {object1});
     WriteBarrierParams params;
     EXPECT_EQ(WriteBarrierType::kMarking,
               HeapConsistency::GetWriteBarrierType(