Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
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.13',
'v8_embedder_string': '-node.16',

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

Expand Down
7 changes: 7 additions & 0 deletions deps/v8/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ v8_flag(
default = False,
)

v8_flag(
name = "v8_enable_seeded_array_index_hash",
default = False,
)

selects.config_setting_group(
name = "enable_drumbrake_x64",
match_all = [
Expand Down Expand Up @@ -505,6 +510,7 @@ v8_config(
"v8_enable_webassembly": "V8_ENABLE_WEBASSEMBLY",
"v8_enable_drumbrake": "V8_ENABLE_DRUMBRAKE",
"v8_enable_drumbrake_tracing": "V8_ENABLE_DRUMBRAKE_TRACING",
"v8_enable_seeded_array_index_hash": "V8_ENABLE_SEEDED_ARRAY_INDEX_HASH",
"v8_jitless": "V8_JITLESS",
"v8_enable_vtunejit": "ENABLE_VTUNE_JIT_INTERFACE",
},
Expand Down Expand Up @@ -1993,6 +1999,7 @@ filegroup(
"src/numbers/conversions.h",
"src/numbers/conversions-inl.h",
"src/numbers/hash-seed.h",
"src/numbers/hash-seed.cc",
"src/numbers/hash-seed-inl.h",
"src/numbers/ieee754.cc",
"src/numbers/ieee754.h",
Expand Down
7 changes: 7 additions & 0 deletions deps/v8/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ declare_args() {

# Use a hard-coded secret value when hashing.
v8_use_default_hasher_secret = true

# Enable seeded array index hash.
v8_enable_seeded_array_index_hash = false
}

# Derived defaults.
Expand Down Expand Up @@ -1200,6 +1203,9 @@ config("features") {
if (v8_enable_lite_mode) {
defines += [ "V8_LITE_MODE" ]
}
if (v8_enable_seeded_array_index_hash) {
defines += [ "V8_ENABLE_SEEDED_ARRAY_INDEX_HASH" ]
}
if (v8_enable_gdbjit) {
defines += [ "ENABLE_GDB_JIT_INTERFACE" ]
}
Expand Down Expand Up @@ -5778,6 +5784,7 @@ v8_source_set("v8_base_without_compiler") {
"src/logging/runtime-call-stats.cc",
"src/logging/tracing-flags.cc",
"src/numbers/conversions.cc",
"src/numbers/hash-seed.cc",
"src/numbers/ieee754.cc",
"src/numbers/math-random.cc",
"src/objects/abstract-code.cc",
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ specific_include_rules = {
"heap\.cc": [
"+third_party/rapidhash-v8/secret.h",
],
"hash-seed-inl\.h": [
"hash-seed\.cc": [
"+third_party/rapidhash-v8/secret.h",
],
}
3 changes: 2 additions & 1 deletion deps/v8/src/ast/ast-value-factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
// can't be convertible to an array index.
if (!IsIntegerIndex()) return false;
if (length() <= Name::kMaxCachedArrayIndexLength) {
*index = Name::ArrayIndexValueBits::decode(raw_hash_field_);
*index = StringHasher::DecodeArrayIndexFromHashField(
raw_hash_field_, HashSeed(GetReadOnlyRoots()));
return true;
}
// Might be an index, but too big to cache it. Do the slow conversion. This
Expand Down
4 changes: 2 additions & 2 deletions deps/v8/src/builtins/number.tq
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ transitioning javascript builtin NumberParseFloat(
const hash: NameHash = s.raw_hash_field;
if (IsIntegerIndex(hash) &&
hash.array_index_length < kMaxCachedArrayIndexLength) {
const arrayIndex: uint32 = hash.array_index_value;
const arrayIndex: uint32 = DecodeArrayIndexFromHashField(hash);
return SmiFromUint32(arrayIndex);
}
// Fall back to the runtime to convert string to a number.
Expand Down Expand Up @@ -351,7 +351,7 @@ transitioning builtin ParseInt(
const hash: NameHash = s.raw_hash_field;
if (IsIntegerIndex(hash) &&
hash.array_index_length < kMaxCachedArrayIndexLength) {
const arrayIndex: uint32 = hash.array_index_value;
const arrayIndex: uint32 = DecodeArrayIndexFromHashField(hash);
return SmiFromUint32(arrayIndex);
}
// Fall back to the runtime.
Expand Down
4 changes: 2 additions & 2 deletions deps/v8/src/builtins/wasm.tq
Original file line number Diff line number Diff line change
Expand Up @@ -1583,8 +1583,8 @@ builtin WasmStringToDouble(s: String): float64 {
const hash: NameHash = s.raw_hash_field;
if (IsIntegerIndex(hash) &&
hash.array_index_length < kMaxCachedArrayIndexLength) {
const arrayIndex: int32 = Signed(hash.array_index_value);
return Convert<float64>(arrayIndex);
const arrayIndex: uint32 = DecodeArrayIndexFromHashField(hash);
return Convert<float64>(Signed(arrayIndex));
}
return StringToFloat64(Flatten(s));
}
Expand Down
68 changes: 63 additions & 5 deletions deps/v8/src/codegen/code-stub-assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2682,6 +2682,66 @@ TNode<Uint32T> CodeStubAssembler::LoadJSReceiverIdentityHash(
return var_hash.value();
}

#ifdef V8_ENABLE_SEEDED_ARRAY_INDEX_HASH
// Mirror C++ StringHasher::SeedArrayIndexValue.
TNode<Uint32T> CodeStubAssembler::SeedArrayIndexValue(TNode<Uint32T> value) {
// Load m1, m2 and m3 from the hash seed byte array. In the compiled code
// these will always come from the read-only roots.
TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed));
intptr_t base_offset = OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag;
TNode<Uint32T> m1 = Load<Uint32T>(
hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1Offset));
TNode<Uint32T> m2 = Load<Uint32T>(
hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2Offset));
TNode<Uint32T> m3 = Load<Uint32T>(
hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3Offset));

TNode<Word32T> x = value;
// 3-round xorshift-multiply.
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
x = Word32And(Uint32Mul(Unsigned(x), m1),
Uint32Constant(Name::kArrayIndexValueMask));
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
x = Word32And(Uint32Mul(Unsigned(x), m2),
Uint32Constant(Name::kArrayIndexValueMask));
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
x = Word32And(Uint32Mul(Unsigned(x), m3),
Uint32Constant(Name::kArrayIndexValueMask));
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));

return Unsigned(x);
}

// Mirror C++ StringHasher::UnseedArrayIndexValue.
TNode<Uint32T> CodeStubAssembler::UnseedArrayIndexValue(TNode<Uint32T> value) {
// Load m1_inv, m2_inv and m3_inv from the hash seed byte array. In the
// compiled code these will always come from the read-only roots.
TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed));
intptr_t base_offset = OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag;
TNode<Uint32T> m1_inv = Load<Uint32T>(
hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1InvOffset));
TNode<Uint32T> m2_inv = Load<Uint32T>(
hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2InvOffset));
TNode<Uint32T> m3_inv = Load<Uint32T>(
hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3InvOffset));

