@@ -4684,6 +4684,30 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
46844684 ASSERT (OffsetInBytes () != 0 || slot ().has_untagged_instance ());
46854685 auto const rep = slot ().representation ();
46864686
4687+ if (!compiler->is_optimizing () && FLAG_target_thread_sanitizer &&
4688+ !slot ().is_no_sanitize_thread () &&
4689+ memory_order () == compiler::Assembler::kRelaxedNonAtomic ) {
4690+ EmitTsanCallUnopt (compiler, this , [&]() -> const RuntimeEntry& {
4691+ intptr_t tag = slot ().has_untagged_instance () ? 0 : kHeapObjectTag ;
4692+ __ AddImmediate (CallingConventions::ArgumentRegisters[0 ], instance_reg,
4693+ slot ().offset_in_bytes () - tag);
4694+ switch (RepresentationUtils::ValueSize (rep)) {
4695+ case 1 :
4696+ return kTsanRead1RuntimeEntry ;
4697+ case 2 :
4698+ return kTsanRead2RuntimeEntry ;
4699+ case 4 :
4700+ return kTsanRead4RuntimeEntry ;
4701+ case 8 :
4702+ return kTsanRead8RuntimeEntry ;
4703+ case 16 :
4704+ return kTsanRead16RuntimeEntry ;
4705+ default :
4706+ UNREACHABLE ();
4707+ }
4708+ });
4709+ }
4710+
46874711 if (calls_initializer ()) {
46884712 __ LoadFromSlot (locs ()->out (0 ).reg (), instance_reg, slot (), memory_order_);
46894713 EmitNativeCodeForInitializerCall (compiler);
@@ -7297,11 +7321,11 @@ static LocationSummary* MakeTsanLocationSummary(Zone* zone,
72977321 return result;
72987322}
72997323
7300- static void EmitTsanNativeCode (
7301- FlowGraphCompiler* compiler ,
7302- LocationSummary* locs ,
7303- std::function< const RuntimeEntry&()> move_parameters) {
7304- const Register saved_sp = locs-> temp ( 0 ). reg ();
7324+ static void EmitTsanCall (FlowGraphCompiler* compiler,
7325+ Instruction* instr ,
7326+ RegisterSet spill_set ,
7327+ Register saved_sp,
7328+ std::function< const RuntimeEntry&()> move_parameters) {
73057329 ASSERT (IsCalleeSavedRegister (saved_sp));
73067330 ASSERT (IsCalleeSavedRegister (THR));
73077331 ASSERT (IsCalleeSavedRegister (PP));
@@ -7316,6 +7340,7 @@ static void EmitTsanNativeCode(
73167340 ASSERT (IsCalleeSavedRegister (DISPATCH_TABLE_REG));
73177341#endif
73187342
7343+ __ PushRegisters (spill_set);
73197344 __ MoveRegister (saved_sp, SPREG);
73207345#if defined(TARGET_ARCH_ARM64)
73217346 __ AndImmediate (CSP, SP, ~(OS::ActivationFrameAlignment () - 1 ));
@@ -7327,13 +7352,40 @@ static void EmitTsanNativeCode(
73277352 __ Store (TMP,
73287353 compiler::Address (THR, compiler::target::Thread::vm_tag_offset ()));
73297354 __ CallCFunction (TMP);
7355+ compiler->AddCurrentDescriptor (UntaggedPcDescriptors::kOther , DeoptId::kNone ,
7356+ instr->source ());
73307357 __ LoadImmediate (TMP, VMTag::kDartTagId );
73317358 __ Store (TMP,
73327359 compiler::Address (THR, compiler::target::Thread::vm_tag_offset ()));
73337360 __ MoveRegister (SPREG, saved_sp);
73347361#if defined(TARGET_ARCH_ARM64)
73357362 __ SetupCSPFromThread (THR);
73367363#endif
7364+ __ PopRegisters (spill_set);
7365+ }
7366+
7367+ static void EmitTsanCall (FlowGraphCompiler* compiler,
7368+ Instruction* instr,
7369+ std::function<const RuntimeEntry&()> move_parameters) {
7370+ EmitTsanCall (compiler, instr, RegisterSet (), instr->locs ()->temp (0 ).reg (),
7371+ move_parameters);
7372+ }
7373+
7374+ void EmitTsanCallUnopt (FlowGraphCompiler* compiler,
7375+ Instruction* instr,
7376+ std::function<const RuntimeEntry&()> move_parameters) {
7377+ intptr_t cpu_reg_mask = 0 ;
7378+ intptr_t fpu_reg_mask = 0 ;
7379+ LocationSummary* locs = instr->locs ();
7380+ for (intptr_t i = 0 , n = locs->input_count (); i < n; i++) {
7381+ if (locs->in (i).IsRegister ()) {
7382+ cpu_reg_mask |= 1 << locs->in (i).reg ();
7383+ } else if (locs->in (i).IsFpuRegister ()) {
7384+ fpu_reg_mask |= 1 << locs->in (i).fpu_reg ();
7385+ }
7386+ }
7387+ EmitTsanCall (compiler, instr, RegisterSet (cpu_reg_mask, fpu_reg_mask),
7388+ CALLEE_SAVED_TEMP, move_parameters);
73377389}
73387390
73397391LocationSummary* TsanFuncEntryExitInstr::MakeLocationSummary (Zone* zone,
@@ -7344,7 +7396,7 @@ LocationSummary* TsanFuncEntryExitInstr::MakeLocationSummary(Zone* zone,
73447396void TsanFuncEntryExitInstr::EmitNativeCode (FlowGraphCompiler* compiler) {
73457397 if (!compiler->flow_graph ().graph_entry ()->NeedsFrame ()) return ;
73467398
7347- EmitTsanNativeCode (compiler, locs () , [&]() -> const RuntimeEntry& {
7399+ EmitTsanCall (compiler, this , [&]() -> const RuntimeEntry& {
73487400 if (kind_ == kEntry ) {
73497401 __ Load (
73507402 CallingConventions::ArgumentRegisters[0 ],
@@ -7364,7 +7416,7 @@ LocationSummary* TsanReadWriteInstr::MakeLocationSummary(Zone* zone,
73647416}
73657417
73667418void TsanReadWriteInstr::EmitNativeCode (FlowGraphCompiler* compiler) {
7367- EmitTsanNativeCode (compiler, locs () , [&]() -> const RuntimeEntry& {
7419+ EmitTsanCall (compiler, this , [&]() -> const RuntimeEntry& {
73687420 const Register instance_reg = locs ()->in (0 ).reg ();
73697421 intptr_t tag = slot ().has_untagged_instance () ? 0 : kHeapObjectTag ;
73707422 __ AddImmediate (CallingConventions::ArgumentRegisters[0 ], instance_reg,
@@ -7413,7 +7465,7 @@ LocationSummary* TsanReadWriteIndexedInstr::MakeLocationSummary(
74137465}
74147466
74157467void TsanReadWriteIndexedInstr::EmitNativeCode (FlowGraphCompiler* compiler) {
7416- EmitTsanNativeCode (compiler, locs () , [&]() -> const RuntimeEntry& {
7468+ EmitTsanCall (compiler, this , [&]() -> const RuntimeEntry& {
74177469 const Register array_reg = locs ()->in (kArrayPos ).reg ();
74187470 Register index_reg = locs ()->in (kIndexPos ).reg ();
74197471
@@ -8022,6 +8074,30 @@ void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
80228074 ASSERT (OffsetInBytes () != 0 || slot ().has_untagged_instance ());
80238075 const Representation rep = slot ().representation ();
80248076
8077+ if (!compiler->is_optimizing () && FLAG_target_thread_sanitizer &&
8078+ !slot ().is_no_sanitize_thread () &&
8079+ memory_order () == compiler::Assembler::kRelaxedNonAtomic ) {
8080+ EmitTsanCallUnopt (compiler, this , [&]() -> const RuntimeEntry& {
8081+ intptr_t tag = slot ().has_untagged_instance () ? 0 : kHeapObjectTag ;
8082+ __ AddImmediate (CallingConventions::ArgumentRegisters[0 ], instance_reg,
8083+ slot ().offset_in_bytes () - tag);
8084+ switch (RepresentationUtils::ValueSize (rep)) {
8085+ case 1 :
8086+ return kTsanWrite1RuntimeEntry ;
8087+ case 2 :
8088+ return kTsanWrite2RuntimeEntry ;
8089+ case 4 :
8090+ return kTsanWrite4RuntimeEntry ;
8091+ case 8 :
8092+ return kTsanWrite8RuntimeEntry ;
8093+ case 16 :
8094+ return kTsanWrite16RuntimeEntry ;
8095+ default :
8096+ UNREACHABLE ();
8097+ }
8098+ });
8099+ }
8100+
80258101#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) || \
80268102 defined (TARGET_ARCH_RISCV64)
80278103 if (locs ()->in (kValuePos ).IsConstant () &&
0 commit comments