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:
parent
6156aecd3a
commit
4f41eb1a6e
4
BUILD.gn
4
BUILD.gn
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user