commit 82a381ce25f5cd47ce64b0f80f63eae721be0271
parent 5c64bd0e8e22c7537babbb08d4678f3d9a6e4fa2
Author: Iain Ireland <iireland@mozilla.com>
Date: Wed, 10 Dec 2025 16:43:56 +0000
Bug 2002881: Support non-power-of-two EntrySize in lookupMFBT r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D274361
Diffstat:
8 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
@@ -10702,12 +10702,17 @@ void MacroAssembler::checkForMatchMFBT(Register hashTable, Register hashIndex,
addPtr(capacityOffset, entries);
// Load entries[hashIndex] into |scratch|
- // TODO: support non-power-of-2 entry sizes
- constexpr size_t EntrySize = sizeof(typename Table::Entry);
- static_assert(mozilla::IsPowerOfTwo(EntrySize));
- uint32_t shift = mozilla::FloorLog2(EntrySize);
- lshiftPtr(Imm32(shift), hashIndex, scratch);
-
+ size_t EntrySize = sizeof(typename Table::Entry);
+ if (mozilla::IsPowerOfTwo(EntrySize)) {
+ uint32_t shift = mozilla::FloorLog2(EntrySize);
+ lshiftPtr(Imm32(shift), hashIndex, scratch);
+ } else {
+ // Note: this is provided as a fallback. Faster paths are possible for many
+ // non-power-of-two constants. If you add a use of this code that requires a
+ // non-power-of-two EntrySize, consider extending this code.
+ move32(hashIndex, scratch);
+ mulPtr(ImmWord(EntrySize), scratch);
+ }
computeEffectiveAddress(BaseIndex(entries, scratch, Scale::TimesOne),
scratch);
}
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
@@ -1175,7 +1175,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
Register dest) PER_ARCH;
inline void mulPtr(Register rhs, Register srcDest) PER_ARCH;
- inline void mulPtr(ImmWord rhs, Register srcDest) DEFINED_ON(x86, x64);
+ inline void mulPtr(ImmWord rhs, Register srcDest) PER_ARCH;
inline void mul64(const Operand& src, const Register64& dest) DEFINED_ON(x64);
inline void mul64(const Operand& src, const Register64& dest,
diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h
@@ -483,6 +483,12 @@ void MacroAssembler::mulPtr(Register rhs, Register srcDest) {
as_mul(srcDest, srcDest, rhs);
}
+void MacroAssembler::mulPtr(ImmWord rhs, Register srcDest) {
+ ScratchRegisterScope scratch(*this);
+ movePtr(rhs, scratch);
+ mulPtr(scratch, srcDest);
+}
+
void MacroAssembler::mul64(Imm64 imm, const Register64& dest) {
// LOW32 = LOW(LOW(dest) * LOW(imm));
// HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits]
diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h
@@ -512,6 +512,14 @@ void MacroAssembler::mulPtr(Register rhs, Register srcDest) {
Mul(ARMRegister(srcDest, 64), ARMRegister(srcDest, 64), ARMRegister(rhs, 64));
}
+void MacroAssembler::mulPtr(ImmWord rhs, Register srcDest) {
+ vixl::UseScratchRegisterScope temps(this);
+ const ARMRegister scratch64 = temps.AcquireX();
+ MOZ_ASSERT(srcDest != scratch64.asUnsized());
+ mov(rhs, scratch64.asUnsized());
+ mulPtr(scratch64.asUnsized(), srcDest);
+}
+
void MacroAssembler::mul64(Imm64 imm, const Register64& dest) {
vixl::UseScratchRegisterScope temps(this);
const ARMRegister scratch64 = temps.AcquireX();
diff --git a/js/src/jit/loong64/MacroAssembler-loong64-inl.h b/js/src/jit/loong64/MacroAssembler-loong64-inl.h
@@ -466,6 +466,14 @@ void MacroAssembler::mulPtr(Register rhs, Register srcDest) {
as_mul_d(srcDest, srcDest, rhs);
}
+void MacroAssembler::mulPtr(ImmWord rhs, Register srcDest) {
+ UseScratchRegisterScope temps(asMasm());
+ Register scratch = temps.Acquire();
+ MOZ_ASSERT(srcDest != scratch);
+ mov(rhs, scratch);
+ mulPtr(scratch, srcDest);
+}
+
void MacroAssembler::mulBy3(Register src, Register dest) {
UseScratchRegisterScope temps(asMasm());
Register scratch = temps.Acquire();
diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h
@@ -241,6 +241,14 @@ void MacroAssembler::mulPtr(Register rhs, Register srcDest) {
#endif
}
+void MacroAssembler::mulPtr(ImmWord rhs, Register srcDest) {
+ UseScratchRegisterScope temps(*this);
+ Register scratch = temps.Acquire();
+ MOZ_ASSERT(srcDest != scratch);
+ mov(rhs, scratch);
+ mulPtr(scratch, srcDest);
+}
+
void MacroAssembler::mul64(Imm64 imm, const Register64& dest) {
UseScratchRegisterScope temps(*this);
Register scratch = temps.Acquire();
diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
@@ -1833,6 +1833,13 @@ void MacroAssembler::mulFloat32(FloatRegister src, FloatRegister dest) {
void MacroAssembler::mulPtr(Register rhs, Register srcDest) {
mul(srcDest, srcDest, rhs);
}
+void MacroAssembler::mulPtr(ImmWord rhs, Register srcDest) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ MOZ_ASSERT(srcDest != scratch);
+ mov(rhs, scratch);
+ mulPtr(scratch, srcDest);
+}
void MacroAssembler::negateDouble(FloatRegister reg) { fneg_d(reg, reg); }
diff --git a/js/src/jit/wasm32/MacroAssembler-wasm32-inl.h b/js/src/jit/wasm32/MacroAssembler-wasm32-inl.h
@@ -136,6 +136,7 @@ void MacroAssembler::sub64(Register64 src, Register64 dest) { MOZ_CRASH(); }
void MacroAssembler::sub64(Imm64 imm, Register64 dest) { MOZ_CRASH(); }
void MacroAssembler::mulPtr(Register rhs, Register srcDest) { MOZ_CRASH(); }
+void MacroAssembler::mulPtr(ImmWord rhs, Register srcDest) { MOZ_CRASH(); }
void MacroAssembler::mul64(Imm64 imm, const Register64& dest) { MOZ_CRASH(); }