TNode<Word32T> x = value;
// 3-round xorshift-multiply (inverse).
// Xorshift is an involution when kShift is at least half of the value width.
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
x = Word32And(Uint32Mul(Unsigned(x), m3_inv),
Uint32Constant(Name::kArrayIndexValueMask));
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
x = Word32And(Uint32Mul(Unsigned(x), m2_inv),
Uint32Constant(Name::kArrayIndexValueMask));
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
x = Word32And(Uint32Mul(Unsigned(x), m1_inv),
Uint32Constant(Name::kArrayIndexValueMask));
x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
return Unsigned(x);
}
#endif // V8_ENABLE_SEEDED_ARRAY_INDEX_HASH

TNode<Uint32T> CodeStubAssembler::LoadNameHashAssumeComputed(TNode<Name> name) {
TNode<Uint32T> hash_field = LoadNameRawHash(name);
CSA_DCHECK(this, IsClearWord32(hash_field, Name::kHashNotComputedMask));
Expand Down Expand Up @@ -9322,8 +9382,7 @@ TNode<Number> CodeStubAssembler::StringToNumber(TNode<String> input) {
GotoIf(IsSetWord32(raw_hash_field, Name::kDoesNotContainCachedArrayIndexMask),
&runtime);

var_result = SmiTag(Signed(
DecodeWordFromWord32<String::ArrayIndexValueBits>(raw_hash_field)));
var_result = SmiFromUint32(DecodeArrayIndexFromHashField(raw_hash_field));
Goto(&end);

BIND(&runtime);
Expand Down Expand Up @@ -10413,9 +10472,8 @@ void CodeStubAssembler::TryToName(TNode<Object> key, Label* if_keyisindex,

BIND(&if_has_cached_index);
{
TNode<IntPtrT> index =
Signed(DecodeWordFromWord32<String::ArrayIndexValueBits>(
raw_hash_field));
TNode<IntPtrT> index = Signed(ChangeUint32ToWord(
DecodeArrayIndexFromHashField(raw_hash_field)));
CSA_DCHECK(this, IntPtrLessThan(index, IntPtrConstant(INT_MAX)));
*var_index = index;
Goto(if_keyisindex);
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/src/codegen/code-stub-assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4780,6 +4780,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return WordEqual(WordAnd(flags, IntPtrConstant(mask)), IntPtrConstant(0));
}

#ifdef V8_ENABLE_SEEDED_ARRAY_INDEX_HASH
// Mirror C++ StringHasher::SeedArrayIndexValue and UnseedArrayIndexValue.
TNode<Uint32T> SeedArrayIndexValue(TNode<Uint32T> value);
TNode<Uint32T> UnseedArrayIndexValue(TNode<Uint32T> value);
#endif // V8_ENABLE_SEEDED_ARRAY_INDEX_HASH

private:
friend class CodeStubArguments;

Expand Down
15 changes: 8 additions & 7 deletions deps/v8/src/heap/factory-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,9 @@ Handle<ProtectedWeakFixedArray> FactoryBase<Impl>::NewProtectedWeakFixedArray(
}

template <typename Impl>
Handle<ByteArray> FactoryBase<Impl>::NewByteArray(int length,
AllocationType allocation) {
return ByteArray::New(isolate(), length, allocation);
Handle<ByteArray> FactoryBase<Impl>::NewByteArray(
int length, AllocationType allocation, AllocationAlignment alignment) {
return ByteArray::New(isolate(), length, allocation, alignment);
}

template <typename Impl>
Expand Down Expand Up @@ -1175,7 +1175,8 @@ inline Handle<String> FactoryBase<Impl>::SmiToString(Tagged<Smi> number,
if (raw->raw_hash_field() == String::kEmptyHashField &&
number.value() >= 0) {
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
static_cast<uint32_t>(number.value()), raw->length());
static_cast<uint32_t>(number.value()), raw->length(),
HashSeed(read_only_roots()));
raw->set_raw_hash_field(raw_hash_field);
}
}
Expand Down Expand Up @@ -1335,9 +1336,9 @@ FactoryBase<Impl>::AllocateRawTwoByteInternalizedString(

template <typename Impl>
Tagged<HeapObject> FactoryBase<Impl>::AllocateRawArray(
int size, AllocationType allocation, AllocationHint hint) {
Tagged<HeapObject> result =
AllocateRaw(size, allocation, AllocationAlignment::kTaggedAligned, hint);
int size, AllocationType allocation, AllocationHint hint,
AllocationAlignment alignment) {
Tagged<HeapObject> result = AllocateRaw(size, allocation, alignment, hint);
if ((size >
isolate()->heap()->AsHeap()->MaxRegularHeapObjectSize(allocation)) &&
v8_flags.use_marking_progress_bar) {
Expand Down
9 changes: 6 additions & 3 deletions deps/v8/src/heap/factory-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {

// The function returns a pre-allocated empty byte array for length = 0.
Handle<ByteArray> NewByteArray(
int length, AllocationType allocation = AllocationType::kYoung);
int length, AllocationType allocation = AllocationType::kYoung,
AllocationAlignment alignment = kTaggedAligned);

// Allocates a trusted byte array in trusted space, initialized with zeros.
Handle<TrustedByteArray> NewTrustedByteArray(
Expand Down Expand Up @@ -413,8 +414,10 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
static constexpr int kNumberToStringBufferSize = 32;

// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
Tagged<HeapObject> AllocateRawArray(int size, AllocationType allocation,
AllocationHint hint = AllocationHint());
Tagged<HeapObject> AllocateRawArray(
int size, AllocationType allocation,
AllocationHint hint = AllocationHint(),
AllocationAlignment alignment = kTaggedAligned);
Tagged<HeapObject> AllocateRawFixedArray(int length,
AllocationType allocation);
Tagged<HeapObject> AllocateRawWeakArrayList(int length,
Expand Down
3 changes: 2 additions & 1 deletion deps/v8/src/heap/factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4054,7 +4054,8 @@ Handle<String> Factory::SizeToString(size_t value, bool check_cache) {
if (value <= JSArray::kMaxArrayIndex &&
raw->raw_hash_field() == String::kEmptyHashField) {
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
static_cast<uint32_t>(value), raw->length());
static_cast<uint32_t>(value), raw->length(),
HashSeed(read_only_roots()));
raw->set_raw_hash_field(raw_hash_field);
}
}
Expand Down
26 changes: 0 additions & 26 deletions deps/v8/src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@
#include "src/tracing/trace-event.h"
#include "src/utils/utils-inl.h"
#include "src/utils/utils.h"
#include "third_party/rapidhash-v8/secret.h"

#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-engine.h"
Expand Down Expand Up @@ -6264,31 +6263,6 @@ void Heap::SetUpSpaces() {
}
}

void Heap::InitializeHashSeed() {
DCHECK(!deserialization_complete_);
uint64_t new_hash_seed;
if (v8_flags.hash_seed == 0) {
int64_t rnd = isolate()->random_number_generator()->NextInt64();
new_hash_seed = static_cast<uint64_t>(rnd);
} else {
new_hash_seed = static_cast<uint64_t>(v8_flags.hash_seed);
}

Tagged<ByteArray> hash_seed = ReadOnlyRoots(this).hash_seed();

MemCopy(hash_seed->begin(), reinterpret_cast<uint8_t*>(&new_hash_seed),
kInt64Size);

#if V8_USE_DEFAULT_HASHER_SECRET
MemCopy(hash_seed->begin() + kInt64Size,
reinterpret_cast<const uint8_t*>(RAPIDHASH_DEFAULT_SECRET),
kInt64Size * 3);
#else
rapidhash_make_secret(new_hash_seed, reinterpret_cast<uint64_t*>(
hash_seed->begin() + kInt64Size));
#endif // V8_USE_DEFAULT_HASHER_SECRET
}

std::shared_ptr<v8::TaskRunner> Heap::GetForegroundTaskRunner(
TaskPriority priority) const {
return V8::GetCurrentPlatform()->GetForegroundTaskRunner(
Expand Down
3 changes: 0 additions & 3 deletions deps/v8/src/heap/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,6 @@ class Heap final {
// Prepares the heap, setting up for deserialization.
void InitializeMainThreadLocalHeap(LocalHeap* main_thread_local_heap);

// (Re-)Initialize hash seed from flag or RNG.
void InitializeHashSeed();

// Invoked once for the process from V8::Initialize.
static void InitializeOncePerProcess();

Expand Down
8 changes: 5 additions & 3 deletions deps/v8/src/heap/setup-heap-internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "src/init/heap-symbols.h"
#include "src/init/setup-isolate.h"
#include "src/interpreter/interpreter.h"
#include "src/numbers/hash-seed.h"
#include "src/objects/arguments.h"
#include "src/objects/call-site-info.h"
#include "src/objects/cell-inl.h"
Expand Down Expand Up @@ -931,9 +932,10 @@ bool Heap::CreateImportantReadOnlyObjects() {
// Hash seed for strings

Factory* factory = isolate()->factory();
set_hash_seed(
*factory->NewByteArray(kInt64Size * 4, AllocationType::kReadOnly));
InitializeHashSeed();
set_hash_seed(*factory->NewByteArray(HashSeed::kTotalSize,
AllocationType::kReadOnly,
AllocationAlignment::kDoubleAligned));
HashSeed::InitializeRoots(isolate());

// Important strings and symbols
for (const ConstantStringInit& entry : kImportantConstantStringTable) {
Expand Down
Loading
Loading