Reland "[codegen] Add TSAN support for tagged stores in generated code"

This is a reland of 2c096b539e

Relanding as-is. Reason for reland: was speculatively reverted.

Original change's description:
> [codegen] Add TSAN support for tagged stores in generated code
>
> Mimics the kArchStoreWithWriteBarrier store in generated code by having
> a relaxed store to the same address, with the same value. This is done
> in order for TSAN to see these stores from generated code.
>
> Since it is done only for kArchStoreWithWriteBarrier TSAN will see
> tagged stores only.
>
> Bug: v8:7790, v8:11600
>
> Change-Id: I275dd46f5556b3a095c416adc03f2f0ac5bde41c
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2848470
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Georg Neis <neis@chromium.org>
> Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#74568}

Bug: v8:7790
Bug: v8:11600
Change-Id: Id1616a0f65b56cb96ca2ffd25d6ef51d0e7230da
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2914874
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74721}
This commit is contained in:
Santiago Aboy Solanes 2021-05-14 11:31:04 +01:00 committed by V8 LUCI CQ
parent 6156aecd3a
commit 4f41eb1a6e
5 changed files with 73 additions and 0 deletions

View File

@ -609,6 +609,7 @@ external_v8_defines = [
"V8_NO_ARGUMENTS_ADAPTOR",
"V8_USE_PERFETTO",
"V8_MAP_PACKING",
"V8_IS_TSAN",
]
enabled_external_v8_defines = []
@ -645,6 +646,9 @@ if (v8_use_perfetto) {
if (v8_enable_map_packing) {
enabled_external_v8_defines += [ "V8_MAP_PACKING" ]
}
if (is_tsan) {
enabled_external_v8_defines += [ "V8_IS_TSAN" ]
}
disabled_external_v8_defines = external_v8_defines - enabled_external_v8_defines

View File

@ -420,4 +420,13 @@ bool is_inbounds(float_t v) {
#define IF_WASM(V, ...)
#endif // V8_ENABLE_WEBASSEMBLY
// Defines IF_TSAN, to be used in macro lists for elements that should only be
// there if TSAN is enabled.
#ifdef V8_IS_TSAN
// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
#define IF_TSAN(V, ...) EXPAND(V(__VA_ARGS__))
#else
#define IF_TSAN(V, ...)
#endif // V8_ENABLE_WEBASSEMBLY
#endif // V8_BASE_MACROS_H_

View File

@ -1153,6 +1153,28 @@ static uint64_t atomic_pair_compare_exchange(intptr_t address,
FUNCTION_REFERENCE(atomic_pair_compare_exchange_function,
atomic_pair_compare_exchange)
#ifdef V8_IS_TSAN
// Mimics the store in generated code (generated by kArchStoreWithWriteBarrier)
// by having a relaxed store to the same address, with the same value. This is
// done in order for TSAN to see these stores from generated code.
// TODO(solanes): Also do this for non-kArchStoreWithWriteBarrier stores.
static void tsan_relaxed_store(Address addr, int64_t value) {
#if V8_TARGET_ARCH_X64
if (COMPRESS_POINTERS_BOOL) {
base::Relaxed_Store(reinterpret_cast<base::Atomic32*>(addr),
static_cast<base::Atomic32>(value));
} else {
base::Relaxed_Store(reinterpret_cast<base::Atomic64*>(addr),
static_cast<base::Atomic64>(value));
}
#else
UNREACHABLE();
#endif // V8_TARGET_ARCH_X64
}
#endif // V8_IS_TSAN
IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_store_function, tsan_relaxed_store)
static int EnterMicrotaskContextWrapper(HandleScopeImplementer* hsi,
Address raw_context) {
Context context = Context::cast(Object(raw_context));

View File

@ -265,6 +265,7 @@ class StatsCounter;
V(atomic_pair_exchange_function, "atomic_pair_exchange_function") \
V(atomic_pair_compare_exchange_function, \
"atomic_pair_compare_exchange_function") \
IF_TSAN(V, tsan_relaxed_store_function, "tsan_relaxed_store_function") \
V(js_finalization_registry_remove_cell_from_unregister_token_map, \
"JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap") \
V(re_match_for_call_from_js, "IrregexpInterpreter::MatchForCallFromJs") \

View File

@ -320,6 +320,36 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Zone* zone_;
};
#ifdef V8_IS_TSAN
class OutOfLineTSANWrite final : public OutOfLineCode {
public:
OutOfLineTSANWrite(CodeGenerator* gen, Operand operand, Register value)
: OutOfLineCode(gen),
operand_(operand),
value_(value),
zone_(gen->zone()) {}
void Generate() final {
const SaveFPRegsMode save_fp_mode = frame()->DidAllocateDoubleRegisters()
? SaveFPRegsMode::kSave
: SaveFPRegsMode::kIgnore;
const int number_of_args = 2;
__ PushCallerSaved(save_fp_mode);
__ PrepareCallCFunction(number_of_args);
__ leaq(arg_reg_1, operand_);
__ movq(arg_reg_2, value_);
__ CallCFunction(ExternalReference::tsan_relaxed_store_function(),
number_of_args);
__ PopCallerSaved(save_fp_mode);
}
private:
Operand const operand_;
Register const value_;
Zone* zone_;
};
#endif // V8_IS_TSAN
#if V8_ENABLE_WEBASSEMBLY
class WasmOutOfLineTrap : public OutOfLineCode {
public:
@ -1184,6 +1214,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
Register value = i.InputRegister(index);
#ifdef V8_IS_TSAN
auto tsan_ool = zone()->New<OutOfLineTSANWrite>(this, operand, value);
__ jmp(tsan_ool->entry());
__ bind(tsan_ool->exit());
#endif // V8_IS_TSAN
Register scratch0 = i.TempRegister(0);
Register scratch1 = i.TempRegister(1);
auto ool = zone()->New<OutOfLineRecordWrite>(this, object, operand, value,