Skip to content

Commit 60a5bb3

Browse files
gezalorewebkit-commit-queue
authored andcommitted
[JSC][ARMv7] Support callee save FPRs
Patch by Geza Lore <glore@igalia.com> on 2022-05-25 https://bugs.webkit.org/show_bug.cgi?id=240376 Reviewed by Yusuke Suzuki. ARMv7 FPRs d8-d15 (also referenced as s16-s32 and q4-q7) are callee save in the host ABI, but currently JSC is unaware of this. This does not currently cause problems as they are not used, but will be used by the Wasm JITs. In preparation for the 32-bit ports of the Wasm JITs, this patch: - Teaches JSC about callee save FPRs on ARMv7. d8-d15 are host ABI callee save, but only d8-d14 are VM callee save, i.e.: we treat d15 as a volatile register in JIT code. This is so we can use d15 as a macro assembler scratch register. - Changes offlineasm and MacroAssemblerARMv7 to use d15 as the FP scratch register. We do this so we can use the full range of d0-d7 as temporary, and in particular as Wasm argument/return registers. - To achieve the above, we need to modify RegisterAtOffsetList as GPRs and FPRs have different sizes on JSVALUE32_64 platforms - Adds the ARMv7 specific registers to RegisterSet::macroScratchRegisters() * assembler/ARMv7Registers.h: * assembler/MacroAssemblerARMv7.h: * b3/air/AirCode.cpp: (JSC::B3::Air::Code::calleeSaveRegisterAtOffsetList const): (JSC::B3::Air::Code::dump const): * b3/testb3_7.cpp: (testInfiniteLoopDoesntCauseBadHoisting): * bytecode/CodeBlock.cpp: (JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters): (JSC::CodeBlock::calleeSaveSpaceAsVirtualRegisters): (JSC::roundCalleeSaveSpaceAsVirtualRegisters): Deleted. * bytecode/ValueRecovery.h: (JSC::ValueRecovery::calleeSaveGPRDisplacedInJSStack): (JSC::ValueRecovery::calleeSaveRegDisplacedInJSStack): Deleted. * dfg/DFGOSREntry.cpp: (JSC::DFG::prepareOSREntry): * dfg/DFGOSRExitCompilerCommon.cpp: (JSC::DFG::calleeSaveSlot): * ftl/FTLOSRExitCompiler.cpp: (JSC::FTL::compileStub): * interpreter/Interpreter.cpp: (JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const): * jit/AssemblyHelpers.cpp: (JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer): (JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl): (JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl): (JSC::AssemblyHelpers::emitSave): (JSC::AssemblyHelpers::emitRestore): (JSC::AssemblyHelpers::emitSaveCalleeSavesFor): (JSC::AssemblyHelpers::emitRestoreCalleeSavesFor): (JSC::AssemblyHelpers::copyLLIntBaselineCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer): (JSC::AssemblyHelpers::emitSaveOrCopyLLIntBaselineCalleeSavesFor): * jit/CallFrameShuffleData.cpp: (JSC::CallFrameShuffleData::setupCalleeSaveRegisters): * jit/CallFrameShuffler.h: (JSC::CallFrameShuffler::snapshot const): * jit/CallFrameShuffler32_64.cpp: (JSC::CallFrameShuffler::emitDisplace): * jit/FPRInfo.h: * jit/GPRInfo.h: * jit/RegisterAtOffsetList.cpp: (JSC::RegisterAtOffsetList::RegisterAtOffsetList): * jit/RegisterAtOffsetList.h: (JSC::RegisterAtOffsetList::registerCount const): (JSC::RegisterAtOffsetList::sizeOfAreaInBytes const): (JSC::RegisterAtOffsetList::adjustOffsets): (JSC::RegisterAtOffsetList::size const): Deleted. (JSC::RegisterAtOffsetList::at): Deleted. * jit/RegisterSet.cpp: (JSC::RegisterSet::macroScratchRegisters): (JSC::RegisterSet::vmCalleeSaveRegisters): * llint/LowLevelInterpreter.asm: * offlineasm/arm.rb: * wasm/js/JSToWasm.cpp: (JSC::Wasm::createJSToWasmWrapper): * wasm/js/WasmToJS.cpp: (JSC::Wasm::wasmToJS): * wasm/js/WebAssemblyFunction.cpp: (JSC::WebAssemblyFunction::jsCallEntrypointSlow): Canonical link: https://commits.webkit.org/250952@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294794 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 651fcae commit 60a5bb3

24 files changed

Lines changed: 250 additions & 137 deletions

