Commit fc2b3fb0d0b for nodejs

commit fc2b3fb0d0b7fac533f772946041e3ba10386840
Author: Joyee Cheung <joyeec9h3@gmail.com>
Date:   Wed Oct 7 23:45:56 2026 +0200

    deps: V8: cherry-pick 5dfeb2e42380

    Original commit message:

        [sandbox] fix dispatch table access on illumos

        illumos pointers are VA48, can allocate from the top of the 64-bit range
        as well.

        Co-Authored-By: Dan McDonald <danmcd@mnx.io>
        Refs: https://github.com/nodejs/node/pull/65161

    Refs: https://github.com/v8/v8/commit/5dfeb2e42380ceb87d062017dd253312cdaef0a6
    Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
    PR-URL: https://github.com/nodejs/node/pull/66601
    Reviewed-By: Richard Lau <richard.lau@ibm.com>
    Reviewed-By: Filip Skokan <panva.ip@gmail.com>
    Reviewed-By: Chengzhong Wu <legendecas@gmail.com>

diff --git a/common.gypi b/common.gypi
index fcdd1d8a047..07137b628a1 100644
--- a/common.gypi
+++ b/common.gypi
@@ -44,7 +44,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.2',
+    'v8_embedder_string': '-node.3',

     ##### V8 defaults for Node.js #####

diff --git a/deps/v8/src/codegen/code-stub-assembler.cc b/deps/v8/src/codegen/code-stub-assembler.cc
index 200a57e7574..180facb5121 100644
--- a/deps/v8/src/codegen/code-stub-assembler.cc
+++ b/deps/v8/src/codegen/code-stub-assembler.cc
@@ -2217,7 +2217,17 @@ TNode<Code> CodeStubAssembler::LoadCodeObjectFromJSDispatchTable(
   TNode<UintPtrT> shifted_value;
   if (JSDispatchEntry::kObjectPointerOffset == 0) {
     shifted_value =
+#if defined(__illumos__) && defined(V8_HOST_ARCH_64_BIT)
+        // Pointers in illumos span both the low 2^47 range and the high 2^47
+        // range as well. Checking the high bit being set in illumos means all
+        // higher bits need to be set to 1 after shifting right. Use WordSar()
+        // so any high-bit check wouldn't be necessary.
+        UncheckedCast<UintPtrT>(
+            WordSar(UncheckedCast<IntPtrT>(value),
+                    IntPtrConstant(JSDispatchEntry::kObjectPointerShift)));
+#else
         WordShr(value, UintPtrConstant(JSDispatchEntry::kObjectPointerShift));
+#endif /* __illumos__ and 64-bit */
   } else {
     shifted_value = UintPtrAdd(
         WordShr(value, UintPtrConstant(JSDispatchEntry::kObjectPointerShift)),
diff --git a/deps/v8/src/sandbox/js-dispatch-table-inl.h b/deps/v8/src/sandbox/js-dispatch-table-inl.h
index 5566fc682a0..e9d2b88b270 100644
--- a/deps/v8/src/sandbox/js-dispatch-table-inl.h
+++ b/deps/v8/src/sandbox/js-dispatch-table-inl.h
@@ -29,6 +29,7 @@ void JSDispatchEntry::MakeJSDispatchEntry(Address object, Address entrypoint,
                                           bool mark_as_alive) {
   DCHECK_NE(entrypoint, kNullAddress);
   DCHECK_EQ(object & kHeapObjectTag, 0);
+#if !defined(__illumos__) || !defined(V8_TARGET_ARCH_64_BIT)
   DCHECK_EQ((((object - kObjectPointerOffset) << kObjectPointerShift) >>
              kObjectPointerShift) +
                 kObjectPointerOffset,
@@ -36,6 +37,7 @@ void JSDispatchEntry::MakeJSDispatchEntry(Address object, Address entrypoint,
   DCHECK_EQ((object - kObjectPointerOffset) + kObjectPointerOffset, object);
   DCHECK_LT((object - kObjectPointerOffset),
             1ULL << ((sizeof(encoded_word_) * 8) - kObjectPointerShift));
+#endif /* __illumos__ & 64-bit */

   Address payload = ((object - kObjectPointerOffset) << kObjectPointerShift) |
                     (parameter_count & kParameterCountMask);
@@ -61,8 +63,17 @@ Address JSDispatchEntry::GetCodePointer() const {
   // and so may be 0 or 1 here. As the return value is a tagged pointer, the
   // bit must be 1 when returned, so we need to set it here.
   Address payload = encoded_word_.load(std::memory_order_acquire);
+#if defined(__illumos__) && defined(V8_TARGET_ARCH_64_BIT)
+  // Unsigned types won't sign-extend on shift-right, but we need to do
+  // this with illumos VA48 addressing.
+  DCHECK_EQ(kObjectPointerOffset, 0);
+  return (Address)(static_cast<intptr_t>(payload) >>
+                   static_cast<int>(kObjectPointerShift)) |
+         kHeapObjectTag;
+#else
   return ((payload >> kObjectPointerShift) + kObjectPointerOffset) |
          kHeapObjectTag;
+#endif /* __illumos__ & 64-bit */
 }

 Tagged<Code> JSDispatchEntry::GetCode() const {
@@ -269,7 +280,12 @@ void JSDispatchEntry::MakeFreelistEntry(uint32_t next_entry_index) {

 #ifdef V8_TARGET_ARCH_64_BIT
 bool JSDispatchEntry::IsFreelistEntry(Address entrypoint) const {
+#ifdef __illumos__
+  // See the illumos definition of kFreeEntryTag for why we have to do this.
+  return (entrypoint & 0xffff000000000000ull) == kFreeEntryTag;
+#else
   return (entrypoint & kFreeEntryTag) == kFreeEntryTag;
+#endif /* __illumos__ */
 }
 #endif

diff --git a/deps/v8/src/sandbox/js-dispatch-table.h b/deps/v8/src/sandbox/js-dispatch-table.h
index 0912c4037eb..830fa95fd3e 100644
--- a/deps/v8/src/sandbox/js-dispatch-table.h
+++ b/deps/v8/src/sandbox/js-dispatch-table.h
@@ -96,7 +96,22 @@ struct JSDispatchEntry {
 #if defined(V8_TARGET_ARCH_64_BIT)
   // Freelist entries contain the index of the next free entry in their lower 32
   // bits and are tagged with this tag.
+#ifdef __illumos__
+  // In illumos 64-bit apps, pointers are allocated both the bottom 2^47 range
+  // AND the top 2^47 range in the 64-bit space. Instead of 47 bits of VA space
+  // we have 48 bits. This means, however, the top 16-bits may be 0xffff. We
+  // therefore pick a different value for the kFreeEntryTag.  If/when we go to
+  // VA57, aka 5-level paging, we'll need to revisit this again, as will node
+  // by default, since the fixed-bits on the high end will shrink from top
+  // 16-bits to top 8-bits.
+  //
+  // Unless illumos ships an Oracle-Solaris-like VA47 link-time options to
+  // restrict pointers from allocating from above the Virtual Address hole,
+  // we need to be mindful of this.
+  static constexpr Address kFreeEntryTag = 0xfeed000000000000ull;
+#else
   static constexpr Address kFreeEntryTag = 0xffff000000000000ull;
+#endif /* __illumos__ */
 #ifdef V8_TARGET_BIG_ENDIAN
   // 2-byte parameter count is on the least significant side of encoded_word_.
   static constexpr int kBigEndianParamCountOffset =