tor-browser

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

commit 67f6bf8eac641ac03c46b0caf25f95a05a1aea70
parent 30e7d973d80ca6ee2ac9d9fd2ff415865c76683e
Author: Ryan Hunt <rhunt@eqrion.net>
Date:   Thu, 18 Dec 2025 16:45:29 +0000

Bug 2002625 - Add documentation for ABI special registers. r=yury

This has needed better documentation for a long time.

Driveby fix for ARM64 to ArgRegMask to remove x8. Doesn't appear
to be used anywhere and so it should not be a functional change.

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

Diffstat:
Mjs/src/jit/arm/Assembler-arm.h | 20++++++++------------
Mjs/src/jit/arm64/Architecture-arm64.h | 2+-
Mjs/src/jit/arm64/Assembler-arm64.h | 22+++++++++-------------
Mjs/src/jit/loong64/Assembler-loong64.h | 18+++++++-----------
Mjs/src/jit/mips64/Assembler-mips64.h | 18+++++++-----------
Mjs/src/jit/riscv64/Register-riscv64.h | 18+++++++-----------
Mjs/src/jit/shared/Assembler-shared.h | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mjs/src/jit/x64/Assembler-x64.h | 20++++++++------------
Mjs/src/jit/x86/Assembler-x86.h | 18+++++++-----------
9 files changed, 149 insertions(+), 82 deletions(-)

diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h @@ -89,7 +89,6 @@ static constexpr Register IntArgReg0 = r0; static constexpr Register IntArgReg1 = r1; static constexpr Register IntArgReg2 = r2; static constexpr Register IntArgReg3 = r3; -static constexpr Register HeapReg = r10; static constexpr Register CallTempNonArgRegs[] = {r5, r6, r7, r8}; static const uint32_t NumCallTempNonArgRegs = std::size(CallTempNonArgRegs); @@ -166,32 +165,29 @@ class ABIArgGenerator : public ABIArgGeneratorShared { bool IsUnaligned(const wasm::MemoryAccessDesc& access); -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReg0 = r4; static constexpr Register ABINonArgReg1 = r5; static constexpr Register ABINonArgReg2 = r6; static constexpr Register ABINonArgReg3 = r7; -// This register may be volatile or nonvolatile. Avoid d15 which is the -// ScratchDoubleReg_. +// See "ABI special registers" in Assembler-shared.h for more information. +// Avoid d15 which is the ScratchDoubleReg_. static constexpr FloatRegister ABINonArgDoubleReg{FloatRegisters::d8, VFPRegister::Double}; -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0 = r4; static constexpr Register ABINonArgReturnReg1 = r5; static constexpr Register ABINonVolatileReg = r6; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnVolatileReg = lr; -// Instance pointer argument register for WebAssembly functions. This must not -// alias any other register used for passing function arguments or return -// values. Preserved by WebAssembly functions. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg = r9; +static constexpr Register HeapReg = r10; // Registers used for wasm table calls. These registers must be disjoint // from the ABI argument registers, InstanceReg and each other. diff --git a/js/src/jit/arm64/Architecture-arm64.h b/js/src/jit/arm64/Architecture-arm64.h @@ -180,7 +180,7 @@ class Registers { static const SetType ArgRegMask = (1 << Registers::x0) | (1 << Registers::x1) | (1 << Registers::x2) | (1 << Registers::x3) | (1 << Registers::x4) | (1 << Registers::x5) | - (1 << Registers::x6) | (1 << Registers::x7) | (1 << Registers::x8); + (1 << Registers::x6) | (1 << Registers::x7); static const SetType VolatileMask = (1 << Registers::x0) | (1 << Registers::x1) | (1 << Registers::x2) | diff --git a/js/src/jit/arm64/Assembler-arm64.h b/js/src/jit/arm64/Assembler-arm64.h @@ -358,7 +358,6 @@ static constexpr Register IntArgReg4{Registers::x4}; static constexpr Register IntArgReg5{Registers::x5}; static constexpr Register IntArgReg6{Registers::x6}; static constexpr Register IntArgReg7{Registers::x7}; -static constexpr Register HeapReg{Registers::x21}; // Define unsized Registers. #define DEFINE_UNSIZED_REGISTERS(N) \ @@ -680,32 +679,29 @@ class ABIArgGenerator : public ABIArgGeneratorShared { ABIArg current_; }; -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReg0 = r8; static constexpr Register ABINonArgReg1 = r9; static constexpr Register ABINonArgReg2 = r10; static constexpr Register ABINonArgReg3 = r11; -// This register may be volatile or nonvolatile. Avoid d31 which is the -// ScratchDoubleReg_. +// See "ABI special registers" in Assembler-shared.h for more information. +// Avoid d31 which is the ScratchDoubleReg_. static constexpr FloatRegister ABINonArgDoubleReg = {FloatRegisters::s16, FloatRegisters::Single}; -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0 = r8; static constexpr Register ABINonArgReturnReg1 = r9; static constexpr Register ABINonVolatileReg{Registers::x19}; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. -static constexpr Register ABINonArgReturnVolatileReg = lr; +// See "ABI special registers" in Assembler-shared.h for more information. +static constexpr Register ABINonArgReturnVolatileReg = r8; -// Instance pointer argument register for WebAssembly functions. This must not -// alias any other register used for passing function arguments or return -// values. Preserved by WebAssembly functions. Must be nonvolatile. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg{Registers::x23}; +static constexpr Register HeapReg{Registers::x21}; // Registers used for wasm table calls. These registers must be disjoint // from the ABI argument registers, InstanceReg and each other. diff --git a/js/src/jit/loong64/Assembler-loong64.h b/js/src/jit/loong64/Assembler-loong64.h @@ -162,7 +162,6 @@ static constexpr Register IntArgReg4 = a4; static constexpr Register IntArgReg5 = a5; static constexpr Register IntArgReg6 = a6; static constexpr Register IntArgReg7 = a7; -static constexpr Register HeapReg = s7; // Registers used by RegExpMatcher and RegExpExecMatch stubs (do not use // JSReturnOperand). @@ -184,32 +183,29 @@ static constexpr Register JSReturnReg_Data = a2; static constexpr Register JSReturnReg = a2; static constexpr ValueOperand JSReturnOperand = ValueOperand(JSReturnReg); -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReg0 = t0; static constexpr Register ABINonArgReg1 = t1; static constexpr Register ABINonArgReg2 = t2; static constexpr Register ABINonArgReg3 = t3; -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0 = t0; static constexpr Register ABINonArgReturnReg1 = t1; static constexpr Register ABINonVolatileReg = s0; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnVolatileReg = ra; -// This register may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. // Avoid f23 which is the scratch register. static constexpr FloatRegister ABINonArgDoubleReg{FloatRegisters::f21, FloatRegisters::Double}; -// Instance pointer argument register for WebAssembly functions. This must not -// alias any other register used for passing function arguments or return -// values. Preserved by WebAssembly functions. Must be nonvolatile. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg = s4; +static constexpr Register HeapReg = s7; // Registers used for wasm table calls. These registers must be disjoint // from the ABI argument registers, InstanceReg and each other. diff --git a/js/src/jit/mips64/Assembler-mips64.h b/js/src/jit/mips64/Assembler-mips64.h @@ -32,31 +32,27 @@ class ABIArgGenerator : public ABIArgGeneratorShared { ABIArg& current() { return current_; } }; -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReg0 = t4; static constexpr Register ABINonArgReg1 = t5; static constexpr Register ABINonArgReg2 = t6; static constexpr Register ABINonArgReg3 = t7; -// This register may be volatile or nonvolatile. Avoid f23 which is the -// ScratchDoubleReg. +// See "ABI special registers" in Assembler-shared.h for more information. +// Avoid f23 which is the ScratchDoubleReg. static constexpr FloatRegister ABINonArgDoubleReg{FloatRegisters::f21, FloatRegisters::Double}; -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0 = t4; static constexpr Register ABINonArgReturnReg1 = t5; static constexpr Register ABINonVolatileReg = s0; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnVolatileReg = t4; -// TLS pointer argument register for WebAssembly functions. This must not alias -// any other register used for passing function arguments or return values. -// Preserved by WebAssembly functions. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg = s5; // Registers used for wasm table calls. These registers must be disjoint diff --git a/js/src/jit/riscv64/Register-riscv64.h b/js/src/jit/riscv64/Register-riscv64.h @@ -127,7 +127,6 @@ static constexpr Register IntArgReg4{Registers::a4}; static constexpr Register IntArgReg5{Registers::a5}; static constexpr Register IntArgReg6{Registers::a6}; static constexpr Register IntArgReg7{Registers::a7}; -static constexpr Register HeapReg{Registers::s7}; // Registers used by RegExpMatcher and RegExpExecMatch stubs (do not use // JSReturnOperand). @@ -149,24 +148,21 @@ static constexpr Register JSReturnReg_Data{Registers::s2}; static constexpr Register JSReturnReg{Registers::a2}; static constexpr ValueOperand JSReturnOperand = ValueOperand(JSReturnReg); -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReg0{Registers::t0}; static constexpr Register ABINonArgReg1{Registers::t1}; static constexpr Register ABINonArgReg2{Registers::t2}; static constexpr Register ABINonArgReg3{Registers::t3}; -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0{Registers::t0}; static constexpr Register ABINonArgReturnReg1{Registers::t1}; static constexpr Register ABINonVolatileReg{Registers::s1}; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnVolatileReg{Registers::t0}; -// This register may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. // Avoid ft11 which is the scratch register. static constexpr FloatRegister ABINonArgDoubleReg{FloatRegisters::ft11}; @@ -175,10 +171,10 @@ static constexpr Register WasmTableCallScratchReg1{ABINonArgReg1}; static constexpr Register WasmTableCallSigReg{ABINonArgReg2}; static constexpr Register WasmTableCallIndexReg{ABINonArgReg3}; -// Instance pointer argument register for WebAssembly functions. This must not -// alias any other register used for passing function arguments or return -// values. Preserved by WebAssembly functions. Must be nonvolatile. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg{Registers::s4}; +static constexpr Register HeapReg{Registers::s7}; static constexpr Register WasmJitEntryReturnScratch{Registers::t1}; diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h @@ -797,6 +797,101 @@ class ABIArgGeneratorShared { uint32_t stackBytesConsumedSoFar() const { return stackOffset_; } }; +// [SMDOC] ABI special registers +// +// There are a number of special registers that can be used for different +// purposes during "ABI calls". These are defined per-architecture in their +// Assembler-XYZ.h header. The documentation for them is centralized here to +// keep them all in-sync. +// +// The WebAssembly and System ABI's are similar but distinct, and so some of +// these can be used in both contexts and others only in one. This is +// unfortunate and should be formalized better. See "The WASM ABIs" in +// WasmFrame.h for documentation on the Wasm ABI. +// +// The relevant similarities/differences for ABI registers are that: +// 1. Wasm functions have special InstanceReg/HeapReg registers. +// 2. Wasm functions do not have non-volatile registers. +// 3. Wasm and System ABI have the same integer argument and return registers. +// 4. Wasm and System ABI may have different FP argument and return registers. +// (notably ARM32 softfp and x87 FP are different). +// +// TODO: understand and describe the relationship with the various +// MacroAssembler scratch registers. It looks like all of these must be +// distinct from the MacroAssembler scratch registers. +// +// # InstanceReg +// +// Instance pointer argument register for WebAssembly functions in the +// WebAssembly ABI. +// +// This must not alias any other register used for passing function arguments +// or return values. Preserved by WebAssembly functions. +// +// The register must be non-volatile in the system ABI, as some code relies on +// this to avoid reloading the register. +// +// See "The WASM ABIs" in WasmFrame.h for more information. +// +// # HeapReg +// +// Pointer to the base of (memory 0) for WebAssembly functions in the +// WebAssembly ABI. +// +// This must not alias any other register used for passing function arguments +// or return values. Preserved by WebAssembly functions. +// +// The register must be non-volatile in the system ABI, as some code relies on +// this to avoid reloading the register. +// +// This register is not available on all architectures. It is notably absent +// from x86. +// +// See "The WASM ABIs" in WasmFrame.h for more information. +// +// # ABINonArgReg (4 available) +// +// A register that can be clobbered in the prologue of a function. +// +// They are each distinct and have the following guarantees: +// - Will not be a System/Wasm ABI argument register. +// - Will not be the InstanceReg or HeapReg. +// - Could be a System/Wasm ABI result register. +// - Could be a System ABI non-volatile register. +// +// # ABINonArgDoubleReg (1 available) +// +// A floating-point register that can be clobbered in the prologue of a +// function. May be volatile or non-volatile. +// +// # ABINonArgReturnReg (2 available) +// +// A register that can be clobbered in the prologue or epilogue of a function. +// +// They are each distinct and have the following guarantees: +// - All the guarantees of ABINonArgReg. +// - Will not be a System/Wasm ABI return register. +// - Will be distinct from ABINonVolatileReg (see below). +// +// There are only two of these, and the constraint is x86. +// +// # ABINonVolatileReg (1 available) +// +// A register that is: +// - Non-volatile in the System ABI +// - (implied by above) Not an argument or return register. +// - Distinct from the ABINonArgReturnReg. +// +// # ABINonArgReturnVolatileReg (1 available) +// +// A register that can be clobbered in the prologue or epilogue of a system ABI +// function. +// +// They are each distinct and have the following guarantees: +// - All the guarantees of ABINonArgReturnReg. +// - Will be a volatile register in the System ABI. +// + } // namespace jit } // namespace js diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h @@ -97,7 +97,6 @@ struct ScratchRegisterScope : public AutoRegisterScope { }; static constexpr Register ReturnReg = rax; -static constexpr Register HeapReg = r15; static constexpr Register64 ReturnReg64(rax); static constexpr FloatRegister ReturnFloat32Reg = FloatRegister(X86Encoding::xmm0, FloatRegisters::Single); @@ -196,33 +195,30 @@ class ABIArgGenerator : public ABIArgGeneratorShared { ABIArg& current() { return current_; } }; -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. // Avoid r11, which is the MacroAssembler's ScratchReg. static constexpr Register ABINonArgReg0 = rax; static constexpr Register ABINonArgReg1 = rbx; static constexpr Register ABINonArgReg2 = r10; static constexpr Register ABINonArgReg3 = r12; -// This register may be volatile or nonvolatile. Avoid xmm15 which is the -// ScratchDoubleReg. +// See "ABI special registers" in Assembler-shared.h for more information. +// Avoid xmm15 which is the ScratchDoubleReg. static constexpr FloatRegister ABINonArgDoubleReg = FloatRegister(X86Encoding::xmm8, FloatRegisters::Double); -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0 = r10; static constexpr Register ABINonArgReturnReg1 = r12; static constexpr Register ABINonVolatileReg = r13; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnVolatileReg = r10; -// Instance pointer argument register for WebAssembly functions. This must not -// alias any other register used for passing function arguments or return -// values. Preserved by WebAssembly functions. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg = r14; +static constexpr Register HeapReg = r15; // Registers used for asm.js/wasm table calls. These registers must be disjoint // from the ABI argument registers, InstanceReg and each other. diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h @@ -100,31 +100,27 @@ class ABIArgGenerator : public ABIArgGeneratorShared { ABIArg& current() { return current_; } }; -// These registers may be volatile or nonvolatile. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReg0 = eax; static constexpr Register ABINonArgReg1 = ebx; static constexpr Register ABINonArgReg2 = ecx; static constexpr Register ABINonArgReg3 = edx; -// This register may be volatile or nonvolatile. Avoid xmm7 which is the -// ScratchDoubleReg_. +// See "ABI special registers" in Assembler-shared.h for more information. +// Avoid xmm7 which is the ScratchDoubleReg_. static constexpr FloatRegister ABINonArgDoubleReg = FloatRegister(X86Encoding::xmm0, FloatRegisters::Double); -// These registers may be volatile or nonvolatile. -// Note: these three registers are all guaranteed to be different +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnReg0 = ecx; static constexpr Register ABINonArgReturnReg1 = edi; static constexpr Register ABINonVolatileReg = ebx; -// This register is guaranteed to be clobberable during the prologue and -// epilogue of an ABI call which must preserve both ABI argument, return -// and non-volatile registers. +// See "ABI special registers" in Assembler-shared.h for more information. static constexpr Register ABINonArgReturnVolatileReg = ecx; -// Instance pointer argument register for WebAssembly functions. This must not -// alias any other register used for passing function arguments or return -// values. Preserved by WebAssembly functions. +// See "ABI special registers" in Assembler-shared.h, and "The WASM ABIs" in +// WasmFrame.h for more information. static constexpr Register InstanceReg = esi; // Registers used for asm.js/wasm table calls. These registers must be disjoint