[ VM ] Move class name from heap profiler report callback to allocation callback

Moving the class name of the allocated object to the allocation callback
gives more flexibility to the embedder, which may decide to track all
sampled allocations, not just those that are still alive.

TEST=Updated DartAPI_HeapSampling_*

Change-Id: Iaae290e15b67ca3e47d72e1896fa6e32b2d4b081
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/297761
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2023-04-25 13:02:49 +00:00 committed by Commit Queue
parent 96a346fc5e
commit 8d97964e6e
6 changed files with 18 additions and 22 deletions

View file

@ -1282,12 +1282,12 @@ DART_EXPORT void Dart_KillIsolate(Dart_Isolate isolate);
DART_EXPORT void Dart_NotifyIdle(int64_t deadline);
typedef void (*Dart_HeapSamplingReportCallback)(void* context,
const char* cls_name,
void* data);
typedef void* (*Dart_HeapSamplingCreateCallback)(
Dart_Isolate isolate,
Dart_IsolateGroup isolate_group,
const char* cls_name,
intptr_t allocation_size);
typedef void (*Dart_HeapSamplingDeleteCallback)(void* data);

View file

@ -10507,30 +10507,29 @@ TEST_CASE(DartAPI_UserTags) {
#endif // !PRODUCT
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
static void* last_allocation_context = nullptr;
static const char* last_allocation_cls = nullptr;
static intptr_t heap_samples = 0;
static const char* expected_allocation_cls = nullptr;
static bool found_allocation = false;
static void* HeapSamplingCreate(Dart_Isolate isolate,
Dart_IsolateGroup isolate_group,
const char* cls_name,
intptr_t heap_size) {
return strdup("test data");
last_allocation_cls = cls_name;
return strdup(cls_name);
}
static void HeapSamplingDelete(void* data) {
free(data);
}
static void* last_allocation_context = nullptr;
static const char* last_allocation_cls = nullptr;
static void* last_allocation_data = nullptr;
static intptr_t heap_samples = 0;
static const char* expected_allocation_cls = nullptr;
static bool found_allocation = false;
void HeapSamplingReport(void* context,
const char* cls_name,
void* data) {
last_allocation_context = context;
last_allocation_cls = cls_name;
last_allocation_data = data;
if (strcmp(cls_name, expected_allocation_cls) == 0) {
if (strcmp(reinterpret_cast<char*>(data), expected_allocation_cls) == 0) {
found_allocation = true;
}
heap_samples++;
@ -10542,7 +10541,6 @@ void ResetHeapSamplingState(const char* expected_cls = nullptr) {
found_allocation = false;
last_allocation_context = nullptr;
last_allocation_cls = nullptr;
last_allocation_data = nullptr;
}
// Threads won't pick up heap sampling profiler state changes until they
@ -10596,7 +10594,6 @@ TEST_CASE(DartAPI_HeapSampling_UserDefinedClass) {
EXPECT(heap_samples < 100000);
EXPECT(last_allocation_context == context);
EXPECT(found_allocation);
EXPECT_STREQ(reinterpret_cast<char*>(last_allocation_data), "test data");
Dart_EnterIsolate(isolate);
}

View file

@ -197,14 +197,15 @@ void HeapProfileSampler::HandleNewTLAB(intptr_t old_tlab_remaining_space,
}
}
void* HeapProfileSampler::InvokeCallbackForLastSample() {
void* HeapProfileSampler::InvokeCallbackForLastSample(intptr_t cid) {
ASSERT(enabled_);
ASSERT(create_callback_ != nullptr);
ReadRwLocker locker(thread_, lock_);
ClassTable* table = IsolateGroup::Current()->class_table();
void* result = create_callback_(
reinterpret_cast<Dart_Isolate>(thread_->isolate()),
reinterpret_cast<Dart_IsolateGroup>(thread_->isolate_group()),
last_sample_size_);
table->UserVisibleNameFor(cid), last_sample_size_);
last_sample_size_ = kUninitialized;
return result;
}

View file

@ -118,7 +118,7 @@ class HeapProfileSampler {
// allocations.
void HandleNewTLAB(intptr_t old_tlab_remaining_space, bool is_first_tlab);
void* InvokeCallbackForLastSample();
void* InvokeCallbackForLastSample(intptr_t cid);
bool HasOutstandingSample() const {
return last_sample_size_ != kUninitialized;

View file

@ -144,13 +144,11 @@ void WeakTable::Forward(ObjectPointerVisitor* visitor) {
void WeakTable::ReportSurvivingAllocations(
Dart_HeapSamplingReportCallback callback,
void* context) {
ClassTable* table = IsolateGroup::Current()->class_table();
MutexLocker ml(&mutex_);
for (intptr_t i = 0; i < size_; i++) {
if (IsValidEntryAtExclusive(i)) {
ObjectPtr obj = static_cast<ObjectPtr>(data_[ObjectIndex(i)]);
void* data = reinterpret_cast<void*>(data_[ValueIndex(i)]);
callback(context, table->UserVisibleNameFor(obj->GetClassId()), data);
callback(context, data);
}
}
}

View file

@ -2833,7 +2833,7 @@ ObjectPtr Object::Allocate(intptr_t cls_id,
HeapProfileSampler& heap_sampler = thread->heap_sampler();
if (heap_sampler.HasOutstandingSample()) {
thread->IncrementNoCallbackScopeDepth();
void* data = heap_sampler.InvokeCallbackForLastSample();
void* data = heap_sampler.InvokeCallbackForLastSample(cls_id);
heap->SetHeapSamplingData(raw_obj, data);
thread->DecrementNoCallbackScopeDepth();
}