‎Source/JavaScriptCore/assembler/ARMv7Registers.h‎

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,22 @@
104104
macro(s13, "s13", 0, 0) \
105105
macro(s14, "s14", 0, 0) \
106106
macro(s15, "s15", 0, 0) \
107-
macro(s16, "s16", 0, 0) \
108-
macro(s17, "s17", 0, 0) \
109-
macro(s18, "s18", 0, 0) \
110-
macro(s19, "s19", 0, 0) \
111-
macro(s20, "s20", 0, 0) \
112-
macro(s21, "s21", 0, 0) \
113-
macro(s22, "s22", 0, 0) \
114-
macro(s23, "s23", 0, 0) \
115-
macro(s24, "s24", 0, 0) \
116-
macro(s25, "s25", 0, 0) \
117-
macro(s26, "s26", 0, 0) \
118-
macro(s27, "s27", 0, 0) \
119-
macro(s28, "s28", 0, 0) \
120-
macro(s29, "s29", 0, 0) \
121-
macro(s30, "s30", 0, 0) \
122-
macro(s31, "s31", 0, 0)
107+
macro(s16, "s16", 0, 1) \
108+
macro(s17, "s17", 0, 1) \
109+
macro(s18, "s18", 0, 1) \
110+
macro(s19, "s19", 0, 1) \
111+
macro(s20, "s20", 0, 1) \
112+
macro(s21, "s21", 0, 1) \
113+
macro(s22, "s22", 0, 1) \
114+
macro(s23, "s23", 0, 1) \
115+
macro(s24, "s24", 0, 1) \
116+
macro(s25, "s25", 0, 1) \
117+
macro(s26, "s26", 0, 1) \
118+
macro(s27, "s27", 0, 1) \
119+
macro(s28, "s28", 0, 1) \
120+
macro(s29, "s29", 0, 1) \
121+
macro(s30, "s30", 0, 1) \
122+
macro(s31, "s31", 0, 1)
123123

124124
#if CPU(ARM_NEON) || CPU(ARM_VFP_V3_D32)
125125
#define FOR_EACH_FP_DOUBLE_REGISTER(macro) \
@@ -131,14 +131,14 @@
131131
macro(d5, "d5", 0, 0) \
132132
macro(d6, "d6", 0, 0) \
133133
macro(d7, "d7", 0, 0) \
134-
macro(d8, "d8", 0, 0) \
135-
macro(d9, "d9", 0, 0) \
136-
macro(d10, "d10", 0, 0) \
137-
macro(d11, "d11", 0, 0) \
138-
macro(d12, "d12", 0, 0) \
139-
macro(d13, "d13", 0, 0) \
140-
macro(d14, "d14", 0, 0) \
141-
macro(d15, "d15", 0, 0) \
134+
macro(d8, "d8", 0, 1) \
135+
macro(d9, "d9", 0, 1) \
136+
macro(d10, "d10", 0, 1) \
137+
macro(d11, "d11", 0, 1) \
138+
macro(d12, "d12", 0, 1) \
139+
macro(d13, "d13", 0, 1) \
140+
macro(d14, "d14", 0, 1) \
141+
macro(d15, "d15", 0, 1) \
142142
macro(d16, "d16", 0, 0) \
143143
macro(d17, "d17", 0, 0) \
144144
macro(d18, "d18", 0, 0) \
@@ -165,14 +165,14 @@
165165
macro(d5, "d5", 0, 0) \
166166
macro(d6, "d6", 0, 0) \
167167
macro(d7, "d7", 0, 0) \
168-
macro(d8, "d8", 0, 0) \
169-
macro(d9, "d9", 0, 0) \
170-
macro(d10, "d10", 0, 0) \
171-
macro(d11, "d11", 0, 0) \
172-
macro(d12, "d12", 0, 0) \
173-
macro(d13, "d13", 0, 0) \
174-
macro(d14, "d14", 0, 0) \
175-
macro(d15, "d15", 0, 0)
168+
macro(d8, "d8", 0, 1) \
169+
macro(d9, "d9", 0, 1) \
170+
macro(d10, "d10", 0, 1) \
171+
macro(d11, "d11", 0, 1) \
172+
macro(d12, "d12", 0, 1) \
173+
macro(d13, "d13", 0, 1) \
174+
macro(d14, "d14", 0, 1) \
175+
macro(d15, "d15", 0, 1)
176176
#endif
177177

