Commit 2c096b53 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by V8 LUCI CQ

[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/+/2848470Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74568}
parent 9905c0b3
......@@ -601,6 +601,7 @@ external_v8_defines = [
"V8_NO_ARGUMENTS_ADAPTOR",
"V8_USE_PERFETTO",
"V8_MAP_PACKING",
"V8_IS_TSAN",
]
enabled_external_v8_defines = []
......@@ -637,6 +638,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
......
......@@ -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_
......@@ -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));
......
......@@ -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") \
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment