@@ -2395,43 +2395,53 @@ TNode<Uint32T> CodeStubAssembler::LoadJSReceiverIdentityHash(
23952395#ifdef V8_ENABLE_SEEDED_ARRAY_INDEX_HASH
23962396// Mirror C++ StringHasher::SeedArrayIndexValue.
23972397TNode<Uint32T> CodeStubAssembler::SeedArrayIndexValue(TNode<Uint32T> value) {
2398- // Load m1 and m2 from the hash seed byte array. In the compiled code
2398+ // Load m1, m2 and m3 from the hash seed byte array. In the compiled code
23992399 // these will always come from the read-only roots.
24002400 TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed));
24012401 intptr_t base_offset = ByteArray::kHeaderSize - kHeapObjectTag;
24022402 TNode<Uint32T> m1 = Load<Uint32T>(
24032403 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1Offset));
24042404 TNode<Uint32T> m2 = Load<Uint32T>(
24052405 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2Offset));
2406+ TNode<Uint32T> m3 = Load<Uint32T>(
2407+ hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3Offset));
24062408
24072409 TNode<Word32T> x = value;
2408- // 2 -round xorshift-multiply.
2410+ // 3 -round xorshift-multiply.
24092411 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
24102412 x = Word32And(Uint32Mul(Unsigned(x), m1),
24112413 Uint32Constant(Name::kArrayIndexValueMask));
24122414 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
24132415 x = Word32And(Uint32Mul(Unsigned(x), m2),
24142416 Uint32Constant(Name::kArrayIndexValueMask));
24152417 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
2418+ x = Word32And(Uint32Mul(Unsigned(x), m3),
2419+ Uint32Constant(Name::kArrayIndexValueMask));
2420+ x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
24162421
24172422 return Unsigned(x);
24182423}
24192424
24202425// Mirror C++ StringHasher::UnseedArrayIndexValue.
24212426TNode<Uint32T> CodeStubAssembler::UnseedArrayIndexValue(TNode<Uint32T> value) {
2422- // Load m1_inv and m2_inv from the hash seed byte array. In the compiled code
2423- // these will always come from the read-only roots.
2427+ // Load m1_inv, m2_inv and m3_inv from the hash seed byte array. In the
2428+ // compiled code these will always come from the read-only roots.
24242429 TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed));
24252430 intptr_t base_offset = ByteArray::kHeaderSize - kHeapObjectTag;
24262431 TNode<Uint32T> m1_inv = Load<Uint32T>(
24272432 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1InvOffset));
24282433 TNode<Uint32T> m2_inv = Load<Uint32T>(
24292434 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2InvOffset));
2435+ TNode<Uint32T> m3_inv = Load<Uint32T>(
2436+ hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3InvOffset));
24302437
24312438 TNode<Word32T> x = value;
2432- // 2 -round xorshift-multiply (inverse).
2439+ // 3 -round xorshift-multiply (inverse).
24332440 // Xorshift is an involution when kShift is at least half of the value width.
24342441 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
2442+ x = Word32And(Uint32Mul(Unsigned(x), m3_inv),
2443+ Uint32Constant(Name::kArrayIndexValueMask));
2444+ x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
24352445 x = Word32And(Uint32Mul(Unsigned(x), m2_inv),
24362446 Uint32Constant(Name::kArrayIndexValueMask));
24372447 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
0 commit comments