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:
Lars T Hansen 2020-06-26 15:22:50 +00:00
Родитель 172b670f76
Коммит 37b5d029fa
9 изменённых файлов: 80 добавлений и 6 удалений

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

@ -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));