[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:
committed by
Commit Queue
parent
c111a1346e
commit
58bf203064
@@ -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.
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user