[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 <rmacnak@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ryan Macnak
2024-01-17 13:50:49 +00:00
committed by Commit Queue
parent c111a1346e
commit 58bf203064
14 changed files with 135 additions and 21 deletions
@@ -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);
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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.
@@ -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.
@@ -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.
@@ -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.
{
+2
View File
@@ -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();
-21
View File
@@ -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<const EnumListParameter*>(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;