mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1718516 - Fix AddToHash of 64-bits numbers on 32-bits platforms. r=nika,anba
Differential Revision: https://phabricator.services.mozilla.com/D197302
This commit is contained in:
parent
4bb1a054be
commit
6e1293b5f7
@ -7639,18 +7639,7 @@ void MacroAssembler::prepareHashNonGCThing(ValueOperand value, Register result,
|
||||
move64(value.toRegister64(), r64);
|
||||
rshift64Arithmetic(Imm32(32), r64);
|
||||
#else
|
||||
// TODO: This seems like a bug in mozilla::detail::AddUintptrToHash().
|
||||
// The uint64_t input is first converted to uintptr_t and then back to
|
||||
// uint64_t. But |uint64_t(uintptr_t(bits))| actually only clears the high
|
||||
// bits, so this computation:
|
||||
//
|
||||
// aValue = uintptr_t(bits)
|
||||
// v2 = static_cast<uint32_t>(static_cast<uint64_t>(aValue) >> 32)
|
||||
//
|
||||
// really just sets |v2 = 0|. And that means the xor-operation in AddU32ToHash
|
||||
// can be optimized away, because |x ^ 0 = x|.
|
||||
//
|
||||
// Filed as bug 1718516.
|
||||
move32(value.typeReg(), temp);
|
||||
#endif
|
||||
|
||||
// mozilla::WrappingMultiply(kGoldenRatioU32, RotateLeft5(aHash) ^ aValue);
|
||||
@ -7660,9 +7649,7 @@ void MacroAssembler::prepareHashNonGCThing(ValueOperand value, Register result,
|
||||
// mozilla::WrappingMultiply(kGoldenRatioU32, RotateLeft5(aHash) ^ aValue);
|
||||
// with |aHash = <above hash>| and |aValue = v2|.
|
||||
rotateLeft(Imm32(5), result, result);
|
||||
#ifdef JS_PUNBOX64
|
||||
xor32(temp, result);
|
||||
#endif
|
||||
|
||||
// Combine |mul32| and |scrambleHashCode| by directly multiplying with
|
||||
// |kGoldenRatioU32 * kGoldenRatioU32|.
|
||||
|
@ -153,17 +153,20 @@ constexpr HashNumber AddU32ToHash(HashNumber aHash, uint32_t aValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* AddUintptrToHash takes sizeof(uintptr_t) as a template parameter.
|
||||
* AddUintNToHash takes sizeof(int_type) as a template parameter.
|
||||
* Changes to these functions need to be propagated to
|
||||
* MacroAssembler::prepareHashNonGCThing, which inlines them manually for
|
||||
* the JIT.
|
||||
*/
|
||||
template <size_t PtrSize>
|
||||
constexpr HashNumber AddUintptrToHash(HashNumber aHash, uintptr_t aValue) {
|
||||
template <size_t Size>
|
||||
constexpr HashNumber AddUintNToHash(HashNumber aHash, uint64_t aValue) {
|
||||
return AddU32ToHash(aHash, static_cast<uint32_t>(aValue));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline HashNumber AddUintptrToHash<8>(HashNumber aHash, uintptr_t aValue) {
|
||||
inline HashNumber AddUintNToHash<8>(HashNumber aHash, uint64_t aValue) {
|
||||
uint32_t v1 = static_cast<uint32_t>(aValue);
|
||||
uint32_t v2 = static_cast<uint32_t>(static_cast<uint64_t>(aValue) >> 32);
|
||||
uint32_t v2 = static_cast<uint32_t>(aValue >> 32);
|
||||
return AddU32ToHash(AddU32ToHash(aHash, v1), v2);
|
||||
}
|
||||
|
||||
@ -196,23 +199,23 @@ template <typename A>
|
||||
|
||||
static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!");
|
||||
|
||||
return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA));
|
||||
return detail::AddUintNToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA));
|
||||
}
|
||||
|
||||
// We use AddUintptrToHash() for hashing all integral types. 8-byte integral
|
||||
// We use AddUintNToHash() for hashing all integral types. 8-byte integral
|
||||
// types are treated the same as 64-bit pointers, and smaller integral types are
|
||||
// first implicitly converted to 32 bits and then passed to AddUintptrToHash()
|
||||
// first implicitly converted to 32 bits and then passed to AddUintNToHash()
|
||||
// to be hashed.
|
||||
template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
|
||||
[[nodiscard]] constexpr HashNumber AddToHash(HashNumber aHash, T aA) {
|
||||
return detail::AddUintptrToHash<sizeof(T)>(aHash, aA);
|
||||
return detail::AddUintNToHash<sizeof(T)>(aHash, aA);
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
|
||||
[[nodiscard]] constexpr HashNumber AddToHash(HashNumber aHash, T aA) {
|
||||
// Hash using AddUintptrToHash with the underlying type of the enum type
|
||||
// Hash using AddUintNToHash with the underlying type of the enum type
|
||||
using UnderlyingType = typename std::underlying_type<T>::type;
|
||||
return detail::AddUintptrToHash<sizeof(UnderlyingType)>(
|
||||
return detail::AddUintNToHash<sizeof(UnderlyingType)>(
|
||||
aHash, static_cast<UnderlyingType>(aA));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user