@@ -2706,43 +2706,53 @@ TNode<Uint32T> CodeStubAssembler::LoadJSReceiverIdentityHash(
27062706#ifdef V8_ENABLE_SEEDED_ARRAY_INDEX_HASH
27072707// Mirror C++ StringHasher::SeedArrayIndexValue.
27082708TNode<Uint32T> CodeStubAssembler::SeedArrayIndexValue(TNode<Uint32T> value) {
2709- // Load m1 and m2 from the hash seed byte array. In the compiled code
2709+ // Load m1, m2 and m3 from the hash seed byte array. In the compiled code
27102710 // these will always come from the read-only roots.
27112711 TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed));
27122712 intptr_t base_offset = OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag;
27132713 TNode<Uint32T> m1 = Load<Uint32T>(
27142714 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1Offset));
27152715 TNode<Uint32T> m2 = Load<Uint32T>(
27162716 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2Offset));
2717+ TNode<Uint32T> m3 = Load<Uint32T>(
2718+ hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3Offset));
27172719
27182720 TNode<Word32T> x = value;
2719- // 2 -round xorshift-multiply.
2721+ // 3 -round xorshift-multiply.
27202722 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
27212723 x = Word32And(Uint32Mul(Unsigned(x), m1),
27222724 Uint32Constant(Name::kArrayIndexValueMask));
27232725 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
27242726 x = Word32And(Uint32Mul(Unsigned(x), m2),
27252727 Uint32Constant(Name::kArrayIndexValueMask));
27262728 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
2729+ x = Word32And(Uint32Mul(Unsigned(x), m3),
2730+ Uint32Constant(Name::kArrayIndexValueMask));
2731+ x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
27272732
27282733 return Unsigned(x);
27292734}
27302735
27312736// Mirror C++ StringHasher::UnseedArrayIndexValue.
27322737TNode<Uint32T> CodeStubAssembler::UnseedArrayIndexValue(TNode<Uint32T> value) {
2733- // Load m1_inv and m2_inv from the hash seed byte array. In the compiled code
2734- // these will always come from the read-only roots.
2738+ // Load m1_inv, m2_inv and m3_inv from the hash seed byte array. In the
2739+ // compiled code these will always come from the read-only roots.
27352740 TNode<ByteArray> hash_seed = CAST(LoadRoot(RootIndex::kHashSeed));
27362741 intptr_t base_offset = OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag;
27372742 TNode<Uint32T> m1_inv = Load<Uint32T>(
27382743 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM1InvOffset));
27392744 TNode<Uint32T> m2_inv = Load<Uint32T>(
27402745 hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM2InvOffset));
2746+ TNode<Uint32T> m3_inv = Load<Uint32T>(
2747+ hash_seed, IntPtrConstant(base_offset + HashSeed::kDerivedM3InvOffset));
27412748
27422749 TNode<Word32T> x = value;
2743- // 2 -round xorshift-multiply (inverse).
2750+ // 3 -round xorshift-multiply (inverse).
27442751 // Xorshift is an involution when kShift is at least half of the value width.
27452752 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
2753+ x = Word32And(Uint32Mul(Unsigned(x), m3_inv),
2754+ Uint32Constant(Name::kArrayIndexValueMask));
2755+ x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
27462756 x = Word32And(Uint32Mul(Unsigned(x), m2_inv),
27472757 Uint32Constant(Name::kArrayIndexValueMask));
27482758 x = Word32Xor(x, Word32Shr(x, Uint32Constant(Name::kArrayIndexHashShift)));
0 commit comments