[vm] Fix quadratic cost of SNAPSHOT_BACKTRACE.

Observed this taking ~16% of debug gen_snapshot time.
Observed this taking ~52% of debug AppJIT training time.

TEST=ci
Change-Id: I945e4f3a8794e607e1402150a10f0d328fa1e677
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506260
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
Ryan Macnak
2026-05-26 09:40:40 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent c5d547fdb8
commit e04d2179a1
5 changed files with 35 additions and 17 deletions
+11 -13
View File
@@ -636,7 +636,6 @@ class Serializer : public ThreadStackResource {
#if defined(SNAPSHOT_BACKTRACE)
ObjectPtr current_parent_;
GrowableArray<Object*> parent_pairs_;
#endif
#if defined(DART_PRECOMPILER)
@@ -7754,8 +7753,7 @@ Serializer::Serializer(Thread* thread,
profile_writer_(profile_writer)
#if defined(SNAPSHOT_BACKTRACE)
,
current_parent_(Object::null()),
parent_pairs_()
current_parent_(Object::null())
#endif
#if defined(DART_PRECOMPILER)
,
@@ -8759,8 +8757,7 @@ void Serializer::Push(ObjectPtr object, intptr_t cid_override) {
num_written_objects_++;
}
#if defined(SNAPSHOT_BACKTRACE)
parent_pairs_.Add(&Object::Handle(zone_, object));
parent_pairs_.Add(&Object::Handle(zone_, current_parent_));
heap()->SetSnapshotParent(object, &Object::Handle(zone_, current_parent_));
#endif
}
}
@@ -8851,19 +8848,17 @@ void Serializer::UnexpectedObject(ObjectPtr raw_object, const char* message) {
#if defined(SNAPSHOT_BACKTRACE)
ObjectPtr Serializer::ParentOf(ObjectPtr object) const {
for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
if (parent_pairs_[i]->ptr() == object) {
return parent_pairs_[i + 1]->ptr();
}
Object* parent = heap()->GetSnapshotParent(object);
if (parent != nullptr) {
return parent->ptr();
}
return Object::null();
}
ObjectPtr Serializer::ParentOf(const Object& object) const {
for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
if (parent_pairs_[i]->ptr() == object.ptr()) {
return parent_pairs_[i + 1]->ptr();
}
Object* parent = heap()->GetSnapshotParent(object.ptr());
if (parent != nullptr) {
return parent->ptr();
}
return Object::null();
}
@@ -9104,6 +9099,9 @@ ZoneGrowableArray<Object*>* Serializer::Serialize(SerializationRoots* roots) {
PrintSnapshotSizes();
heap()->ResetObjectIdTable();
#if defined(SNAPSHOT_BACKTRACE)
heap()->ResetSnapshotParentTable();
#endif
return objects_;
}
+4
View File
@@ -149,6 +149,10 @@ const intptr_t kDefaultNewGenSemiMaxSize = (kWordSize <= 4) ? 8 : 16;
#define TARGET_HAS_FAST_WRITE_WRITE_FENCE 1
#define HOST_HAS_FAST_WRITE_WRITE_FENCE 1
#if defined(DEBUG)
#define SNAPSHOT_BACKTRACE
#endif
// The expression OFFSET_OF(type, field) computes the byte-offset of
// the specified field relative to the containing type.
//
+7
View File
@@ -879,6 +879,13 @@ void Heap::ResetObjectIdTable() {
old_weak_tables_[kObjectIds]->Reset();
}
#if defined(SNAPSHOT_BACKTRACE)
void Heap::ResetSnapshotParentTable() {
new_weak_tables_[kSnapshotParents]->Reset();
old_weak_tables_[kSnapshotParents]->Reset();
}
#endif
intptr_t Heap::GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const {
if (raw_obj->IsImmediateOrOldObject()) {
return old_weak_tables_[sel]->GetValue(raw_obj);
+13
View File
@@ -47,6 +47,9 @@ class Heap {
#endif
kCanonicalHashes,
kObjectIds,
#if defined(SNAPSHOT_BACKTRACE)
kSnapshotParents,
#endif
kLoadingUnits,
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
kHeapSamplingData,
@@ -202,6 +205,16 @@ class Heap {
}
void ResetObjectIdTable();
#if defined(SNAPSHOT_BACKTRACE)
void SetSnapshotParent(ObjectPtr obj, Object* parent) {
SetWeakEntry(obj, kSnapshotParents, reinterpret_cast<intptr_t>(parent));
}
Object* GetSnapshotParent(ObjectPtr obj) const {
return reinterpret_cast<Object*>(GetWeakEntry(obj, kSnapshotParents));
}
void ResetSnapshotParentTable();
#endif
void SetLoadingUnit(ObjectPtr raw_obj, intptr_t unit_id) {
ASSERT(Thread::Current()->IsDartMutatorThread());
SetWeakEntry(raw_obj, kLoadingUnits, unit_id);
-4
View File
@@ -22,10 +22,6 @@
#include "vm/type_testing_stubs.h"
#include "vm/v8_snapshot_writer.h"
#if defined(DEBUG)
#define SNAPSHOT_BACKTRACE
#endif
namespace dart {
// Forward declarations.