Commit 59d158d0 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by V8 LUCI CQ

[codegen] Use separate TSANRelaxedStore stubs

Inline the SaveFPMode flag directly into the TSANRelaxedStore stubs:
 - Saves one register for input arguments
 - Avoid branches in the TSANRelaxedStore stubs

Bug: v8:7790, v8:11600
Change-Id: Ib1083f8c1a7e856028ff606ba8c2a93efb10db69
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2917037Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74781}
parent 72adfb0d
...@@ -41,7 +41,8 @@ namespace internal { ...@@ -41,7 +41,8 @@ namespace internal {
TFC(EphemeronKeyBarrierIgnoreFP, WriteBarrier) \ TFC(EphemeronKeyBarrierIgnoreFP, WriteBarrier) \
\ \
/* TSAN support for tagged stores in generated code.*/ \ /* TSAN support for tagged stores in generated code.*/ \
IF_TSAN(TFC, TSANRelaxedStore, TSANRelaxedStore) \ IF_TSAN(TFC, TSANRelaxedStoreIgnoreFP, TSANRelaxedStore) \
IF_TSAN(TFC, TSANRelaxedStoreSaveFP, TSANRelaxedStore) \
\ \
/* Adaptor for CPP builtin */ \ /* Adaptor for CPP builtin */ \
TFC(AdaptorWithBuiltinExitFrame, CppBuiltinAdaptor) \ TFC(AdaptorWithBuiltinExitFrame, CppBuiltinAdaptor) \
......
...@@ -414,41 +414,32 @@ class TSANRelaxedStoreCodeStubAssembler : public CodeStubAssembler { ...@@ -414,41 +414,32 @@ class TSANRelaxedStoreCodeStubAssembler : public CodeStubAssembler {
explicit TSANRelaxedStoreCodeStubAssembler( explicit TSANRelaxedStoreCodeStubAssembler(
compiler::CodeAssemblerState* state) compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {} : CodeStubAssembler(state) {}
TNode<BoolT> ShouldSkipFPRegs(TNode<Smi> mode) {
return TaggedEqual(mode, SmiConstant(SaveFPRegsMode::kIgnore));
}
}; };
TF_BUILTIN(TSANRelaxedStore, TSANRelaxedStoreCodeStubAssembler) { TF_BUILTIN(TSANRelaxedStoreIgnoreFP, TSANRelaxedStoreCodeStubAssembler) {
Label exit(this);
TNode<ExternalReference> function = TNode<ExternalReference> function =
ExternalConstant(ExternalReference::tsan_relaxed_store_function()); ExternalConstant(ExternalReference::tsan_relaxed_store_function());
auto address = UncheckedParameter<IntPtrT>(Descriptor::kAddress); auto address = UncheckedParameter<IntPtrT>(Descriptor::kAddress);
TNode<IntPtrT> value = TNode<IntPtrT> value =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kValue)); BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kValue));
auto fp_mode = UncheckedParameter<Smi>(Descriptor::kFPMode);
Label dont_save_fp(this), save_fp(this);
Branch(ShouldSkipFPRegs(fp_mode), &dont_save_fp, &save_fp);
BIND(&dont_save_fp);
{
CallCFunctionWithCallerSavedRegisters( CallCFunctionWithCallerSavedRegisters(
function, MachineType::Int32(), SaveFPRegsMode::kIgnore, function, MachineType::Int32(), SaveFPRegsMode::kIgnore,
std::make_pair(MachineType::IntPtr(), address), std::make_pair(MachineType::IntPtr(), address),
std::make_pair(MachineType::IntPtr(), value)); std::make_pair(MachineType::IntPtr(), value));
Goto(&exit); Return(UndefinedConstant());
} }
BIND(&save_fp); TF_BUILTIN(TSANRelaxedStoreSaveFP, TSANRelaxedStoreCodeStubAssembler) {
{ TNode<ExternalReference> function =
ExternalConstant(ExternalReference::tsan_relaxed_store_function());
auto address = UncheckedParameter<IntPtrT>(Descriptor::kAddress);
TNode<IntPtrT> value =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kValue));
CallCFunctionWithCallerSavedRegisters( CallCFunctionWithCallerSavedRegisters(
function, MachineType::Int32(), SaveFPRegsMode::kSave, function, MachineType::Int32(), SaveFPRegsMode::kSave,
std::make_pair(MachineType::IntPtr(), address), std::make_pair(MachineType::IntPtr(), address),
std::make_pair(MachineType::IntPtr(), value)); std::make_pair(MachineType::IntPtr(), value));
Goto(&exit); Return(UndefinedConstant());
}
BIND(&exit);
Return(TrueConstant());
} }
#endif // V8_IS_TSAN #endif // V8_IS_TSAN
......
...@@ -113,6 +113,14 @@ class Builtins { ...@@ -113,6 +113,14 @@ class Builtins {
} }
} }
#ifdef V8_IS_TSAN
static Name GetTSANRelaxedStoreStub(SaveFPRegsMode fp_mode) {
return fp_mode == SaveFPRegsMode::kIgnore
? Builtins::kTSANRelaxedStoreIgnoreFP
: Builtins::kTSANRelaxedStoreSaveFP;
}
#endif // V8_IS_TSAN
// Convenience wrappers. // Convenience wrappers.
Handle<Code> CallFunction(ConvertReceiverMode = ConvertReceiverMode::kAny); Handle<Code> CallFunction(ConvertReceiverMode = ConvertReceiverMode::kAny);
Handle<Code> Call(ConvertReceiverMode = ConvertReceiverMode::kAny); Handle<Code> Call(ConvertReceiverMode = ConvertReceiverMode::kAny);
......
...@@ -1008,10 +1008,9 @@ class WriteBarrierDescriptor final ...@@ -1008,10 +1008,9 @@ class WriteBarrierDescriptor final
class TSANRelaxedStoreDescriptor final class TSANRelaxedStoreDescriptor final
: public StaticCallInterfaceDescriptor<TSANRelaxedStoreDescriptor> { : public StaticCallInterfaceDescriptor<TSANRelaxedStoreDescriptor> {
public: public:
DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kValue, kFPMode) DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kValue)
DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kAddress DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kAddress
MachineType::AnyTagged(), // kValue MachineType::AnyTagged()) // kValue
MachineType::TaggedSigned()) // kFPMode
DECLARE_DESCRIPTOR(TSANRelaxedStoreDescriptor) DECLARE_DESCRIPTOR(TSANRelaxedStoreDescriptor)
......
...@@ -27,7 +27,7 @@ constexpr auto WriteBarrierDescriptor::registers() { ...@@ -27,7 +27,7 @@ constexpr auto WriteBarrierDescriptor::registers() {
#ifdef V8_IS_TSAN #ifdef V8_IS_TSAN
// static // static
constexpr auto TSANRelaxedStoreDescriptor::registers() { constexpr auto TSANRelaxedStoreDescriptor::registers() {
return RegisterArray(arg_reg_1, arg_reg_2, arg_reg_3, kReturnRegister0); return RegisterArray(arg_reg_1, arg_reg_2, kReturnRegister0);
} }
#endif // V8_IS_TSAN #endif // V8_IS_TSAN
......
...@@ -473,7 +473,8 @@ void TurboAssembler::CallRecordWriteStub( ...@@ -473,7 +473,8 @@ void TurboAssembler::CallRecordWriteStub(
#ifdef V8_IS_TSAN #ifdef V8_IS_TSAN
void TurboAssembler::CallTSANRelaxedStoreStub(Register address, Register value, void TurboAssembler::CallTSANRelaxedStoreStub(Register address, Register value,
SaveFPRegsMode fp_mode, SaveFPRegsMode fp_mode,
Address wasm_target) { StubCallMode mode) {
DCHECK(!AreAliased(address, value));
TSANRelaxedStoreDescriptor descriptor; TSANRelaxedStoreDescriptor descriptor;
RegList registers = descriptor.allocatable_registers(); RegList registers = descriptor.allocatable_registers();
...@@ -483,22 +484,20 @@ void TurboAssembler::CallTSANRelaxedStoreStub(Register address, Register value, ...@@ -483,22 +484,20 @@ void TurboAssembler::CallTSANRelaxedStoreStub(Register address, Register value,
descriptor.GetRegisterParameter(TSANRelaxedStoreDescriptor::kAddress)); descriptor.GetRegisterParameter(TSANRelaxedStoreDescriptor::kAddress));
Register value_parameter( Register value_parameter(
descriptor.GetRegisterParameter(TSANRelaxedStoreDescriptor::kValue)); descriptor.GetRegisterParameter(TSANRelaxedStoreDescriptor::kValue));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(TSANRelaxedStoreDescriptor::kFPMode));
// Prepare argument registers for calling RecordWrite // Prepare argument registers for calling RecordWrite
// address_parameter <= address // address_parameter <= address
// value_parameter <= value // value_parameter <= value
MovePair(address_parameter, address, value_parameter, value); MovePair(address_parameter, address, value_parameter, value);
// fp_mode_parameter <= fp_mode
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (wasm_target != kNullAddress) { if (mode == StubCallMode::kCallWasmRuntimeStub) {
// Use {near_call} for direct Wasm call within a module. // Use {near_call} for direct Wasm call within a module.
auto wasm_target = wasm::WasmCode::GetTSANRelaxedStoreStub(fp_mode);
near_call(wasm_target, RelocInfo::WASM_STUB_CALL); near_call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else { } else {
auto builtin_index = Builtins::GetTSANRelaxedStoreStub(fp_mode);
Handle<Code> code_target = Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kTSANRelaxedStore); isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET); Call(code_target, RelocInfo::CODE_TARGET);
} }
......
...@@ -513,9 +513,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler { ...@@ -513,9 +513,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
StubCallMode mode = StubCallMode::kCallBuiltinPointer); StubCallMode mode = StubCallMode::kCallBuiltinPointer);
#ifdef V8_IS_TSAN #ifdef V8_IS_TSAN
void CallTSANRelaxedStoreStub(Register address, Register value, void CallTSANRelaxedStoreStub(
SaveFPRegsMode fp_mode, Register address, Register value, SaveFPRegsMode fp_mode,
Address wasm_target = kNullAddress); StubCallMode mode = StubCallMode::kCallBuiltinPointer);
#endif // V8_IS_TSAN #endif // V8_IS_TSAN
void MoveNumber(Register dst, double value); void MoveNumber(Register dst, double value);
......
...@@ -335,6 +335,7 @@ class OutOfLineTSANRelaxedStore final : public OutOfLineCode { ...@@ -335,6 +335,7 @@ class OutOfLineTSANRelaxedStore final : public OutOfLineCode {
stub_mode_(stub_mode), stub_mode_(stub_mode),
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
zone_(gen->zone()) { zone_(gen->zone()) {
DCHECK(!AreAliased(value, scratch0));
} }
void Generate() final { void Generate() final {
...@@ -349,7 +350,7 @@ class OutOfLineTSANRelaxedStore final : public OutOfLineCode { ...@@ -349,7 +350,7 @@ class OutOfLineTSANRelaxedStore final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code // Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space. // is added to the native module and copied into wasm code space.
__ CallTSANRelaxedStoreStub(scratch0_, value_, save_fp_mode, __ CallTSANRelaxedStoreStub(scratch0_, value_, save_fp_mode,
wasm::WasmCode::kTSANRelaxedStore); StubCallMode::kCallWasmRuntimeStub);
return; return;
} }
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
......
...@@ -1054,7 +1054,8 @@ static bool TransitivelyCalledBuiltinHasNoSideEffect(Builtins::Name caller, ...@@ -1054,7 +1054,8 @@ static bool TransitivelyCalledBuiltinHasNoSideEffect(Builtins::Name caller,
case Builtins::kToObject: case Builtins::kToObject:
case Builtins::kToString: case Builtins::kToString:
#ifdef V8_IS_TSAN #ifdef V8_IS_TSAN
case Builtins::kTSANRelaxedStore: case Builtins::kTSANRelaxedStoreIgnoreFP:
case Builtins::kTSANRelaxedStoreSaveFP:
#endif // V8_IS_TSAN #endif // V8_IS_TSAN
case Builtins::kWeakMapLookupHashIndex: case Builtins::kWeakMapLookupHashIndex:
return true; return true;
......
...@@ -95,7 +95,8 @@ struct WasmModule; ...@@ -95,7 +95,8 @@ struct WasmModule;
V(RecordWriteEmitRememberedSetIgnoreFP) \ V(RecordWriteEmitRememberedSetIgnoreFP) \
V(RecordWriteOmitRememberedSetIgnoreFP) \ V(RecordWriteOmitRememberedSetIgnoreFP) \
V(ToNumber) \ V(ToNumber) \
IF_TSAN(V, TSANRelaxedStore) \ IF_TSAN(V, TSANRelaxedStoreIgnoreFP) \
IF_TSAN(V, TSANRelaxedStoreSaveFP) \
V(WasmAllocateArrayWithRtt) \ V(WasmAllocateArrayWithRtt) \
V(WasmAllocateRtt) \ V(WasmAllocateRtt) \
V(WasmAllocateStructWithRtt) \ V(WasmAllocateStructWithRtt) \
...@@ -172,6 +173,14 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -172,6 +173,14 @@ class V8_EXPORT_PRIVATE WasmCode final {
} }
} }
#ifdef V8_IS_TSAN
static RuntimeStubId GetTSANRelaxedStoreStub(SaveFPRegsMode fp_mode) {
return fp_mode == SaveFPRegsMode::kIgnore
? RuntimeStubId::kTSANRelaxedStoreIgnoreFP
: RuntimeStubId::kTSANRelaxedStoreSaveFP;
}
#endif // V8_IS_TSAN
Vector<byte> instructions() const { Vector<byte> instructions() const {
return VectorOf(instructions_, static_cast<size_t>(instructions_size_)); return VectorOf(instructions_, static_cast<size_t>(instructions_size_));
} }
......
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