Skip to content

Commit cf385b3

Browse files
danmcdnodejs-github-bot
authored andcommitted
deps: patch V8 for illumos
illumos pointers are VA48, can allocate from the top of the 64-bit range as well. PR-URL: nodejs/node#59805 Reviewed-By: Filip Skokan <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent d88640a commit cf385b3

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.4',
41+
'v8_embedder_string': '-node.5',
4242

4343
##### V8 defaults for Node.js #####
4444

deps/v8/src/codegen/code-stub-assembler.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,7 +2042,16 @@ TNode<Code> CodeStubAssembler::LoadCodeObjectFromJSDispatchTable(
20422042
TNode<UintPtrT> shifted_value;
20432043
if (JSDispatchEntry::kObjectPointerOffset == 0) {
20442044
shifted_value =
2045+
#if defined(__illumos__) && defined(V8_HOST_ARCH_64_BIT)
2046+
// Pointers in illumos span both the low 2^47 range and the high 2^47 range
2047+
// as well. Checking the high bit being set in illumos means all higher bits
2048+
// need to be set to 1 after shifting right.
2049+
// Use WordSar() so any high-bit check wouldn't be necessary.
2050+
UncheckedCast<UintPtrT>(WordSar(UncheckedCast<IntPtrT>(value),
2051+
IntPtrConstant(JSDispatchEntry::kObjectPointerShift)));
2052+
#else
20452053
WordShr(value, UintPtrConstant(JSDispatchEntry::kObjectPointerShift));
2054+
#endif /* __illumos__ and 64-bit */
20462055
} else {
20472056
shifted_value = UintPtrAdd(
20482057
WordShr(value, UintPtrConstant(JSDispatchEntry::kObjectPointerShift)),

deps/v8/src/sandbox/js-dispatch-table-inl.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ void JSDispatchEntry::MakeJSDispatchEntry(Address object, Address entrypoint,
2424
uint16_t parameter_count,
2525
bool mark_as_alive) {
2626
DCHECK_EQ(object & kHeapObjectTag, 0);
27+
#if !defined(__illumos__) || !defined(V8_TARGET_ARCH_64_BIT)
2728
DCHECK_EQ((((object - kObjectPointerOffset) << kObjectPointerShift) >>
2829
kObjectPointerShift) +
2930
kObjectPointerOffset,
3031
object);
3132
DCHECK_EQ((object - kObjectPointerOffset) + kObjectPointerOffset, object);
3233
DCHECK_LT((object - kObjectPointerOffset),
3334
1ULL << ((sizeof(encoded_word_) * 8) - kObjectPointerShift));
35+
#endif /* __illumos__ & 64-bit */
3436

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

6373
Tagged<Code> JSDispatchEntry::GetCode() const {
@@ -219,7 +229,12 @@ void JSDispatchEntry::MakeFreelistEntry(uint32_t next_entry_index) {
219229
bool JSDispatchEntry::IsFreelistEntry() const {
220230
#ifdef V8_TARGET_ARCH_64_BIT
221231
auto entrypoint = entrypoint_.load(std::memory_order_relaxed);
232+
#ifdef __illumos__
233+
// See the illumos definition of kFreeEntryTag for why we have to do this.
234+
return (entrypoint & 0xffff000000000000ull) == kFreeEntryTag;
235+
#else
222236
return (entrypoint & kFreeEntryTag) == kFreeEntryTag;
237+
#endif /* __illumos__ */
223238
#else
224239
return next_free_entry_.load(std::memory_order_relaxed) != 0;
225240
#endif

deps/v8/src/sandbox/js-dispatch-table.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,22 @@ struct JSDispatchEntry {
8989
#if defined(V8_TARGET_ARCH_64_BIT)
9090
// Freelist entries contain the index of the next free entry in their lower 32
9191
// bits and are tagged with this tag.
92+
#ifdef __illumos__
93+
// In illumos 64-bit apps, pointers are allocated both the bottom 2^47 range
94+
// AND the top 2^47 range in the 64-bit space. Instead of 47 bits of VA space
95+
// we have 48 bits. This means, however, the top 16-bits may be 0xffff. We
96+
// therefore pick a different value for the kFreeEntryTag. If/when we go to
97+
// VA57, aka 5-level paging, we'll need to revisit this again, as will node
98+
// by default, since the fixed-bits on the high end will shrink from top
99+
// 16-bits to top 8-bits.
100+
//
101+
// Unless illumos ships an Oracle-Solaris-like VA47 link-time options to
102+
// restrict pointers from allocating from above the Virtual Address hole,
103+
// we need to be mindful of this.
104+
static constexpr Address kFreeEntryTag = 0xfeed000000000000ull;
105+
#else
92106
static constexpr Address kFreeEntryTag = 0xffff000000000000ull;
107+
#endif /* __illumos__ */
93108
#ifdef V8_TARGET_BIG_ENDIAN
94109
// 2-byte parameter count is on the least significant side of encoded_word_.
95110
static constexpr int kBigEndianParamCountOffset =

0 commit comments

Comments
 (0)