v8/test/cctest/test-poison-disasm-arm.cc
Artem Serov 66f2519628 Reland "[turbofan,arm64] Add float loads poisoning."
This is a reland of 2869d9de0d

Original change's description:
> [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}

Change-Id: I8155456f6ad571897f6274a86e58fec6cd66ee7d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1800583
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Commit-Queue: Martyn Capewell <martyn.capewell@arm.com>
Cr-Commit-Position: refs/heads/master@{#63800}
2019-09-16 14:57:08 +00:00

152 lines
6.2 KiB
C++

// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The C++ style guide recommends using <re2> instead of <regex>. However, the
// former isn't available in V8.
#include <regex> // NOLINT(build/c++11)
#include <vector>
#include "src/codegen/arm/register-arm.h"
#include "test/cctest/cctest.h"
#include "test/cctest/disasm-regex-helper.h"
namespace v8 {
namespace internal {
namespace {
// Poison register.
const int kPRegCode = kSpeculationPoisonRegister.code();
const std::string kPReg = // NOLINT(runtime/string)
"r" + std::to_string(kPRegCode);
} // namespace
TEST(DisasmPoisonMonomorphicLoad) {
#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 });"
"mono({ x : 1 });"
"%OptimizeFunctionOnNextCall(mono);"
"mono({ x : 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
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
};
CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array));
#endif // ENABLE_DISASSEMBLER
}
TEST(DisasmPoisonPolymorphicLoad) {
#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 poly(o) { return o.x + 1; };"
"let o1 = { x : 1 };"
"let o2 = { y : 1 };"
"o2.x = 2;"
"%PrepareFunctionForOptimization(poly);"
"poly(o2);"
"poly(o1);"
"poly(o2);"
"%OptimizeFunctionOnNextCall(poly);"
"poly(o1);");
// Matches that the property access sequence is instrumented with
// poisoning.
std::vector<std::string> patterns_array = {
"ldr <<Map0:r[0-9]+>>, \\[<<Obj:r[0-9]+>>, #-1\\]", // load map
"ldr <<ExpMap0:r[0-9]+>>, \\[pc", // load map const #1
"cmp <<Map0>>, <<ExpMap0>>", // compare maps
"beq", // ? go to the load
"eoreq " + kPReg + ", " + kPReg + ", " + kPReg, // update the poison
"csdb", // spec. barrier
"ldr <<Map1:r[0-9]+>>, \\[<<Obj>>, #-1\\]", // load map
"ldr <<ExpMap1:r[0-9]+>>, \\[pc", // load map const #2
"cmp <<Map1>>, <<ExpMap1>>", // 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
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
"mov r[0-9]+, <<Field>>, asr #1", // untag
"b", // goto merge point
// Lcase1:
"eorne " + kPReg + ", " + kPReg + ", " + kPReg, // update the poison
"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]+>>, \\[<<BSt>>, #\\+[0-9]+\\]", // load the property
"and <<Prop>>, <<Prop>>, " + kPReg, // apply the poison
// Ldone:
};
CHECK(CheckDisassemblyRegexPatterns("poly", patterns_array));
#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
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
"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