commit c72f89659963348d9ae01aea95e2dbdc1e65098e
parent b8f574e58bd7f677851c8d2dba9b15ef5371c331
Author: Rong "Mantle" Bao <webmaster@csmantle.top>
Date: Wed, 15 Oct 2025 16:39:53 +0000
Bug 1984472 - Part 2: Mark LNewTypedArray[DynamicLength] as call instructions. r=spidermonkey-reviewers,jandem
This patch removes inline register saving and restoring code by marking
LNewTypedArray[DynamicLength] as call instructions.
Test cases
bench_1984472_dyn.js
```js
let rand = 0;
for (let i = 0; i < 100_000; i++) {
rand = ((rand * 114 + 514) ^ 0x0d000721) & 0x7fffffff;
const arr = new Uint32Array(rand % 4096);
arr[rand % (rand % 4096)] = rand * 1919810;
}
```
bench_1984472_sta.js
```js
let rand = 0;
for (let i = 0; i < 100_000; i++) {
rand = ((rand * 114 + 514) ^ 0x0d000721) & 0x7fffffff;
const arr = new Uint32Array(4096);
arr[rand % 4096] = rand * 1919810;
}
```
Codegen - LNewTypedArrayDynamicLength
Before (56 insns):
```plain-text
[Codegen] # LIR=NewTypedArrayDynamicLength
[Codegen] movabsq $0x7f665a22be30, %rdx
[Codegen] .set .Llabel316, .
[Codegen] movq 0x0(%rdx), %rsi
[Codegen] addq $64, %rsi
[Codegen] cmpq %rsi, 0x8(%rdx)
[Codegen] jb .Lfrom333
[Codegen] .set .Llabel333, .
[Codegen] movq %rsi, 0x0(%rdx)
[Codegen] subq $56, %rsi
[Codegen] movabsq $0x7f6658ffe918, %r11
[Codegen] movq %r11, -0x8(%rsi)
[Codegen] movabsq $0xfc635367940, %r11
[Codegen] movq %r11, 0x0(%rsi)
[Codegen] movabsq $0x55b42967d440, %r11
[Codegen] movq %r11, 0x8(%rsi)
[Codegen] movabsq $0x55b42967d410, %r11
[Codegen] movq %r11, 0x10(%rsi)
[Codegen] movabsq $0xfff9000000000000, %r11
[Codegen] movq %r11, 0x18(%rsi)
[Codegen] movl $0x72d, %r11d
[Codegen] movq %r11, 0x20(%rsi)
[Codegen] xorl %r11d, %r11d
[Codegen] movq %r11, 0x28(%rsi)
[Codegen] movabsq $0xfff9800000000000, %rdx
[Codegen] .set .Llabel436, .
[Codegen] movq %rdx, 0x30(%rsi)
[Codegen] xorl %eax, %eax
[Codegen] push %r10
[Codegen] push %r8
[Codegen] push %rdi
[Codegen] push %rsi
[Codegen] push %rdx
[Codegen] push %rcx
[Codegen] push %rax
[Codegen] subq $16, %rsp
[Codegen] .set .Llabel455, .
[Codegen] vmovsd %xmm1, 0x8(%rsp)
[Codegen] .set .Llabel461, .
[Codegen] vmovsd %xmm0, 0x0(%rsp)
[Codegen] movq %rsp, %rdx
[Codegen] andq $0xfffffffffffffff0, %rsp
[Codegen] push %rdx
[Codegen] movabsq $0x7f665a23b500, %rdx
[Codegen] subq $8, %rsp
[Codegen] movq %rax, %rcx
[Codegen] xchgq %rdi, %rdx
[Codegen] call .Lfrom499
[Codegen] addq $8, %rsp
[Codegen] pop %rsp
[Codegen] .set .Llabel504, .
[Codegen] vmovsd 0x8(%rsp), %xmm1
[Codegen] .set .Llabel510, .
[Codegen] vmovsd 0x0(%rsp), %xmm0
[Codegen] addq $16, %rsp
[Codegen] pop %rax
[Codegen] pop %rcx
[Codegen] pop %rdx
[Codegen] pop %rsi
[Codegen] pop %rdi
[Codegen] pop %r8
[Codegen] pop %r10
[Codegen] cmpl $0xfff98000, 0x34(%rsi)
[Codegen] je .Lfrom541
[Codegen] .set .Llabel541, .
[Codegen] .set .Llabel541, .
```
After (44 insns):
```plain-text
[Codegen] # LIR=NewTypedArrayDynamicLength
[Codegen] movabsq $0x7ff0c9c2be30, %rsi
[Codegen] .set .Llabel366, .
[Codegen] movq 0x0(%rsi), %rcx
[Codegen] addq $64, %rcx
[Codegen] cmpq %rcx, 0x8(%rsi)
[Codegen] jb .Lfrom383
[Codegen] .set .Llabel383, .
[Codegen] movq %rcx, 0x0(%rsi)
[Codegen] subq $56, %rcx
[Codegen] movabsq $0x7ff0c89fe918, %r11
[Codegen] movq %r11, -0x8(%rcx)
[Codegen] movabsq $0x35be51267940, %r11
[Codegen] movq %r11, 0x0(%rcx)
[Codegen] movabsq $0x560537bab440, %r11
[Codegen] movq %r11, 0x8(%rcx)
[Codegen] movabsq $0x560537bab410, %r11
[Codegen] movq %r11, 0x10(%rcx)
[Codegen] movabsq $0xfff9000000000000, %r11
[Codegen] movq %r11, 0x18(%rcx)
[Codegen] movl $0x72d, %r11d
[Codegen] movq %r11, 0x20(%rcx)
[Codegen] xorl %r11d, %r11d
[Codegen] movq %r11, 0x28(%rcx)
[Codegen] movabsq $0xfff9800000000000, %rsi
[Codegen] .set .Llabel486, .
[Codegen] movq %rsi, 0x30(%rcx)
[Codegen] xorl %edx, %edx
[Codegen] push %rcx
[Codegen] push %rdi
[Codegen] movq %rsp, %rsi
[Codegen] andq $0xfffffffffffffff0, %rsp
[Codegen] push %rsi
[Codegen] movabsq $0x7ff0c9c33c00, %rsi
[Codegen] subq $8, %rsp
[Codegen] push %rdx
[Codegen] movq %rdi, %rdx
[Codegen] movq %rsi, %rdi
[Codegen] movq %rcx, %rsi
[Codegen] pop %rcx
[Codegen] call .Lfrom532
[Codegen] addq $8, %rsp
[Codegen] pop %rsp
[Codegen] pop %rdi
[Codegen] pop %rcx
[Codegen] cmpl $0xfff98000, 0x34(%rcx)
[Codegen] je .Lfrom552
[Codegen] movq %rcx, %rax
[Codegen] .set .Llabel555, .
[Codegen] .set .Llabel555, .
```
Codegen - LNewTypedArray
Before (58 insns):
```plain-text
[Codegen] # LIR=NewTypedArray
[Codegen] movabsq $0x7f48b7a2be30, %r9
[Codegen] .set .Llabel308, .
[Codegen] movq 0x0(%r9), %rsi
[Codegen] addq $64, %rsi
[Codegen] cmpq %rsi, 0x8(%r9)
[Codegen] jb .Lfrom325
[Codegen] .set .Llabel325, .
[Codegen] movq %rsi, 0x0(%r9)
[Codegen] subq $56, %rsi
[Codegen] movabsq $0x7f48b67fe918, %r11
[Codegen] movq %r11, -0x8(%rsi)
[Codegen] movabsq $0x8987fc67940, %r11
[Codegen] movq %r11, 0x0(%rsi)
[Codegen] movabsq $0x563d1e72e440, %r11
[Codegen] movq %r11, 0x8(%rsi)
[Codegen] movabsq $0x563d1e72e410, %r11
[Codegen] movq %r11, 0x10(%rsi)
[Codegen] movabsq $0xfff9000000000000, %r11
[Codegen] movq %r11, 0x18(%rsi)
[Codegen] movl $0x1000, %r11d
[Codegen] movq %r11, 0x20(%rsi)
[Codegen] xorl %r11d, %r11d
[Codegen] movq %r11, 0x28(%rsi)
[Codegen] movabsq $0xfff9800000000000, %r9
[Codegen] .set .Llabel428, .
[Codegen] movq %r9, 0x30(%rsi)
[Codegen] movl $0x1000, %r8d
[Codegen] xorl %edi, %edi
[Codegen] push %r9
[Codegen] push %r8
[Codegen] push %rdi
[Codegen] push %rsi
[Codegen] push %rdx
[Codegen] push %rcx
[Codegen] push %rax
[Codegen] subq $16, %rsp
[Codegen] .set .Llabel453, .
[Codegen] vmovsd %xmm1, 0x8(%rsp)
[Codegen] .set .Llabel459, .
[Codegen] vmovsd %xmm0, 0x0(%rsp)
[Codegen] movq %rsp, %r9
[Codegen] andq $0xfffffffffffffff0, %rsp
[Codegen] push %r9
[Codegen] movabsq $0x7f48b7a33100, %r9
[Codegen] subq $8, %rsp
[Codegen] movq %rdi, %rcx
[Codegen] movq %r8, %rdx
[Codegen] movq %r9, %rdi
[Codegen] call .Lfrom501
[Codegen] addq $8, %rsp
[Codegen] pop %rsp
[Codegen] .set .Llabel506, .
[Codegen] vmovsd 0x8(%rsp), %xmm1
[Codegen] .set .Llabel512, .
[Codegen] vmovsd 0x0(%rsp), %xmm0
[Codegen] addq $16, %rsp
[Codegen] pop %rax
[Codegen] pop %rcx
[Codegen] pop %rdx
[Codegen] pop %rsi
[Codegen] pop %rdi
[Codegen] pop %r8
[Codegen] pop %r9
[Codegen] cmpl $0xfff98000, 0x34(%rsi)
[Codegen] je .Lfrom543
[Codegen] .set .Llabel543, .
[Codegen] .set .Llabel543, .
```
After (41 insns):
```plain-text
[Codegen] # LIR=NewTypedArray
[Codegen] movabsq $0x7f982fc2be30, %rdi
[Codegen] .set .Llabel366, .
[Codegen] movq 0x0(%rdi), %rcx
[Codegen] addq $64, %rcx
[Codegen] cmpq %rcx, 0x8(%rdi)
[Codegen] jb .Lfrom383
[Codegen] .set .Llabel383, .
[Codegen] movq %rcx, 0x0(%rdi)
[Codegen] subq $56, %rcx
[Codegen] movabsq $0x7f982e9fe918, %r11
[Codegen] movq %r11, -0x8(%rcx)
[Codegen] movabsq $0x21b30a167940, %r11
[Codegen] movq %r11, 0x0(%rcx)
[Codegen] movabsq $0x559606222440, %r11
[Codegen] movq %r11, 0x8(%rcx)
[Codegen] movabsq $0x559606222410, %r11
[Codegen] movq %r11, 0x10(%rcx)
[Codegen] movabsq $0xfff9000000000000, %r11
[Codegen] movq %r11, 0x18(%rcx)
[Codegen] movl $0x1000, %r11d
[Codegen] movq %r11, 0x20(%rcx)
[Codegen] xorl %r11d, %r11d
[Codegen] movq %r11, 0x28(%rcx)
[Codegen] movabsq $0xfff9800000000000, %rdi
[Codegen] .set .Llabel486, .
[Codegen] movq %rdi, 0x30(%rcx)
[Codegen] movl $0x1000, %edx
[Codegen] xorl %esi, %esi
[Codegen] push %rcx
[Codegen] push %rdx
[Codegen] movq %rsp, %rdi
[Codegen] andq $0xfffffffffffffff0, %rsp
[Codegen] push %rdi
[Codegen] movabsq $0x7f982fc33100, %rdi
[Codegen] subq $8, %rsp
[Codegen] xchgq %rsi, %rcx
[Codegen] call .Lfrom529
[Codegen] addq $8, %rsp
[Codegen] pop %rsp
[Codegen] pop %rdx
[Codegen] pop %rcx
[Codegen] cmpl $0xfff98000, 0x34(%rcx)
[Codegen] je .Lfrom549
[Codegen] movq %rcx, %rax
[Codegen] .set .Llabel552, .
[Codegen] .set .Llabel552, .
```
Differential Revision: https://phabricator.services.mozilla.com/D268309
Diffstat:
6 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
@@ -8683,11 +8683,11 @@ void CodeGenerator::visitNewTypedArrayInline(LNewTypedArrayInline* lir) {
}
void CodeGenerator::visitNewTypedArray(LNewTypedArray* lir) {
- Register objReg = ToRegister(lir->output());
+ Register output = ToRegister(lir->output());
Register temp1Reg = ToRegister(lir->temp0());
Register temp2Reg = ToRegister(lir->temp1());
Register lengthReg = ToRegister(lir->temp2());
- LiveRegisterSet liveRegs = liveVolatileRegs(lir);
+ Register temp4Reg = ToRegister(lir->temp3());
auto* templateObject = lir->mir()->templateObject();
gc::Heap initialHeap = lir->mir()->initialHeap();
@@ -8699,15 +8699,17 @@ void CodeGenerator::visitNewTypedArray(LNewTypedArray* lir) {
using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, int32_t length);
OutOfLineCode* ool = oolCallVM<Fn, NewTypedArrayWithTemplateAndLength>(
lir, ArgList(ImmGCPtr(templateObject), Imm32(n)),
- StoreRegisterTo(objReg));
+ StoreRegisterTo(output));
TemplateObject templateObj(templateObject);
- masm.createGCObject(objReg, temp1Reg, templateObj, initialHeap, ool->entry());
+ masm.createGCObject(temp4Reg, temp1Reg, templateObj, initialHeap,
+ ool->entry());
masm.move32(Imm32(n), lengthReg);
- masm.initTypedArraySlots(objReg, lengthReg, temp1Reg, temp2Reg, liveRegs,
+ masm.initTypedArraySlots(temp4Reg, lengthReg, temp1Reg, temp2Reg,
ool->entry(), templateObject);
+ masm.mov(temp4Reg, output);
masm.bind(ool->rejoin());
}
@@ -8715,10 +8717,10 @@ void CodeGenerator::visitNewTypedArray(LNewTypedArray* lir) {
void CodeGenerator::visitNewTypedArrayDynamicLength(
LNewTypedArrayDynamicLength* lir) {
Register lengthReg = ToRegister(lir->length());
- Register objReg = ToRegister(lir->output());
+ Register output = ToRegister(lir->output());
Register temp1Reg = ToRegister(lir->temp0());
Register temp2Reg = ToRegister(lir->temp1());
- LiveRegisterSet liveRegs = liveVolatileRegs(lir);
+ Register temp3Reg = ToRegister(lir->temp2());
JSObject* templateObject = lir->mir()->templateObject();
gc::Heap initialHeap = lir->mir()->initialHeap();
@@ -8728,16 +8730,15 @@ void CodeGenerator::visitNewTypedArrayDynamicLength(
using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, int32_t length);
OutOfLineCode* ool = oolCallVM<Fn, NewTypedArrayWithTemplateAndLength>(
lir, ArgList(ImmGCPtr(templateObject), lengthReg),
- StoreRegisterTo(objReg));
-
- // Volatile |lengthReg| is saved across the ABI call in |initTypedArraySlots|.
- MOZ_ASSERT_IF(lengthReg.volatile_(), liveRegs.has(lengthReg));
+ StoreRegisterTo(output));
TemplateObject templateObj(templateObject);
- masm.createGCObject(objReg, temp1Reg, templateObj, initialHeap, ool->entry());
+ masm.createGCObject(temp3Reg, temp1Reg, templateObj, initialHeap,
+ ool->entry());
- masm.initTypedArraySlots(objReg, lengthReg, temp1Reg, temp2Reg, liveRegs,
+ masm.initTypedArraySlots(temp3Reg, lengthReg, temp1Reg, temp2Reg,
ool->entry(), ttemplate);
+ masm.mov(temp3Reg, output);
masm.bind(ool->rejoin());
}
diff --git a/js/src/jit/LIROps.yaml b/js/src/jit/LIROps.yaml
@@ -205,7 +205,8 @@
- name: NewTypedArray
result_type: WordSized
- num_temps: 3
+ call_instruction: true
+ num_temps: 4
mir_op: true
- name: NewTypedArrayInline
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
@@ -163,8 +163,10 @@ void LIRGenerator::visitNewTypedArray(MNewTypedArray* ins) {
define(lir, ins);
assignSafepoint(lir, ins);
} else {
- auto* lir = new (alloc()) LNewTypedArray(temp(), temp(), temp());
- define(lir, ins);
+ auto* lir = new (alloc())
+ LNewTypedArray(tempFixed(CallTempReg0), tempFixed(CallTempReg1),
+ tempFixed(CallTempReg2), tempFixed(CallTempReg3));
+ defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
}
@@ -174,9 +176,10 @@ void LIRGenerator::visitNewTypedArrayDynamicLength(
MDefinition* length = ins->length();
MOZ_ASSERT(length->type() == MIRType::Int32);
- auto* lir = new (alloc())
- LNewTypedArrayDynamicLength(useRegister(length), temp(), temp());
- define(lir, ins);
+ auto* lir = new (alloc()) LNewTypedArrayDynamicLength(
+ useFixedAtStart(length, CallTempReg0), tempFixed(CallTempReg1),
+ tempFixed(CallTempReg2), tempFixed(CallTempReg3));
+ defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
diff --git a/js/src/jit/MIROps.yaml b/js/src/jit/MIROps.yaml
@@ -292,8 +292,9 @@
guard: true
# Throws if length is negative.
alias_set: custom
+ possibly_calls: true
generate_lir: true
- lir_temps: 2
+ lir_temps: 3
# Create a new TypedArray from an Array (or Array-like object) or a TypedArray.
- name: NewTypedArrayFromArray
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
@@ -902,10 +902,15 @@ static std::pair<uint32_t, uint32_t> FindStartOfUninitializedAndUndefinedSlots(
}
void MacroAssembler::initTypedArraySlots(
- Register obj, Register length, Register temp1, Register temp2,
- LiveRegisterSet liveRegs, Label* fail,
+ Register obj, Register length, Register temp1, Register temp2, Label* fail,
const FixedLengthTypedArrayObject* templateObj) {
MOZ_ASSERT(!templateObj->hasBuffer());
+ MOZ_ASSERT(obj != length);
+ MOZ_ASSERT(obj != temp1);
+ MOZ_ASSERT(obj != temp2);
+ MOZ_ASSERT(length != temp1);
+ MOZ_ASSERT(length != temp2);
+ MOZ_ASSERT(temp1 != temp2);
constexpr size_t dataSlotOffset = ArrayBufferViewObject::dataOffset();
constexpr size_t dataOffset = dataSlotOffset + sizeof(HeapSlot);
@@ -926,13 +931,14 @@ void MacroAssembler::initTypedArraySlots(
size_t inlineCapacity = templateObj->tenuredSizeOfThis() - dataOffset;
movePtr(ImmWord(inlineCapacity), temp2);
- // Ensure volatile |obj| is saved across the call.
+ // Ensure volatile |obj| and |length| are saved across the call.
if (obj.volatile_()) {
- liveRegs.addUnchecked(obj);
+ Push(obj);
+ }
+ if (length.volatile_()) {
+ Push(length);
}
-
// Allocate a buffer on the heap to store the data elements.
- PushRegsInMask(liveRegs);
using Fn =
void (*)(JSContext*, FixedLengthTypedArrayObject*, int32_t, size_t);
setupUnalignedABICall(temp1);
@@ -942,7 +948,12 @@ void MacroAssembler::initTypedArraySlots(
passABIArg(length);
passABIArg(temp2);
callWithABI<Fn, AllocateAndInitTypedArrayBuffer>();
- PopRegsInMask(liveRegs);
+ if (length.volatile_()) {
+ Pop(length);
+ }
+ if (obj.volatile_()) {
+ Pop(obj);
+ }
// Fail when data slot is UndefinedValue.
branchTestUndefined(Assembler::Equal, Address(obj, dataSlotOffset), fail);
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
@@ -5623,8 +5623,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
const TemplateObject& templateObj, bool initContents = true);
void initTypedArraySlots(Register obj, Register length, Register temp1,
- Register temp2, LiveRegisterSet liveRegs,
- Label* fail,
+ Register temp2, Label* fail,
const FixedLengthTypedArrayObject* templateObj);
void initTypedArraySlotsInline(