зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1646787 - Mask i32 wasm results. r=luke
See bug for further information. Differential Revision: https://phabricator.services.mozilla.com/D80820
This commit is contained in:
Родитель
172b670f76
Коммит
37b5d029fa
|
@ -7865,8 +7865,8 @@ void CodeGenerator::visitGetNextEntryForIterator(
|
|||
}
|
||||
|
||||
// The point of these is to inform Ion of where these values already are; they
|
||||
// don't generate code.
|
||||
void CodeGenerator::visitWasmRegisterResult(LWasmRegisterResult* lir) {}
|
||||
// don't normally generate code. Still, visitWasmRegisterResult is
|
||||
// per-platform.
|
||||
void CodeGenerator::visitWasmRegisterPairResult(LWasmRegisterPairResult* lir) {}
|
||||
void CodeGenerator::visitWasmStackResult(LWasmStackResult* lir) {}
|
||||
void CodeGenerator::visitWasmStackResult64(LWasmStackResult64* lir) {}
|
||||
|
|
|
@ -4107,6 +4107,8 @@ IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo,
|
|||
current->add(postConversion);
|
||||
break;
|
||||
default:
|
||||
// No spectre.index_masking of i32 results required, as the generated
|
||||
// stub takes care of that.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1495,6 +1495,9 @@ void CodeGenerator::visitBitAndAndBranch(LBitAndAndBranch* baab) {
|
|||
emitBranch(baab->cond(), baab->ifTrue(), baab->ifFalse());
|
||||
}
|
||||
|
||||
// See ../CodeGenerator.cpp for more information.
|
||||
void CodeGenerator::visitWasmRegisterResult(LWasmRegisterResult* lir) {}
|
||||
|
||||
void CodeGenerator::visitWasmUint32ToDouble(LWasmUint32ToDouble* lir) {
|
||||
masm.convertUInt32ToDouble(ToRegister(lir->input()),
|
||||
ToFloatRegister(lir->output()));
|
||||
|
|
|
@ -1527,6 +1527,9 @@ void CodeGenerator::visitBitAndAndBranch(LBitAndAndBranch* baab) {
|
|||
emitBranch(baab->cond(), baab->ifTrue(), baab->ifFalse());
|
||||
}
|
||||
|
||||
// See ../CodeGenerator.cpp for more information.
|
||||
void CodeGenerator::visitWasmRegisterResult(LWasmRegisterResult* lir) {}
|
||||
|
||||
void CodeGenerator::visitWasmUint32ToDouble(LWasmUint32ToDouble* lir) {
|
||||
masm.convertUInt32ToDouble(ToRegister(lir->input()),
|
||||
ToFloatRegister(lir->output()));
|
||||
|
|
|
@ -7055,7 +7055,12 @@ class LWasmRegisterResult : public LInstructionHelper<1, 0, 0> {
|
|||
|
||||
LWasmRegisterResult() : LInstructionHelper(classOpcode) {}
|
||||
|
||||
MWasmRegisterResult* mir() const { return mir_->toWasmRegisterResult(); }
|
||||
MWasmRegisterResult* mir() const {
|
||||
if (!mir_->isWasmRegisterResult()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mir_->toWasmRegisterResult();
|
||||
}
|
||||
};
|
||||
|
||||
class LWasmRegisterPairResult : public LInstructionHelper<2, 0, 0> {
|
||||
|
|
|
@ -324,6 +324,16 @@ void CodeGenerator::visitUDivOrModI64(LUDivOrModI64* lir) {
|
|||
masm.bind(&done);
|
||||
}
|
||||
|
||||
void CodeGenerator::visitWasmRegisterResult(LWasmRegisterResult* lir) {
|
||||
if (JitOptions.spectreIndexMasking) {
|
||||
if (MWasmRegisterResult* mir = lir->mir()) {
|
||||
if (mir->type() == MIRType::Int32) {
|
||||
masm.movl(ToRegister(lir->output()), ToRegister(lir->output()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::visitWasmSelectI64(LWasmSelectI64* lir) {
|
||||
MOZ_ASSERT(lir->mir()->type() == MIRType::Int64);
|
||||
|
||||
|
|
|
@ -208,6 +208,9 @@ void CodeGenerator::visitCompareBitwiseAndBranch(
|
|||
emitBranch(cond, lir->ifTrue(), lir->ifFalse());
|
||||
}
|
||||
|
||||
// See ../CodeGenerator.cpp for more information.
|
||||
void CodeGenerator::visitWasmRegisterResult(LWasmRegisterResult* lir) {}
|
||||
|
||||
void CodeGenerator::visitWasmUint32ToDouble(LWasmUint32ToDouble* lir) {
|
||||
Register input = ToRegister(lir->input());
|
||||
Register temp = ToRegister(lir->temp());
|
||||
|
|
|
@ -3441,6 +3441,23 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef JS_CODEGEN_X64
|
||||
inline void maskResultRegisters(ResultType type) {
|
||||
MOZ_ASSERT(JitOptions.spectreIndexMasking);
|
||||
|
||||
if (type.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ABIResultIter iter(type); !iter.done(); iter.next()) {
|
||||
ABIResult result = iter.cur();
|
||||
if (result.inRegister() && result.type().kind() == ValType::I32) {
|
||||
masm.movl(result.gpr(), result.gpr());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void freeResultRegisters(ResultType type, RegKind which) {
|
||||
if (type.empty()) {
|
||||
return;
|
||||
|
@ -3540,6 +3557,15 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
needResultRegisters(type);
|
||||
}
|
||||
|
||||
void captureCallResultRegisters(ResultType type) {
|
||||
captureResultRegisters(type);
|
||||
#ifdef JS_CODEGEN_X64
|
||||
if (JitOptions.spectreIndexMasking) {
|
||||
maskResultRegisters(type);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Value stack and spilling.
|
||||
|
@ -5915,6 +5941,11 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
RegI32 r = RegI32(ReturnReg);
|
||||
MOZ_ASSERT(isAvailableI32(r));
|
||||
needI32(r);
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
if (JitOptions.spectreIndexMasking) {
|
||||
masm.movl(r, r);
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -10121,7 +10152,7 @@ bool BaseCompiler::emitCall() {
|
|||
|
||||
popValueStackBy(numArgs);
|
||||
|
||||
captureResultRegisters(resultType);
|
||||
captureCallResultRegisters(resultType);
|
||||
pushCallResults(baselineCall, resultType, results);
|
||||
|
||||
return true;
|
||||
|
@ -10178,7 +10209,7 @@ bool BaseCompiler::emitCallIndirect() {
|
|||
|
||||
popValueStackBy(numArgs);
|
||||
|
||||
captureResultRegisters(resultType);
|
||||
captureCallResultRegisters(resultType);
|
||||
pushCallResults(baselineCall, resultType, results);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -799,6 +799,7 @@ static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe,
|
|||
#endif
|
||||
|
||||
// Store the register result, if any, in argv[0].
|
||||
// No spectre.index_masking is required, as the value leaves ReturnReg.
|
||||
StoreRegisterResult(masm, fe, argv);
|
||||
|
||||
// After the ReturnReg is stored into argv[0] but before fp is clobbered by
|
||||
|
@ -1257,6 +1258,7 @@ static bool GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex,
|
|||
switch (results[0].kind()) {
|
||||
case ValType::I32:
|
||||
GenPrintIsize(DebugChannel::Function, masm, ReturnReg);
|
||||
// No spectre.index_masking is required, as the value is boxed.
|
||||
masm.boxNonDouble(JSVAL_TYPE_INT32, ReturnReg, JSReturnOperand);
|
||||
break;
|
||||
case ValType::F32: {
|
||||
|
@ -1356,6 +1358,8 @@ static bool GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex,
|
|||
SymbolicAddress::CoerceInPlace_JitEntry);
|
||||
masm.assertStackAlignment(ABIStackAlignment);
|
||||
|
||||
// No spectre.index_masking is required, as the return value is used as a
|
||||
// bool.
|
||||
masm.branchTest32(Assembler::NonZero, ReturnReg, ReturnReg,
|
||||
&rejoinBeforeCall);
|
||||
}
|
||||
|
@ -1560,6 +1564,11 @@ void wasm::GenerateDirectCallFromJit(MacroAssembler& masm, const FuncExport& fe,
|
|||
case wasm::ValType::I32:
|
||||
// The return value is in ReturnReg, which is what Ion expects.
|
||||
GenPrintIsize(DebugChannel::Function, masm, ReturnReg);
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
if (JitOptions.spectreIndexMasking) {
|
||||
masm.movl(ReturnReg, ReturnReg);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case wasm::ValType::I64:
|
||||
// The return value is in ReturnReg64, which is what Ion expects.
|
||||
|
@ -2060,6 +2069,8 @@ static bool GenerateImportInterpExit(MacroAssembler& masm, const FuncImport& fi,
|
|||
masm.call(SymbolicAddress::CallImport_I32);
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.load32(argv, ReturnReg);
|
||||
// No spectre.index_masking is required, as we know the value comes from
|
||||
// an i32 load.
|
||||
GenPrintf(DebugChannel::Import, masm, "wasm-import[%u]; returns ",
|
||||
funcImportIndex);
|
||||
GenPrintIsize(DebugChannel::Import, masm, ReturnReg);
|
||||
|
@ -2317,6 +2328,8 @@ static bool GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi,
|
|||
MOZ_ASSERT(results.length() == 1, "multi-value return unimplemented");
|
||||
switch (results[0].kind()) {
|
||||
case ValType::I32:
|
||||
// No spectre.index_masking required, as the return value does not come
|
||||
// to us in ReturnReg.
|
||||
masm.truncateValueToInt32(JSReturnOperand, ReturnDoubleReg, ReturnReg,
|
||||
&oolConvert);
|
||||
GenPrintIsize(DebugChannel::Import, masm, ReturnReg);
|
||||
|
@ -2422,6 +2435,8 @@ static bool GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi,
|
|||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.unboxInt32(Address(masm.getStackPointer(), offsetToCoerceArgv),
|
||||
ReturnReg);
|
||||
// No spectre.index_masking required, as we generate a known-good
|
||||
// value in a safe way here.
|
||||
break;
|
||||
case ValType::I64: {
|
||||
masm.call(SymbolicAddress::CoerceInPlace_ToBigInt);
|
||||
|
@ -2542,7 +2557,9 @@ bool wasm::GenerateBuiltinThunk(MacroAssembler& masm, ABIFunctionType abiType,
|
|||
MoveSPForJitABI(masm);
|
||||
masm.call(ImmPtr(funcPtr, ImmPtr::NoCheckToken()));
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
// No spectre.index_masking is required, as the caller will mask.
|
||||
#elif defined(JS_CODEGEN_X86)
|
||||
// x86 passes the return value on the x87 FP stack.
|
||||
Operand op(esp, 0);
|
||||
MIRType retType = ToMIRType(ABIArgType(abiType & ArgType_Mask));
|
||||
|
|
Загрузка…
Ссылка в новой задаче