GeezerVison is showing github.com — build,test: test array index hash collision · nodejs/node@089d6c7
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: common.gypi +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 38 | 38 |
| 39 | 39 | # Reset this number to 0 on major V8 upgrades. | 40 | 40 | # Increment by one for each non-official patch applied to deps/v8. | 41 | | - 'v8_embedder_string': '-node.17', | | 41 | + 'v8_embedder_string': '-node.18', | 42 | 42 |
| 43 | 43 | ##### V8 defaults for Node.js ##### | 44 | 44 |
| |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/BUILD.bazel +7Lines changed: 7 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -240,6 +240,11 @@ v8_flag( | 240 | 240 | default = False, | 241 | 241 | ) | 242 | 242 |
| | 243 | +v8_flag( | | 244 | + name = "v8_enable_seeded_array_index_hash", | | 245 | + default = False, | | 246 | +) | | 247 | + | 243 | 248 | selects.config_setting_group( | 244 | 249 | name = "enable_drumbrake_x64", | 245 | 250 | match_all = [ | @@ -512,6 +517,7 @@ v8_config( | 512 | 517 | "v8_enable_webassembly": "V8_ENABLE_WEBASSEMBLY", | 513 | 518 | "v8_enable_drumbrake": "V8_ENABLE_DRUMBRAKE", | 514 | 519 | "v8_enable_drumbrake_tracing": "V8_ENABLE_DRUMBRAKE_TRACING", | | 520 | + "v8_enable_seeded_array_index_hash": "V8_ENABLE_SEEDED_ARRAY_INDEX_HASH", | 515 | 521 | "v8_jitless": "V8_JITLESS", | 516 | 522 | "v8_enable_vtunejit": "ENABLE_VTUNE_JIT_INTERFACE", | 517 | 523 | "v8_enable_undefined_double": "V8_ENABLE_UNDEFINED_DOUBLE", | @@ -2028,6 +2034,7 @@ filegroup( | 2028 | 2034 | "src/numbers/conversions.h", | 2029 | 2035 | "src/numbers/conversions-inl.h", | 2030 | 2036 | "src/numbers/hash-seed.h", | | 2037 | + "src/numbers/hash-seed.cc", | 2031 | 2038 | "src/numbers/hash-seed-inl.h", | 2032 | 2039 | "src/numbers/ieee754.cc", | 2033 | 2040 | "src/numbers/ieee754.h", | |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/BUILD.gn +7Lines changed: 7 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -499,6 +499,9 @@ declare_args() { | 499 | 499 | # Use a hard-coded secret value when hashing. | 500 | 500 | v8_use_default_hasher_secret = true | 501 | 501 |
| | 502 | + # Enable seeded array index hash. | | 503 | + v8_enable_seeded_array_index_hash = false | | 504 | + | 502 | 505 | # add instrumentation for Dumpling differential fuzzing | 503 | 506 | v8_dumpling = false | 504 | 507 |
| @@ -1241,6 +1244,9 @@ config("features") { | 1241 | 1244 | if (v8_enable_lite_mode) { | 1242 | 1245 | defines += [ "V8_LITE_MODE" ] | 1243 | 1246 | } | | 1247 | + if (v8_enable_seeded_array_index_hash) { | | 1248 | + defines += [ "V8_ENABLE_SEEDED_ARRAY_INDEX_HASH" ] | | 1249 | + } | 1244 | 1250 | if (v8_enable_gdbjit) { | 1245 | 1251 | defines += [ "ENABLE_GDB_JIT_INTERFACE" ] | 1246 | 1252 | } | @@ -5981,6 +5987,7 @@ v8_source_set("v8_base_without_compiler") { | 5981 | 5987 | "src/logging/runtime-call-stats.cc", | 5982 | 5988 | "src/logging/tracing-flags.cc", | 5983 | 5989 | "src/numbers/conversions.cc", | | 5990 | + "src/numbers/hash-seed.cc", | 5984 | 5991 | "src/numbers/ieee754.cc", | 5985 | 5992 | "src/numbers/math-random.cc", | 5986 | 5993 | "src/objects/abstract-code.cc", | |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/DEPS +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -138,7 +138,7 @@ specific_include_rules = { | 138 | 138 | "heap\.cc": [ | 139 | 139 | "+third_party/rapidhash-v8/secret.h", | 140 | 140 | ], | 141 | | - "hash-seed-inl\.h": [ | | 141 | + "hash-seed\.cc": [ | 142 | 142 | "+third_party/rapidhash-v8/secret.h", | 143 | 143 | ], | 144 | 144 | } |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/ast/ast-value-factory.cc +2-1Lines changed: 2 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -83,7 +83,8 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const { | 83 | 83 | // can't be convertible to an array index. | 84 | 84 | if (!IsIntegerIndex()) return false; | 85 | 85 | if (length() <= Name::kMaxCachedArrayIndexLength) { | 86 | | - *index = Name::ArrayIndexValueBits::decode(raw_hash_field_); | | 86 | + *index = StringHasher::DecodeArrayIndexFromHashField( | | 87 | + raw_hash_field_, HashSeed(GetReadOnlyRoots())); | 87 | 88 | return true; | 88 | 89 | } | 89 | 90 | // Might be an index, but too big to cache it. Do the slow conversion. This | |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/builtins/number.tq +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -300,7 +300,7 @@ transitioning javascript builtin NumberParseFloat( | 300 | 300 | const hash: NameHash = s.raw_hash_field; | 301 | 301 | if (IsIntegerIndex(hash) && | 302 | 302 | hash.array_index_length < kMaxCachedArrayIndexLength) { | 303 | | - const arrayIndex: uint32 = hash.array_index_value; | | 303 | + const arrayIndex: uint32 = DecodeArrayIndexFromHashField(hash); | 304 | 304 | return SmiFromUint32(arrayIndex); | 305 | 305 | } | 306 | 306 | // Fall back to the runtime to convert string to a number. | @@ -351,7 +351,7 @@ transitioning builtin ParseInt( | 351 | 351 | const hash: NameHash = s.raw_hash_field; | 352 | 352 | if (IsIntegerIndex(hash) && | 353 | 353 | hash.array_index_length < kMaxCachedArrayIndexLength) { | 354 | | - const arrayIndex: uint32 = hash.array_index_value; | | 354 | + const arrayIndex: uint32 = DecodeArrayIndexFromHashField(hash); | 355 | 355 | return SmiFromUint32(arrayIndex); | 356 | 356 | } | 357 | 357 | // Fall back to the runtime. | |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/builtins/wasm.tq +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1611,8 +1611,8 @@ builtin WasmStringToDouble(s: String): float64 { | 1611 | 1611 | const hash: NameHash = s.raw_hash_field; | 1612 | 1612 | if (IsIntegerIndex(hash) && | 1613 | 1613 | hash.array_index_length < kMaxCachedArrayIndexLength) { | 1614 | | - const arrayIndex: int32 = Signed(hash.array_index_value); | 1615 | | - return Convert<float64>(arrayIndex); | | 1614 | + const arrayIndex: uint32 = DecodeArrayIndexFromHashField(hash); | | 1615 | + return Convert<float64>(Signed(arrayIndex)); | 1616 | 1616 | } | 1617 | 1617 | return StringToFloat64(Flatten(s)); | 1618 | 1618 | } | |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/codegen/code-stub-assembler.cc +63-5Lines changed: 63 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2711,6 +2711,66 @@ TNode<Uint32T> CodeStubAssembler::LoadJSReceiverIdentityHash( | 2711 | 2711 | return var_hash.value(); | 2712 | 2712 | } | 2713 | 2713 |
| | 2714 | +#ifdef V8_ENABLE_SEEDED_ARRAY_INDEX_HASH | | 2715 | +// Mirror C++ StringHasher::SeedArrayIndexValue. | | 2716 | +TNode<Uint32T> CodeStubAssembler::SeedArrayIndexValue(TNode<Uint32T> value) { | | 2717 | + // Load m1, m2 and m3 from the hash seed byte array. In the compiled code | | 2718 | + // these will always come from the read-only roots. | | 2719 | + TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed)); | | 2720 | + intptr_t base_offset = OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag; | | 2721 | + TNode<Uint32T> m1 = Load<Uint32T>( | | 2722 | + hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1Offset)); | | 2723 | + TNode<Uint32T> m2 = Load<Uint32T>( | | 2724 | + hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2Offset)); | | 2725 | + TNode<Uint32T> m3 = Load<Uint32T>( | | 2726 | + hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3Offset)); | | 2727 | + | | 2728 | + TNode<Word32T> x = value; | | 2729 | + // 3-round xorshift-multiply. | | 2730 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2731 | + x = Word32And(Uint32Mul(Unsigned(x), m1), | | 2732 | + Uint32Constant(Name::kArrayIndexValueMask)); | | 2733 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2734 | + x = Word32And(Uint32Mul(Unsigned(x), m2), | | 2735 | + Uint32Constant(Name::kArrayIndexValueMask)); | | 2736 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2737 | + x = Word32And(Uint32Mul(Unsigned(x), m3), | | 2738 | + Uint32Constant(Name::kArrayIndexValueMask)); | | 2739 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2740 | + | | 2741 | + return Unsigned(x); | | 2742 | +} | | 2743 | + | | 2744 | +// Mirror C++ StringHasher::UnseedArrayIndexValue. | | 2745 | +TNode<Uint32T> CodeStubAssembler::UnseedArrayIndexValue(TNode<Uint32T> value) { | | 2746 | + // Load m1_inv, m2_inv and m3_inv from the hash seed byte array. In the | | 2747 | + // compiled code these will always come from the read-only roots. | | 2748 | + TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed)); | | 2749 | + intptr_t base_offset = OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag; | | 2750 | + TNode<Uint32T> m1_inv = Load<Uint32T>( | | 2751 | + hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1InvOffset)); | | 2752 | + TNode<Uint32T> m2_inv = Load<Uint32T>( | | 2753 | + hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2InvOffset)); | | 2754 | + TNode<Uint32T> m3_inv = Load<Uint32T>( | | 2755 | + hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3InvOffset)); | | 2756 | + | | 2757 | + TNode<Word32T> x = value; | | 2758 | + // 3-round xorshift-multiply (inverse). | | 2759 | + // Xorshift is an involution when kShift is at least half of the value width. | | 2760 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2761 | + x = Word32And(Uint32Mul(Unsigned(x), m3_inv), | | 2762 | + Uint32Constant(Name::kArrayIndexValueMask)); | | 2763 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2764 | + x = Word32And(Uint32Mul(Unsigned(x), m2_inv), | | 2765 | + Uint32Constant(Name::kArrayIndexValueMask)); | | 2766 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2767 | + x = Word32And(Uint32Mul(Unsigned(x), m1_inv), | | 2768 | + Uint32Constant(Name::kArrayIndexValueMask)); | | 2769 | + x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift))); | | 2770 | + return Unsigned(x); | | 2771 | +} | | 2772 | +#endif // V8_ENABLE_SEEDED_ARRAY_INDEX_HASH | | 2773 | + | 2714 | 2774 | TNode<Uint32T> CodeStubAssembler::LoadNameHashAssumeComputed(TNode<Name> name) { | 2715 | 2775 | TNode<Uint32T> hash_field = LoadNameRawHash(name); | 2716 | 2776 | CSA_DCHECK(this, IsClearWord32(hash_field, Name::kHashNotComputedMask)); | @@ -9404,8 +9464,7 @@ TNode<Number> CodeStubAssembler::StringToNumber(TNode<String> input) { | 9404 | 9464 | GotoIf(IsSetWord32(raw_hash_field, Name::kDoesNotContainCachedArrayIndexMask), | 9405 | 9465 | &runtime); | 9406 | 9466 |
| 9407 | | - var_result = SmiTag(Signed( | 9408 | | - DecodeWordFromWord32<String::ArrayIndexValueBits>(raw_hash_field))); | | 9467 | + var_result = SmiFromUint32(DecodeArrayIndexFromHashField(raw_hash_field)); | 9409 | 9468 | Goto(&end); | 9410 | 9469 |
| 9411 | 9470 | BIND(&runtime); | @@ -10535,9 +10594,8 @@ void CodeStubAssembler::TryToName(TNode<Object> key, Label* if_keyisindex, | 10535 | 10594 |
| 10536 | 10595 | BIND(&if_has_cached_index); | 10537 | 10596 | { | 10538 | | - TNode<IntPtrT> index = | 10539 | | - Signed(DecodeWordFromWord32<String::ArrayIndexValueBits>( | 10540 | | - raw_hash_field)); | | 10597 | + TNode<IntPtrT> index = Signed(ChangeUint32ToWord( | | 10598 | + DecodeArrayIndexFromHashField(raw_hash_field))); | 10541 | 10599 | CSA_DCHECK(this, IntPtrLessThan(index, IntPtrConstant(INT_MAX))); | 10542 | 10600 | *var_index = index; | 10543 | 10601 | Goto(if_keyisindex); | |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/codegen/code-stub-assembler.h +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -4835,6 +4835,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler | 4835 | 4835 | return WordEqual(WordAnd(flags, IntPtrConstant(mask)), IntPtrConstant(0)); | 4836 | 4836 | } | 4837 | 4837 |
| | 4838 | +#ifdef V8_ENABLE_SEEDED_ARRAY_INDEX_HASH | | 4839 | + // Mirror C++ StringHasher::SeedArrayIndexValue and UnseedArrayIndexValue. | | 4840 | + TNode<Uint32T> SeedArrayIndexValue(TNode<Uint32T> value); | | 4841 | + TNode<Uint32T> UnseedArrayIndexValue(TNode<Uint32T> value); | | 4842 | +#endif // V8_ENABLE_SEEDED_ARRAY_INDEX_HASH | | 4843 | + | 4838 | 4844 | private: | 4839 | 4845 | friend class CodeStubArguments; | 4840 | 4846 |
| |
Collapse file Copy file name to clipboardExpand all lines: deps/v8/src/heap/factory-base.cc +8-7Lines changed: 8 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -299,9 +299,9 @@ Handle<ProtectedWeakFixedArray> FactoryBase<Impl>::NewProtectedWeakFixedArray( | 299 | 299 | } | 300 | 300 |
| 301 | 301 | template <typename Impl> | 302 | | -Handle<ByteArray> FactoryBase<Impl>::NewByteArray(int length, | 303 | | - AllocationType allocation) { | 304 | | - return ByteArray::New(isolate(), length, allocation); | | 302 | +Handle<ByteArray> FactoryBase<Impl>::NewByteArray( | | 303 | + int length, AllocationType allocation, AllocationAlignment alignment) { | | 304 | + return ByteArray::New(isolate(), length, allocation, alignment); | 305 | 305 | } | 306 | 306 |
| 307 | 307 | template <typename Impl> | @@ -1173,7 +1173,8 @@ inline Handle<String> FactoryBase<Impl>::SmiToString(Tagged<Smi> number, | 1173 | 1173 | if (raw->raw_hash_field() == String::kEmptyHashField && | 1174 | 1174 | number.value() >= 0) { | 1175 | 1175 | uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash( | 1176 | | - static_cast<uint32_t>(number.value()), raw->length()); | | 1176 | + static_cast<uint32_t>(number.value()), raw->length(), | | 1177 | + HashSeed(read_only_roots())); | 1177 | 1178 | raw->set_raw_hash_field(raw_hash_field); | 1178 | 1179 | } | 1179 | 1180 | } | @@ -1333,9 +1334,9 @@ FactoryBase<Impl>::AllocateRawTwoByteInternalizedString( | 1333 | 1334 |
| 1334 | 1335 | template <typename Impl> | 1335 | 1336 | Tagged<HeapObject> FactoryBase<Impl>::AllocateRawArray( | 1336 | | - int size, AllocationType allocation, AllocationHint hint) { | 1337 | | - Tagged<HeapObject> result = | 1338 | | - AllocateRaw(size, allocation, AllocationAlignment::kTaggedAligned, hint); | | 1337 | + int size, AllocationType allocation, AllocationHint hint, | | 1338 | + AllocationAlignment alignment) { | | 1339 | + Tagged<HeapObject> result = AllocateRaw(size, allocation, alignment, hint); | 1339 | 1340 | if ((size > | 1340 | 1341 | isolate()->heap()->AsHeap()->MaxRegularHeapObjectSize(allocation)) && | 1341 | 1342 | v8_flags.use_marking_progress_bar) { | |
|