178178
#if CPU(ARM_NEON)
@@ -181,10 +181,10 @@
181181
macro(q1, "q1", 0, 0) \
182182
macro(q2, "q2", 0, 0) \
183183
macro(q3, "q3", 0, 0) \
184-
macro(q4, "q4", 0, 0) \
185-
macro(q5, "q5", 0, 0) \
186-
macro(q6, "q6", 0, 0) \
187-
macro(q7, "q7", 0, 0) \
184+
macro(q4, "q4", 0, 1) \
185+
macro(q5, "q5", 0, 1) \
186+
macro(q6, "q6", 0, 1) \
187+
macro(q7, "q7", 0, 1) \
188188
macro(q8, "q8", 0, 0) \
189189
macro(q9, "q9", 0, 0) \
190190
macro(q10, "q10", 0, 0) \

‎Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<Assembler> {
4141
public:
4242
static constexpr size_t nearJumpRange = 16 * MB;
4343

44-
private:
4544
static constexpr RegisterID dataTempRegister = ARMRegisters::ip;
4645
static constexpr RegisterID addressTempRegister = ARMRegisters::r6;
4746

48-
static constexpr ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d7;
47+
// d15 is host/C ABI callee save, but is volatile in the VM/JS ABI. We use
48+
// this as scratch register so we can use the full range of d0-d7 as
49+
// temporary, and in particular as Wasm argument/return register.
50+
static constexpr ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d15;
51+
private:
4952
inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
5053

5154
// In the Thumb-2 instruction set, instructions operating only on registers r0-r7 can often

‎Source/JavaScriptCore/b3/air/AirCode.cpp‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,8 @@ void Code::setCalleeSaveRegisterAtOffsetList(RegisterAtOffsetList&& registerAtOf
229229
RegisterAtOffsetList Code::calleeSaveRegisterAtOffsetList() const
230230
{
231231
RegisterAtOffsetList result = m_uncorrectedCalleeSaveRegisterAtOffsetList;
232-
if (StackSlot* slot = m_calleeSaveStackSlot) {
233-
ptrdiff_t offset = slot->byteSize() + slot->offsetFromFP();
234-
for (size_t i = result.size(); i--;) {
235-
result.at(i) = RegisterAtOffset(
236-
result.at(i).reg(),
237-
result.at(i).offset() + offset);
238-
}
239-
}
232+
if (StackSlot* slot = m_calleeSaveStackSlot)
233+
result.adjustOffsets(slot->byteSize() + slot->offsetFromFP());
240234
return result;
241235
}
242236

@@ -277,7 +271,7 @@ void Code::dump(PrintStream& out) const
277271
if (m_callArgAreaSize)
278272
out.print(tierName, "Call arg area size: ", m_callArgAreaSize, "\n");
279273
RegisterAtOffsetList calleeSaveRegisters = this->calleeSaveRegisterAtOffsetList();
280-
if (calleeSaveRegisters.size())
274+
if (calleeSaveRegisters.registerCount())
281275
out.print(tierName, "Callee saves: ", calleeSaveRegisters, "\n");
282276
}
283277

‎Source/JavaScriptCore/b3/testb3_7.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1557,7 +1557,7 @@ void testInfiniteLoopDoesntCauseBadHoisting()
15571557

15581558
// The patchpoint early ret() works because we don't have callee saves.
15591559
auto code = compileProc(proc);
1560-
RELEASE_ASSERT(!proc.calleeSaveRegisterAtOffsetList().size());
1560+
RELEASE_ASSERT(!proc.calleeSaveRegisterAtOffsetList().registerCount());
15611561
invoke<void>(*code, static_cast<uint64_t>(55)); // Shouldn't crash dereferncing 55.
15621562
}
15631563

‎Source/JavaScriptCore/bytecode/CodeBlock.cpp‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,21 +2462,14 @@ unsigned CodeBlock::reoptimizationRetryCounter() const
24622462
}
24632463

24642464
#if !ENABLE(C_LOOP)
2465-
static size_t roundCalleeSaveSpaceAsVirtualRegisters(size_t calleeSaveRegisters)
2466-
{
2467-
2468-
return (WTF::roundUpToMultipleOf(sizeof(Register), calleeSaveRegisters * sizeof(CPURegister)) / sizeof(Register));
2469-
2470-
}
2471-
24722465
size_t CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()
24732466
{
2474-
return roundCalleeSaveSpaceAsVirtualRegisters(numberOfLLIntBaselineCalleeSaveRegisters());
2467+
return WTF::roundUpToMultipleOf<sizeof(Register)>(numberOfLLIntBaselineCalleeSaveRegisters() * sizeof(CPURegister)) / sizeof(Register);
24752468
}
24762469

