tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 3c5ab0e82dccef9f3ccb8f726ab514ce5181c4a6
parent 6e9c5451caf2a02acd98cbe935e729246535f0f0
Author: André Bargull <andre.bargull@gmail.com>
Date:   Thu, 23 Oct 2025 12:23:34 +0000

Bug 1995707 - Part 1: Use at-start for fallible ALU operations except LMulI on arm32/arm64. r=spidermonkey-reviewers,jandem

Differential Revision: https://phabricator.services.mozilla.com/D269551

Diffstat:
Mjs/src/jit/arm/Lowering-arm.cpp | 25+++++++++++++++++--------
Mjs/src/jit/arm64/CodeGenerator-arm64.cpp | 1-
Mjs/src/jit/arm64/Lowering-arm64.cpp | 23+++++++++++++++++------
3 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp @@ -162,8 +162,9 @@ void LIRGeneratorARM::lowerInt64PhiInput(MPhi* phi, uint32_t inputPosition, // x = !y void LIRGeneratorARM::lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input) { - ins->setOperand( - 0, ins->snapshot() ? useRegister(input) : useRegisterAtStart(input)); + // Unary ALU operations don't read the input after writing to the output, even + // for fallible operations, so we can use at-start allocations. + ins->setOperand(0, useRegisterAtStart(input)); define(ins, mir); } @@ -171,12 +172,10 @@ void LIRGeneratorARM::lowerForALU(LInstructionHelper<1, 1, 0>* ins, void LIRGeneratorARM::lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs) { - // Some operations depend on checking inputs after writing the result, e.g. - // MulI, but only for bail out paths so useAtStart when no bailouts. - ins->setOperand(0, - ins->snapshot() ? useRegister(lhs) : useRegisterAtStart(lhs)); - ins->setOperand(1, ins->snapshot() ? useRegisterOrConstant(rhs) - : useRegisterOrConstantAtStart(rhs)); + // Binary ALU operations don't read any input after writing to the output, + // even for fallible operations, so we can use at-start allocations. + ins->setOperand(0, useRegisterAtStart(lhs)); + ins->setOperand(1, useRegisterOrConstantAtStart(rhs)); define(ins, mir); } @@ -376,6 +375,16 @@ void LIRGeneratorARM::lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs) { if (mul->fallible()) { assignSnapshot(lir, mul->bailoutKind()); } + + // Negative zero check reads |lhs| and |rhs| after writing to the output, so + // we can't use at-start allocations. + if (mul->canBeNegativeZero() && !rhs->isConstant()) { + lir->setOperand(0, useRegister(lhs)); + lir->setOperand(1, useRegister(rhs)); + define(lir, mul); + return; + } + lowerForALU(lir, mul, lhs, rhs); } diff --git a/js/src/jit/arm64/CodeGenerator-arm64.cpp b/js/src/jit/arm64/CodeGenerator-arm64.cpp @@ -265,7 +265,6 @@ void CodeGenerator::visitMulI(LMulI* ins) { masm.mul32(lhsreg, scratch, destreg, onOverflow); if (onOverflow) { - MOZ_ASSERT(lhsreg != destreg); bailoutFrom(&bailout, ins->snapshot()); } return; diff --git a/js/src/jit/arm64/Lowering-arm64.cpp b/js/src/jit/arm64/Lowering-arm64.cpp @@ -101,8 +101,9 @@ void LIRGenerator::visitReturnImpl(MDefinition* opd, bool isGenerator) { // x = !y void LIRGeneratorARM64::lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input) { - ins->setOperand( - 0, ins->snapshot() ? useRegister(input) : useRegisterAtStart(input)); + // Unary ALU operations don't read the input after writing to the output, even + // for fallible operations, so we can use at-start allocations. + ins->setOperand(0, useRegisterAtStart(input)); define(ins, mir); } @@ -110,10 +111,10 @@ void LIRGeneratorARM64::lowerForALU(LInstructionHelper<1, 1, 0>* ins, void LIRGeneratorARM64::lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs) { - ins->setOperand(0, - ins->snapshot() ? useRegister(lhs) : useRegisterAtStart(lhs)); - ins->setOperand(1, ins->snapshot() ? useRegisterOrConstant(rhs) - : useRegisterOrConstantAtStart(rhs)); + // Binary ALU operations don't read any input after writing to the output, + // even for fallible operations, so we can use at-start allocations. + ins->setOperand(0, useRegisterAtStart(lhs)); + ins->setOperand(1, useRegisterOrConstantAtStart(rhs)); define(ins, mir); } @@ -264,6 +265,16 @@ void LIRGeneratorARM64::lowerMulI(MMul* mul, MDefinition* lhs, if (mul->fallible()) { assignSnapshot(lir, mul->bailoutKind()); } + + // Negative zero check reads |lhs| and |rhs| after writing to the output, so + // we can't use at-start allocations. + if (mul->canBeNegativeZero() && !rhs->isConstant()) { + lir->setOperand(0, useRegister(lhs)); + lir->setOperand(1, useRegister(rhs)); + define(lir, mul); + return; + } + lowerForALU(lir, mul, lhs, rhs); }