18namespace snapshot_analyzer {
31 for (
ObjectPtr* current = first; current <= last; current++) {
32 (*callback_)(*current);
36#if defined(DART_COMPRESSED_POINTERS)
41 (*callback_)(current->Decompress(heap_base));
47 std::function<void(ObjectPtr
object)>* callback_ =
nullptr;
59 void DumpLibrary(
const Library& library);
60 void DumpArray(
const Array& array,
const char*
name);
61 void DumpClass(
const Class& klass);
63 void DumpCode(
const Code& code);
64 void DumpField(
const Field& field);
65 void DumpString(
const String&
string);
66 void DumpInstance(
const Object&
object);
70 void DumpInterestingObjects();
75 const Dart_SnapshotAnalyzerInformation& info_;
81void SnapshotAnalyzer::DumpLibrary(
const Library& library) {
89void SnapshotAnalyzer::DumpArray(
const Array& array,
const char*
name) {
91 for (intptr_t i = 0; i < array.Length(); ++i) {
97void SnapshotAnalyzer::DumpClass(
const Class& klass) {
102 js_.
PrintProperty(
"super_class", GetObjectId(klass.SuperClass()));
104 Zone* zone = thread_->
zone();
110 array = klass.fields();
111 if (!array.IsNull()) {
112 DumpArray(array,
"fields");
115 array = klass.functions();
116 if (!array.IsNull()) {
117 DumpArray(array,
"functions");
120 array = klass.interfaces();
121 if (!array.IsNull()) {
122 DumpArray(array,
"interfaces");
126 if (!library.IsNull()) {
131void SnapshotAnalyzer::DumpFunction(
const Function&
function) {
141 GetObjectId(
function.parent_function()));
145void SnapshotAnalyzer::DumpCode(
const Code& code) {
147 const auto instruction_base =
153 const auto code_addr =
static_cast<uint64_t
>(
code.PayloadStart());
156 if (code_addr == 0) {
159 js_.
PrintProperty(
"section",
"_kDartVmSnapshotInstructions");
163 js_.
PrintProperty(
"section",
"_kDartIsolateSnapshotInstructions");
167void SnapshotAnalyzer::DumpField(
const Field& field) {
171 if (field.is_static()) {
172 js_.
PrintProperty(
"instance", GetObjectId(field.StaticValue()));
174 if (field.HasInitializerFunction()) {
176 GetObjectId(field.InitializerFunction()));
180void SnapshotAnalyzer::DumpString(
const String&
string) {
185void SnapshotAnalyzer::DumpInstance(
const Object&
object) {
193 std::function<void(ObjectPtr)> print_reference = [&](ObjectPtr
value) {
194 if (!
value.IsHeapObject())
return;
195 intptr_t index = GetObjectId(value);
198 visitor.init(&print_reference);
201 object.ptr().untag()->VisitPointers(&visitor);
205void SnapshotAnalyzer::DumpType(
const Type&
type) {
212 for (intptr_t i = 0; i < arguments.Length(); ++i) {
218void SnapshotAnalyzer::DumpObjectPool(
const ObjectPool&
pool) {
221 for (intptr_t i = 0; i <
pool.Length(); ++i) {
222 if (
pool.TypeAt(i) == ObjectPool::EntryType::kTaggedObject) {
232void SnapshotAnalyzer::DumpInterestingObjects() {
233 Zone* zone = thread_->
zone();
236 std::vector<const Object*> discovered_objects;
239 NoSafepointScope ns(thread_);
242 std::function<void(ObjectPtr)> handle_object = [&](ObjectPtr
value) {
243 if (!
value.IsHeapObject())
return;
252 value->untag()->VisitPointers(&visitor);
254 visitor.init(&handle_object);
260 handle_object(
object.ptr());
264 object = GrowableObjectArray::Cast(
object).data();
265 object.ptr().untag()->VisitPointers(&visitor);
269 for (intptr_t
cid = 0;
cid < class_table->NumCids(); ++
cid) {
270 if (!class_table->HasValidClassAt(
cid))
continue;
271 object = class_table->
At(
cid);
272 handle_object(
object.ptr());
285 for (
size_t id = 0;
id < discovered_objects.size(); ++
id) {
286 const auto*
object = discovered_objects[
id];
292 if (object->IsNull()) {
294 }
else if (object->IsLibrary()) {
295 DumpLibrary(Library::Cast(*
object));
296 }
else if (object->IsObjectPool()) {
297 DumpObjectPool(ObjectPool::Cast(*
object));
298 }
else if (object->IsClass()) {
299 DumpClass(Class::Cast(*
object));
300 }
else if (object->IsFunction()) {
301 DumpFunction(Function::Cast(*
object));
302 }
else if (object->IsCode()) {
303 DumpCode(Code::Cast(*
object));
304 }
else if (object->IsField()) {
305 DumpField(Field::Cast(*
object));
306 }
else if (object->IsString()) {
307 DumpString(String::Cast(*
object));
308 }
else if (object->IsArray()) {
311 DumpArray(array,
"elements");
312 }
else if (object->IsType()) {
313 DumpType(Type::Cast(*
object));
314 }
else if (object->IsInstance()) {
315 DumpInstance(*
object);
323void SnapshotAnalyzer::DumpMetadata() {
342 dart::compiler::target::kCompressedWordSize);
360 intptr_t* buffer_length) {
380 DumpInterestingObjects();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
ClassPtr At(intptr_t cid) const
void ResetObjectIdTable()
intptr_t GetObjectId(ObjectPtr raw_obj) const
void SetObjectId(ObjectPtr raw_obj, intptr_t object_id)
ObjectStore * object_store() const
SafepointRwLock * program_lock()
ClassTable * class_table() const
static intptr_t class_table_offset()
static intptr_t cached_class_table_table_offset()
static intptr_t object_store_offset()
void PrintProperty64(const char *name, int64_t i)
void Steal(char **buffer, intptr_t *buffer_length)
void PrintProperty(const char *name, intptr_t i)
void OpenArray(const char *property_name=nullptr)
void PrintfProperty(const char *name, const char *format,...) PRINTF_ATTRIBUTE(3
void OpenObject(const char *property_name=nullptr)
void PrintValue64(int64_t i)
IsolateGroup * isolate_group() const
void VisitCompressedPointers(uword heap_base, CompressedObjectPtr *first, CompressedObjectPtr *last)
virtual const char * ToCString() const
static ObjectPtr RawCast(ObjectPtr obj)
static Thread * Current()
static intptr_t isolate_offset()
static intptr_t isolate_group_offset()
IsolateGroup * isolate_group() const
static intptr_t dispatch_table_array_offset()
void init(std::function< void(ObjectPtr)> *fun)
void VisitPointers(ObjectPtr *first, ObjectPtr *last) override
FieldVisitor(IsolateGroup *isolate_group)
void DumpSnapshotInformation(char **buffer, intptr_t *buffer_length)
SnapshotAnalyzer(const Dart_SnapshotAnalyzerInformation &info)
#define DARTSCOPE(thread)
static const uint8_t buffer[]
Dart_NativeFunction function
constexpr intptr_t kSnapshotAnalyzerVersion
constexpr intptr_t kStartIndex
void Dart_DumpSnapshotInformationAsJson(const Dart_SnapshotAnalyzerInformation &info, char **buffer, intptr_t *buffer_length)