24772470
size_t CodeBlock::calleeSaveSpaceAsVirtualRegisters(const RegisterAtOffsetList& calleeSaveRegisters)
24782471
{
2479-
return roundCalleeSaveSpaceAsVirtualRegisters(calleeSaveRegisters.size());
2472+
return WTF::roundUpToMultipleOf<sizeof(Register)>(calleeSaveRegisters.sizeOfAreaInBytes()) / sizeof(Register);
24802473
}
24812474
#endif
24822475

‎Source/JavaScriptCore/bytecode/ValueRecovery.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class ValueRecovery {
192192
}
193193

194194
#if USE(JSVALUE32_64)
195-
static ValueRecovery calleeSaveRegDisplacedInJSStack(VirtualRegister virtualReg, bool inTag)
195+
static ValueRecovery calleeSaveGPRDisplacedInJSStack(VirtualRegister virtualReg, bool inTag)
196196
{
197197
ValueRecovery result;
198198
UnionType u;

‎Source/JavaScriptCore/dfg/DFGOSREntry.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ void* prepareOSREntry(VM& vm, CallFrame* callFrame, CodeBlock* codeBlock, Byteco
299299
RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
300300
RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters());
301301

302-
unsigned registerCount = registerSaveLocations->size();
302+
unsigned registerCount = registerSaveLocations->registerCount();
303303
VMEntryRecord* record = vmEntryRecord(vm.topEntryFrame);
304304
for (unsigned i = 0; i < registerCount; i++) {
305305
RegisterAtOffset currentEntry = registerSaveLocations->at(i);

‎Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ static MacroAssemblerCodePtr<JSEntryPtrTag> callerReturnPC(CodeBlock* baselineCo
231231
CCallHelpers::Address calleeSaveSlot(InlineCallFrame* inlineCallFrame, CodeBlock* baselineCodeBlock, GPRReg calleeSave)
232232
{
233233
const RegisterAtOffsetList* calleeSaves = baselineCodeBlock->jitCode()->calleeSaveRegisters();
234-
for (unsigned i = 0; i < calleeSaves->size(); i++) {
234+
for (unsigned i = 0; i < calleeSaves->registerCount(); i++) {
235235
RegisterAtOffset entry = calleeSaves->at(i);
236236
if (entry.reg() != calleeSave)
237237
continue;

‎Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static void compileStub(VM& vm, unsigned exitID, JITCode* jitCode, OSRExit& exit
182182
sizeof(EncodedJSValue) * (
183183
exit.m_descriptor->m_values.size() + numMaterializations + maxMaterializationNumArguments) +
184184
requiredScratchMemorySizeInBytes() +
185-
codeBlock->jitCode()->calleeSaveRegisters()->size() * sizeof(uint64_t));
185+
codeBlock->jitCode()->calleeSaveRegisters()->sizeOfAreaInBytes());
186186
EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : nullptr;
187187
EncodedJSValue* materializationPointers = scratch + exit.m_descriptor->m_values.size();
188188
EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
@@ -452,7 +452,7 @@ static void compileStub(VM& vm, unsigned exitID, JITCode* jitCode, OSRExit& exit
452452
jit.move(CCallHelpers::framePointerRegister, srcBufferGPR);
453453
jit.move(CCallHelpers::TrustedImmPtr(unwindScratch), destBufferGPR);
454454
CCallHelpers::CopySpooler spooler(CCallHelpers::CopySpooler::BufferRegs::AllowModification, jit, srcBufferGPR, destBufferGPR, GPRInfo::regT0, GPRInfo::regT1);
455-
for (unsigned i = codeBlock->jitCode()->calleeSaveRegisters()->size(); i--;) {
455+
for (unsigned i = codeBlock->jitCode()->calleeSaveRegisters()->registerCount(); i--;) {
456456
RegisterAtOffset entry = codeBlock->jitCode()->calleeSaveRegisters()->at(i);
457457
spooler.loadGPR(entry.offset());
458458
spooler.storeGPR(i * sizeof(uint64_t));

‎Source/JavaScriptCore/interpreter/Interpreter.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ class UnwindFunctor {
625625
RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
626626
CPURegister* frame = reinterpret_cast<CPURegister*>(m_callFrame->registers());
627627

628-
unsigned registerCount = currentCalleeSaves->size();
628+
unsigned registerCount = currentCalleeSaves->registerCount();
629629
VMEntryRecord* record = vmEntryRecord(m_vm.topEntryFrame);
630630
for (unsigned i = 0; i < registerCount; i++) {
631631
RegisterAtOffset currentEntry = currentCalleeSaves->at(i);

0 commit comments

Comments
 (0)