Bug 1639153 - Part 2: Preserve callee and caller tls'es. r=lth

This is a followup patch for removing Frame::tls.
Now, we are preserving caller's and callee's tls'es for all possible cross-instance calls in the previously allocated abi slots.
We also use preserved tls values to restore the caller's tls in Ion. Baseline doesn't need this because it restores the caller tls from its private stack slot after the call.

Differential Revision: https://phabricator.services.mozilla.com/D82888
This commit is contained in:
Dmitry Bezhetskov 2020-11-03 10:20:49 +00:00
Родитель ee1a9eaf56
Коммит 5559874442
4 изменённых файлов: 38 добавлений и 1 удалений

Просмотреть файл

@ -8606,7 +8606,8 @@ void CodeGenerator::visitWasmCall(LWasmCall* lir) {
MOZ_ASSERT(!lir->safepoint()->isWasmTrap());
if (reloadRegs) {
masm.loadWasmTlsRegFromFrame();
masm.loadPtr(Address(masm.getStackPointer(), WasmCallerTLSOffsetBeforeCall),
WasmTlsReg);
masm.loadWasmPinnedRegsFromTls();
if (switchRealm) {
masm.switchToWasmTlsRealm(ABINonArgReturnReg0, ABINonArgReturnReg1);

Просмотреть файл

@ -3758,6 +3758,9 @@ std::pair<CodeOffset, uint32_t> MacroAssembler::wasmReserveStackChecked(
CodeOffset MacroAssembler::wasmCallImport(const wasm::CallSiteDesc& desc,
const wasm::CalleeDesc& callee) {
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCallerTLSOffsetBeforeCall));
// Load the callee, before the caller's registers are clobbered.
uint32_t globalDataOffset = callee.importGlobalDataOffset();
loadWasmGlobalPtr(globalDataOffset + offsetof(wasm::FuncImportTls, code),
@ -3776,6 +3779,9 @@ CodeOffset MacroAssembler::wasmCallImport(const wasm::CallSiteDesc& desc,
// Switch to the callee's TLS and pinned registers and make the call.
loadWasmGlobalPtr(globalDataOffset + offsetof(wasm::FuncImportTls, tls),
WasmTlsReg);
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCalleeTLSOffsetBeforeCall));
loadWasmPinnedRegsFromTls();
return call(desc, ABINonArgReg0);
@ -3786,6 +3792,10 @@ CodeOffset MacroAssembler::wasmCallBuiltinInstanceMethod(
wasm::SymbolicAddress builtin, wasm::FailureMode failureMode) {
MOZ_ASSERT(instanceArg != ABIArg());
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCallerTLSOffsetBeforeCall));
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCalleeTLSOffsetBeforeCall));
if (instanceArg.kind() == ABIArg::GPR) {
loadPtr(Address(WasmTlsReg, offsetof(wasm::TlsData, instance)),
instanceArg.gpr());
@ -3851,6 +3861,10 @@ CodeOffset MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc,
addPtr(index, scratch);
}
loadPtr(Address(scratch, offsetof(wasm::FunctionTableElem, code)), scratch);
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCallerTLSOffsetBeforeCall));
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCalleeTLSOffsetBeforeCall));
return call(desc, scratch);
}
@ -3892,7 +3906,11 @@ CodeOffset MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc,
addPtr(index, scratch);
}
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCallerTLSOffsetBeforeCall));
loadPtr(Address(scratch, offsetof(wasm::FunctionTableElem, tls)), WasmTlsReg);
storePtr(WasmTlsReg,
Address(getStackPointer(), WasmCalleeTLSOffsetBeforeCall));
Label nonNull;
branchTest32(Assembler::NonZero, WasmTlsReg, WasmTlsReg, &nonNull);

Просмотреть файл

@ -260,6 +260,11 @@ static inline DynFn DynamicFunction(Sig fun);
enum class CharEncoding { Latin1, TwoByte };
constexpr uint32_t WasmCallerTLSOffsetBeforeCall =
wasm::FrameWithTls::callerTLSOffset() + ShadowStackSpace;
constexpr uint32_t WasmCalleeTLSOffsetBeforeCall =
wasm::FrameWithTls::calleeTLSOffset() + ShadowStackSpace;
// The public entrypoint for emitting assembly. Note that a MacroAssembler can
// use cx->lifoAlloc, so take care not to interleave masm use with other
// lifoAlloc use if one will be destroyed before the other.

Просмотреть файл

@ -3311,8 +3311,21 @@ class FrameWithTls : public Frame {
constexpr static uint32_t sizeWithoutFrame() {
return sizeof(wasm::FrameWithTls) - sizeof(wasm::Frame);
}
constexpr static uint32_t calleeTLSOffset() {
return offsetof(FrameWithTls, calleeTls_) - sizeof(wasm::Frame);
}
constexpr static uint32_t callerTLSOffset() {
return offsetof(FrameWithTls, callerTls_) - sizeof(wasm::Frame);
}
};
static_assert(FrameWithTls::calleeTLSOffset() == 0u,
"Callee tls stored right above the return address.");
static_assert(FrameWithTls::callerTLSOffset() == sizeof(void*),
"Caller tls stored right above the callee tls.");
static_assert(FrameWithTls::sizeWithoutFrame() == 2 * sizeof(void*),
"There are only two additional slots");