v8/test/cctest/test-poison-disasm-arm64.cc
Artem Serov 2048e5b7f6 [turbofan] Improve load poisoning tests.
Introduce a helper class for regular expression parsing
and use it to improve load poison tests readability and
maintainability.

Extend load poisoning tests for arm64 platform (e.g.
for both regular and compressed references cases).

Change-Id: Ie62dfd14a60186feaa5f48e1a6122d77766472af
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1645913
Commit-Queue: Martyn Capewell <martyn.capewell@arm.com>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62493}
2019-07-02 17:55:04 +00:00

161 lines
7.3 KiB
C++

// Copyright 2019 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/arm64/register-arm64.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)
"x" + 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.
#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 different
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldur w<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
"and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison
};
#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 different
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldur <<Field:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
};
#endif
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(o1);"
"poly(o2);"
"poly(o1);"
"poly(o2);"
"%OptimizeFunctionOnNextCall(poly);"
"poly(o1);");
// Matches that the property access sequence is instrumented with
// poisoning.
#if defined(V8_COMPRESS_POINTERS)
std::vector<std::string> patterns_array = {
"ldur <<Map0:w[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map
"ldr <<ExpMap:w[0-9]+>>, pc", // load map const #1
"cmp <<Map0>>, <<ExpMap>>", // compare maps
"b.eq", // ? go to the load
"csel " + kPReg + ", xzr, " + kPReg + ", eq", // update the poison
"csdb", // spec. barrier
"ldur <<Map1:w[0-9]+>>, \\[<<Obj>>, #-1\\]", // load map
"ldr <<ExpMap1:w[0-9]+>>, pc", // load map const #2
"cmp <<Map1>>, <<ExpMap1>>", // compare maps
"b.ne", // deopt if different
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldur w<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
"and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison
"sxtw x<<Field>>, w<<Field>>",
"asr w[0-9]+, w<<Field>>, #1", // untag
"b", // goto merge point
// Lcase1:
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldur w<<BSt:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store
"and x<<BSt>>, x<<BSt>>, " + kPReg, // apply the poison
"sbfx <<Temp:x[0-9]+>>, x<<BSt>>, #0, #1", // Decompress ref
"and <<Temp>>, <<Temp>>, x26", // Decompress ref
"add x<<BSt>>, <<Temp>>, w<<BSt>>, sxtw", // Decompress ref
"ldur w<<Prop:[0-9]+>>, \\[x<<BSt>>, #[0-9]+\\]", // load the property
"and x<<Prop>>, x<<Prop>>, " + kPReg, // apply the poison
// Ldone:
};
#else
std::vector<std::string> patterns_array = {
"ldur <<Map0:x[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map
"ldr <<ExpMap0:x[0-9]+>>, pc", // load map const #1
"cmp <<Map0>>, <<ExpMap0>>", // compare maps
"b.eq", // ? go to the load
"csel " + kPReg + ", xzr, " + kPReg + ", eq", // update the poison
"csdb", // spec. barrier
"ldur <<Map1:x[0-9]+>>, \\[<<Obj>>, #-1\\]", // load map
"ldr <<ExpMap1:x[0-9]+>>, pc", // load map const #2
"cmp <<Map1>>, <<ExpMap1>>", // compare maps
"b.ne", // deopt if different
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldur <<Field:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
"asr x[0-9]+, <<Field>>, #32", // untag
"b", // goto merge point
// Lcase1:
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldur <<BSt:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store
"and <<BSt>>, <<BSt>>, " + kPReg, // apply the poison
"ldur <<Prop:x[0-9]+>>, \\[<<BSt>>, #[0-9]+\\]", // load the property
"and <<Prop>>, <<Prop>>, " + kPReg, // apply the poison
// Ldone:
};
#endif
CHECK(CheckDisassemblyRegexPatterns("poly", patterns_array));
#endif // ENABLE_DISASSEMBLER
}
} // namespace internal
} // namespace v8