From 58bf2030647e40ce7351f07ee6dbc24e97fe540f Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Wed, 17 Jan 2024 13:50:49 +0000 Subject: [PATCH] [VM] Add support for allocation tracing in AOT TEST=Manual Bug: https://github.com/dart-lang/sdk/issues/51234 Change-Id: I4ab75bb85898a41dfb091b38402711170fd3b972 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/271420 Reviewed-by: Ryan Macnak Commit-Queue: Ben Konyi --- .../vm/compiler/assembler/assembler_arm.cc | 22 +++++++++++++++++++ runtime/vm/compiler/assembler/assembler_arm.h | 6 +++++ .../vm/compiler/assembler/assembler_arm64.cc | 17 ++++++++++++++ .../vm/compiler/assembler/assembler_arm64.h | 5 +++++ .../vm/compiler/assembler/assembler_riscv.cc | 16 ++++++++++++++ .../vm/compiler/assembler/assembler_riscv.h | 5 +++++ .../vm/compiler/assembler/assembler_x64.cc | 22 +++++++++++++++++++ runtime/vm/compiler/assembler/assembler_x64.h | 5 +++++ runtime/vm/compiler/stub_code_compiler_arm.cc | 10 +++++++++ .../vm/compiler/stub_code_compiler_arm64.cc | 10 +++++++++ .../vm/compiler/stub_code_compiler_riscv.cc | 8 +++++++ runtime/vm/compiler/stub_code_compiler_x64.cc | 7 ++++++ runtime/vm/object.cc | 2 ++ runtime/vm/service.cc | 21 ------------------ 14 files changed, 135 insertions(+), 21 deletions(-) diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc index d5bdb539584..a4877c9dedb 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.cc +++ b/runtime/vm/compiler/assembler/assembler_arm.cc @@ -3590,6 +3590,28 @@ void Assembler::MaybeTraceAllocation(intptr_t cid, MaybeTraceAllocation(temp_reg, trace); } +void Assembler::MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance) { + LoadAllocationTracingStateAddress(temp_reg, cid); + MaybeTraceAllocation(temp_reg, trace); +} + +void Assembler::LoadAllocationTracingStateAddress(Register dest, Register cid) { + ASSERT(dest != kNoRegister); + ASSERT(dest != TMP); + + LoadIsolateGroup(dest); + ldr(dest, Address(dest, target::IsolateGroup::class_table_offset())); + ldr(dest, + Address(dest, + target::ClassTable::allocation_tracing_state_table_offset())); + AddScaled(cid, cid, TIMES_1, + target::ClassTable::AllocationTracingStateSlotOffsetFor(0)); + AddRegisters(dest, cid); +} + void Assembler::LoadAllocationTracingStateAddress(Register dest, intptr_t cid) { ASSERT(dest != kNoRegister); ASSERT(dest != TMP); diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h index 4f574945520..5571bca5e0f 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.h +++ b/runtime/vm/compiler/assembler/assembler_arm.h @@ -1493,6 +1493,7 @@ class Assembler : public AssemblerBase { // These are separate assembler macros so we can avoid a dependent load too // nearby the load of the table address. void LoadAllocationTracingStateAddress(Register dest, intptr_t cid); + void LoadAllocationTracingStateAddress(Register dest, Register cid); // If true is returned, then the out parameter [need_base] signifies whether // a register is needed for storing the array base (which should be passed @@ -1575,6 +1576,11 @@ class Assembler : public AssemblerBase { Register temp_reg, JumpDistance distance = JumpDistance::kFarJump); + void MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance = JumpDistance::kFarJump); + void TryAllocateObject(intptr_t cid, intptr_t instance_size, Label* failure, diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc index 42b081b2ccf..266ff65a883 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.cc +++ b/runtime/vm/compiler/assembler/assembler_arm64.cc @@ -2050,6 +2050,23 @@ void Assembler::MaybeTraceAllocation(intptr_t cid, kUnsignedByte); cbnz(trace, temp_reg); } + +void Assembler::MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance) { + ASSERT(temp_reg != cid); + LoadIsolateGroup(temp_reg); + ldr(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset())); + ldr(temp_reg, + Address(temp_reg, + target::ClassTable::allocation_tracing_state_table_offset())); + AddRegisters(temp_reg, cid); + LoadFromOffset(temp_reg, temp_reg, + target::ClassTable::AllocationTracingStateSlotOffsetFor(0), + kUnsignedByte); + cbnz(trace, temp_reg); +} #endif // !PRODUCT void Assembler::TryAllocateObject(intptr_t cid, diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h index 132073f0162..3c1ee260fa4 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.h +++ b/runtime/vm/compiler/assembler/assembler_arm64.h @@ -2297,6 +2297,11 @@ class Assembler : public AssemblerBase { Register temp_reg, JumpDistance distance = JumpDistance::kFarJump); + void MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance = JumpDistance::kFarJump); + void TryAllocateObject(intptr_t cid, intptr_t instance_size, Label* failure, diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc index 96d6fbd289b..8fbc969bd31 100644 --- a/runtime/vm/compiler/assembler/assembler_riscv.cc +++ b/runtime/vm/compiler/assembler/assembler_riscv.cc @@ -4420,6 +4420,22 @@ void Assembler::FinalizeHashForSize(intptr_t bit_size, } #ifndef PRODUCT +void Assembler::MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance) { + LoadIsolateGroup(temp_reg); + lx(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset())); + lx(temp_reg, + Address(temp_reg, + target::ClassTable::allocation_tracing_state_table_offset())); + add(temp_reg, temp_reg, cid); + LoadFromOffset(temp_reg, temp_reg, + target::ClassTable::AllocationTracingStateSlotOffsetFor(0), + kUnsignedByte); + bnez(temp_reg, trace); +} + void Assembler::MaybeTraceAllocation(intptr_t cid, Label* trace, Register temp_reg, diff --git a/runtime/vm/compiler/assembler/assembler_riscv.h b/runtime/vm/compiler/assembler/assembler_riscv.h index 0e074ad54ea..756d5f9be05 100644 --- a/runtime/vm/compiler/assembler/assembler_riscv.h +++ b/runtime/vm/compiler/assembler/assembler_riscv.h @@ -1486,6 +1486,11 @@ class Assembler : public MicroAssembler { Register temp_reg, JumpDistance distance = JumpDistance::kFarJump); + void MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance = JumpDistance::kFarJump); + void TryAllocateObject(intptr_t cid, intptr_t instance_size, Label* failure, diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc index b7a70003f64..4594100d46a 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.cc +++ b/runtime/vm/compiler/assembler/assembler_x64.cc @@ -2353,6 +2353,28 @@ void Assembler::FinalizeHashForSize(intptr_t bit_size, } #ifndef PRODUCT +void Assembler::MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg, + JumpDistance distance) { + if (temp_reg == kNoRegister) { + temp_reg = TMP; + } + ASSERT(temp_reg != cid); + LoadIsolateGroup(temp_reg); + movq(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset())); + + movq(temp_reg, + Address(temp_reg, + target::ClassTable::allocation_tracing_state_table_offset())); + cmpb(Address(temp_reg, cid, TIMES_1, + target::ClassTable::AllocationTracingStateSlotOffsetFor(0)), + Immediate(0)); + // We are tracing for this class, jump to the trace label which will use + // the allocation stub. + j(NOT_ZERO, trace, distance); +} + void Assembler::MaybeTraceAllocation(intptr_t cid, Label* trace, Register temp_reg, diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h index b28b0a3f770..be444c98fce 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.h +++ b/runtime/vm/compiler/assembler/assembler_x64.h @@ -1356,6 +1356,11 @@ class Assembler : public AssemblerBase { Register temp_reg = kNoRegister, JumpDistance distance = JumpDistance::kFarJump); + void MaybeTraceAllocation(Register cid, + Label* trace, + Register temp_reg = kNoRegister, + JumpDistance distance = JumpDistance::kFarJump); + void TryAllocateObject(intptr_t cid, intptr_t instance_size, Label* failure, diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc index 4ec132ddcd2..aff561ec268 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm.cc @@ -1844,6 +1844,16 @@ static void GenerateAllocateObjectHelper(Assembler* assembler, { Label slow_case; +#if !defined(PRODUCT) + { + const Register kTraceAllocationTempReg = R8; + const Register kCidRegister = R9; + __ ExtractClassIdFromTags(kCidRegister, AllocateObjectABI::kTagsReg); + __ MaybeTraceAllocation(kCidRegister, &slow_case, + kTraceAllocationTempReg); + } +#endif + const Register kNewTopReg = R8; // Bump allocation. diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc index 6a558254088..c50a4e47595 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm64.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc @@ -2155,6 +2155,16 @@ static void GenerateAllocateObjectHelper(Assembler* assembler, { Label slow_case; +#if !defined(PRODUCT) + { + const Register kTraceAllocationTempReg = R8; + const Register kCidRegister = R9; + __ ExtractClassIdFromTags(kCidRegister, AllocateObjectABI::kTagsReg); + __ MaybeTraceAllocation(kCidRegister, &slow_case, + kTraceAllocationTempReg); + } +#endif + const Register kNewTopReg = R3; // Bump allocation. diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc index 4e483b46cb5..534560dac97 100644 --- a/runtime/vm/compiler/stub_code_compiler_riscv.cc +++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc @@ -1949,6 +1949,14 @@ static void GenerateAllocateObjectHelper(Assembler* assembler, { Label slow_case; +#if !defined(PRODUCT) + { + const Register kCidRegister = TMP2; + __ ExtractClassIdFromTags(kCidRegister, AllocateObjectABI::kTagsReg); + __ MaybeTraceAllocation(kCidRegister, &slow_case, TMP); + } +#endif + const Register kNewTopReg = T3; // Bump allocation. diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc index 5b9ccb581d7..69b714ee481 100644 --- a/runtime/vm/compiler/stub_code_compiler_x64.cc +++ b/runtime/vm/compiler/stub_code_compiler_x64.cc @@ -2085,6 +2085,13 @@ static void GenerateAllocateObjectHelper(Assembler* assembler, Label slow_case; const Register kNewTopReg = R9; +#if !defined(PRODUCT) + { + const Register kCidRegister = RSI; + __ ExtractClassIdFromTags(kCidRegister, AllocateObjectABI::kTagsReg); + __ MaybeTraceAllocation(kCidRegister, &slow_case, TMP); + } +#endif // Allocate the object and update top to point to // next object start and initialize the allocated object. { diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 0a1e9584b2d..baeffc6031b 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -4515,7 +4515,9 @@ void Class::SetTraceAllocation(bool trace_allocation) const { if (changed) { auto class_table = isolate_group->class_table(); class_table->SetTraceAllocationFor(id(), trace_allocation); +#ifdef TARGET_ARCH_IA32 DisableAllocationStub(); +#endif } #else UNREACHABLE(); diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc index 8994704394d..20cdcd195a8 100644 --- a/runtime/vm/service.cc +++ b/runtime/vm/service.cc @@ -522,15 +522,6 @@ static bool CheckDebuggerDisabled(Thread* thread, JSONStream* js) { #endif } -static bool CheckCompilerDisabled(Thread* thread, JSONStream* js) { -#if defined(DART_PRECOMPILED_RUNTIME) - js->PrintError(kFeatureDisabled, "Compiler is disabled in AOT mode."); - return true; -#else - return false; -#endif -} - static bool CheckProfilerDisabled(Thread* thread, JSONStream* js) { if (!FLAG_profiler) { js->PrintError(kFeatureDisabled, "Profiler is disabled."); @@ -3740,10 +3731,6 @@ static void GetSourceReport(Thread* thread, JSONStream* js) { #if defined(DART_PRECOMPILED_RUNTIME) js->PrintError(kFeatureDisabled, "disabled in AOT mode and PRODUCT."); #else - if (CheckCompilerDisabled(thread, js)) { - return; - } - char* reports_str = Utils::StrDup(js->LookupParam("reports")); const EnumListParameter* reports_parameter = static_cast(get_source_report_params[1]); @@ -3854,10 +3841,6 @@ static void ReloadSources(Thread* thread, JSONStream* js) { #if defined(DART_PRECOMPILED_RUNTIME) js->PrintError(kFeatureDisabled, "Compiler is disabled in AOT mode."); #else - if (CheckCompilerDisabled(thread, js)) { - return; - } - IsolateGroup* isolate_group = thread->isolate_group(); if (isolate_group->library_tag_handler() == nullptr) { js->PrintError(kFeatureDisabled, @@ -5762,10 +5745,6 @@ static const MethodParameter* const set_trace_class_allocation_params[] = { }; static void SetTraceClassAllocation(Thread* thread, JSONStream* js) { - if (CheckCompilerDisabled(thread, js)) { - return; - } - const char* class_id = js->LookupParam("classId"); const bool enable = BoolParameter::Parse(js->LookupParam("enable")); intptr_t cid = -1;