[turbofan,arm64] Add float loads poisoning.
Also extend load poisoning testing for arm and arm64. This is a port of I1ef202296744a39054366f2bc424d6952c3bbe9d, originally introduced for arm. Change-Id: I7d317bba6be633dd1e563daa7231d3c5e930f8e4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1691032 Commit-Queue: Martyn Capewell <martyn.capewell@arm.com> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#63519}
This commit is contained in:
parent
ffffed9020
commit
2869d9de0d
@ -389,6 +389,36 @@ void EmitWordLoadPoisoningIfNeeded(
|
||||
}
|
||||
}
|
||||
|
||||
void EmitMaybePoisonedFPLoad(CodeGenerator* codegen, InstructionCode opcode,
|
||||
Arm64OperandConverter* i, VRegister output_reg) {
|
||||
const MemoryAccessMode access_mode =
|
||||
static_cast<MemoryAccessMode>(MiscField::decode(opcode));
|
||||
AddressingMode address_mode = AddressingModeField::decode(opcode);
|
||||
if (access_mode == kMemoryAccessPoisoned && address_mode != kMode_Root) {
|
||||
UseScratchRegisterScope temps(codegen->tasm());
|
||||
Register address = temps.AcquireX();
|
||||
switch (address_mode) {
|
||||
case kMode_MRI: // Fall through.
|
||||
case kMode_MRR:
|
||||
codegen->tasm()->Add(address, i->InputRegister(0), i->InputOperand(1));
|
||||
break;
|
||||
case kMode_Operand2_R_LSL_I:
|
||||
codegen->tasm()->Add(address, i->InputRegister(0),
|
||||
i->InputOperand2_64(1));
|
||||
break;
|
||||
default:
|
||||
// Note: we don't need poisoning for kMode_Root loads as those loads
|
||||
// target a fixed offset from root register which is set once when
|
||||
// initializing the vm.
|
||||
UNREACHABLE();
|
||||
}
|
||||
codegen->tasm()->And(address, address, Operand(kSpeculationPoisonRegister));
|
||||
codegen->tasm()->Ldr(output_reg, MemOperand(address));
|
||||
} else {
|
||||
codegen->tasm()->Ldr(output_reg, i->MemoryOperand());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#define ASSEMBLE_SHIFT(asm_instr, width) \
|
||||
@ -1599,13 +1629,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
break;
|
||||
}
|
||||
case kArm64LdrS:
|
||||
__ Ldr(i.OutputDoubleRegister().S(), i.MemoryOperand());
|
||||
EmitMaybePoisonedFPLoad(this, opcode, &i, i.OutputDoubleRegister().S());
|
||||
break;
|
||||
case kArm64StrS:
|
||||
__ Str(i.InputFloat32OrZeroRegister(0), i.MemoryOperand(1));
|
||||
break;
|
||||
case kArm64LdrD:
|
||||
__ Ldr(i.OutputDoubleRegister(), i.MemoryOperand());
|
||||
EmitMaybePoisonedFPLoad(this, opcode, &i, i.OutputDoubleRegister());
|
||||
break;
|
||||
case kArm64StrD:
|
||||
__ Str(i.InputFloat64OrZeroRegister(0), i.MemoryOperand(1));
|
||||
|
@ -101,7 +101,7 @@ TEST(DisasmPoisonPolymorphicLoad) {
|
||||
"csdb", // spec. barrier
|
||||
"ldr <<BSt:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load backing store
|
||||
"and <<BSt>>, <<BSt>>, " + kPReg, // apply the poison
|
||||
"ldr <<Prop:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the property
|
||||
"ldr <<Prop:r[0-9]+>>, \\[<<BSt>>, #\\+[0-9]+\\]", // load the property
|
||||
"and <<Prop>>, <<Prop>>, " + kPReg, // apply the poison
|
||||
// Ldone:
|
||||
};
|
||||
@ -109,5 +109,42 @@ TEST(DisasmPoisonPolymorphicLoad) {
|
||||
#endif // ENABLE_DISASSEMBLER
|
||||
}
|
||||
|
||||
TEST(DisasmPoisonMonomorphicLoadFloat64) {
|
||||
#ifdef ENABLE_DISASSEMBLER
|
||||
if (i::FLAG_always_opt || !i::FLAG_opt) return;
|
||||
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
i::FLAG_untrusted_code_mitigations = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
|
||||
CompileRun(
|
||||
"function mono(o) { return o.x; }"
|
||||
"%PrepareFunctionForOptimization(mono);"
|
||||
"mono({ x : 1.1 });"
|
||||
"mono({ x : 1.1 });"
|
||||
"%OptimizeFunctionOnNextCall(mono);"
|
||||
"mono({ x : 1.1 });");
|
||||
|
||||
// Matches that the property access sequence is instrumented with
|
||||
// poisoning.
|
||||
std::vector<std::string> patterns_array = {
|
||||
"ldr <<Map:r[0-9]+>>, \\[<<Obj:r[0-9]+>>, #-1\\]", // load map
|
||||
"ldr <<ExpMap:r[0-9]+>>, \\[pc, #", // load expected map
|
||||
"cmp <<Map>>, <<ExpMap>>", // compare maps
|
||||
"bne", // deopt if different
|
||||
"eorne " + kPReg + ", " + kPReg + ", " + kPReg, // update the poison
|
||||
"csdb", // spec. barrier
|
||||
"ldr <<Field:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the field
|
||||
"mov <<Mov:r[0-9]+>>, #[0-9]+", // addr. calculation
|
||||
"add ip, <<Field>>, <<Mov>>", // addr. calculation
|
||||
"and ip, ip, " + kPReg, // apply the poison
|
||||
"vldr d[0-9]+, \\[ip", // load Float64
|
||||
};
|
||||
CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array));
|
||||
#endif // ENABLE_DISASSEMBLER
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -49,8 +49,8 @@ TEST(DisasmPoisonMonomorphicLoad) {
|
||||
"b.ne", // deopt if different
|
||||
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
|
||||
"csdb", // spec. barrier
|
||||
"ldursw x<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
|
||||
"and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison
|
||||
"ldursw <<Field:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
|
||||
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
|
||||
};
|
||||
#else
|
||||
std::vector<std::string> patterns_array = {
|
||||
@ -153,5 +153,56 @@ TEST(DisasmPoisonPolymorphicLoad) {
|
||||
#endif // ENABLE_DISASSEMBLER
|
||||
}
|
||||
|
||||
TEST(DisasmPoisonMonomorphicLoadFloat64) {
|
||||
#ifdef ENABLE_DISASSEMBLER
|
||||
if (i::FLAG_always_opt || !i::FLAG_opt) return;
|
||||
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
i::FLAG_untrusted_code_mitigations = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
|
||||
CompileRun(
|
||||
"function mono(o) { return o.x; }"
|
||||
"%PrepareFunctionForOptimization(mono);"
|
||||
"mono({ x : 1.1 });"
|
||||
"mono({ x : 1.1 });"
|
||||
"%OptimizeFunctionOnNextCall(mono);"
|
||||
"mono({ x : 1.1 });");
|
||||
|
||||
// Matches that the property access sequence is instrumented with
|
||||
// poisoning.
|
||||
#if defined(V8_COMPRESS_POINTERS)
|
||||
std::vector<std::string> patterns_array = {
|
||||
"ldur <<Map:w[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map
|
||||
"ldr <<ExpMap:w[0-9]+>>, pc", // load expected map
|
||||
"cmp <<Map>>, <<ExpMap>>", // compare maps
|
||||
"b.ne", // deopt if differ
|
||||
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
|
||||
"csdb", // spec. barrier
|
||||
"ldursw <<F1:x[0-9]+>>, \\[<<Obj>>, #11\\]", // load field
|
||||
"add <<F1>>, x26, <<F1>>", // Decompress ref
|
||||
"add <<Addr:x[0-9]+>>, <<F1>>, #0x[0-9a-f]+", // addr. calculation
|
||||
"and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison
|
||||
"ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64
|
||||
};
|
||||
#else
|
||||
std::vector<std::string> patterns_array = {
|
||||
"ldur <<Map:x[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map
|
||||
"ldr <<ExpMap:x[0-9]+>>, pc", // load expected map
|
||||
"cmp <<Map>>, <<ExpMap>>", // compare maps
|
||||
"b.ne", // deopt if differ
|
||||
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
|
||||
"csdb", // spec. barrier
|
||||
"add <<Addr:x[0-9]+>>, <<Obj>>, #0x[0-9a-f]+", // addr. calculation
|
||||
"and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison
|
||||
"ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64
|
||||
};
|
||||
#endif
|
||||
CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array));
|
||||
#endif // ENABLE_DISASSEMBLER
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user