Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
deps: patch V8 for illumos
illumos pointers are VA48, can allocate from the top of the 64-bit range
as well.

PR-URL: #59805
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
  • Loading branch information
Dan McDonald authored and targos committed Nov 12, 2025
commit 55ab9c4b5e72554a282bc000c5b879fcad961fff
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -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.4',
'v8_embedder_string': '-node.5',

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

Expand Down
9 changes: 9 additions & 0 deletions deps/v8/src/codegen/code-stub-assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2043,7 +2043,16 @@ 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)),
Expand Down
15 changes: 15 additions & 0 deletions deps/v8/src/sandbox/js-dispatch-table-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ void JSDispatchEntry::MakeJSDispatchEntry(Address object, Address entrypoint,
uint16_t parameter_count,
bool mark_as_alive) {
DCHECK_EQ(object & kHeapObjectTag, 0);
#if !defined(__illumos__) || !defined(V8_TARGET_ARCH_64_BIT)
DCHECK_EQ((((object - kObjectPointerOffset) << kObjectPointerShift) >>
kObjectPointerShift) +
kObjectPointerOffset,
object);
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);
Expand All @@ -57,8 +59,16 @@ 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)((intptr_t)payload >> (int)kObjectPointerShift) |
kHeapObjectTag;
#else
return ((payload >> kObjectPointerShift) + kObjectPointerOffset) |
kHeapObjectTag;
#endif /* __illumos__ & 64-bit */
}

Tagged<Code> JSDispatchEntry::GetCode() const {
Expand Down Expand Up @@ -220,7 +230,12 @@ void JSDispatchEntry::MakeFreelistEntry(uint32_t next_entry_index) {
bool JSDispatchEntry::IsFreelistEntry() const {
#ifdef V8_TARGET_ARCH_64_BIT
auto entrypoint = entrypoint_.load(std::memory_order_relaxed);
#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__ */
#else
return next_free_entry_.load(std::memory_order_relaxed) != 0;
#endif
Expand Down
15 changes: 15 additions & 0 deletions deps/v8/src/sandbox/js-dispatch-table.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,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 =
Expand Down