| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/heap_profiler.h" | 5 #include "vm/heap_profiler.h" |
| 6 | 6 |
| 7 #include "vm/dart_api_state.h" | 7 #include "vm/dart_api_state.h" |
| 8 #include "vm/object.h" | 8 #include "vm/object.h" |
| 9 #include "vm/raw_object.h" | 9 #include "vm/raw_object.h" |
| 10 #include "vm/stack_frame.h" | 10 #include "vm/stack_frame.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 uint16_t x = 0xFF; | 61 uint16_t x = 0xFF; |
| 62 if (*reinterpret_cast<uint8_t*>(&x) == 0xFF) { | 62 if (*reinterpret_cast<uint8_t*>(&x) == 0xFF) { |
| 63 uint64_t hi = static_cast<uint64_t>(htonl(value & 0xFFFFFFFF)) << 32; | 63 uint64_t hi = static_cast<uint64_t>(htonl(value & 0xFFFFFFFF)) << 32; |
| 64 uint64_t lo = htonl(value >> 32); | 64 uint64_t lo = htonl(value >> 32); |
| 65 value = hi | lo; | 65 value = hi | lo; |
| 66 } | 66 } |
| 67 body_.Write(reinterpret_cast<uint8_t*>(&value), sizeof(value)); | 67 body_.Write(reinterpret_cast<uint8_t*>(&value), sizeof(value)); |
| 68 } | 68 } |
| 69 | 69 |
| 70 | 70 |
| 71 void HeapProfiler::Record::WritePointer(const void* value) { | 71 void HeapProfiler::Record::WriteObjectId(const void* value) { |
| 72 Write64(reinterpret_cast<uint64_t>(value)); | 72 Write64(reinterpret_cast<uint64_t>(value)); |
| 73 } | 73 } |
| 74 | 74 |
| 75 | 75 |
| 76 HeapProfiler::SubRecord::SubRecord(uint8_t sub_tag, HeapProfiler* profiler) | 76 HeapProfiler::SubRecord::SubRecord(uint8_t sub_tag, HeapProfiler* profiler) |
| 77 : record_(profiler->heap_dump_record_) { | 77 : record_(profiler->heap_dump_record_) { |
| 78 record_->Write8(sub_tag); | 78 record_->Write8(sub_tag); |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 101 void HeapProfiler::SubRecord::Write32(uint32_t value) { | 101 void HeapProfiler::SubRecord::Write32(uint32_t value) { |
| 102 record_->Write32(value); | 102 record_->Write32(value); |
| 103 } | 103 } |
| 104 | 104 |
| 105 | 105 |
| 106 void HeapProfiler::SubRecord::Write64(uint64_t value) { | 106 void HeapProfiler::SubRecord::Write64(uint64_t value) { |
| 107 record_->Write64(value); | 107 record_->Write64(value); |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 void HeapProfiler::SubRecord::WritePointer(const void* value) { | 111 void HeapProfiler::SubRecord::WriteObjectId(const void* value) { |
| 112 record_->WritePointer(value); | 112 record_->WriteObjectId(value); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 HeapProfiler::HeapProfiler(Dart_FileWriteCallback callback, void* stream) | 116 HeapProfiler::HeapProfiler(Dart_FileWriteCallback callback, void* stream) |
| 117 : write_callback_(callback), | 117 : write_callback_(callback), |
| 118 output_stream_(stream), | 118 output_stream_(stream), |
| 119 heap_dump_record_(NULL) { | 119 heap_dump_record_(NULL) { |
| 120 WriteHeader(); | 120 WriteHeader(); |
| 121 WriteStackTrace(); | 121 WriteStackTrace(); |
| 122 heap_dump_record_ = new Record(kHeapDump, this); | 122 heap_dump_record_ = new Record(kHeapDump, this); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 const RawType* super_type = raw_class->ptr()->super_type_; | 189 const RawType* super_type = raw_class->ptr()->super_type_; |
| 190 if (super_type == Type::null()) { | 190 if (super_type == Type::null()) { |
| 191 return Class::null(); | 191 return Class::null(); |
| 192 } | 192 } |
| 193 return reinterpret_cast<const RawClass*>(super_type->ptr()->type_class_); | 193 return reinterpret_cast<const RawClass*>(super_type->ptr()->type_class_); |
| 194 } | 194 } |
| 195 | 195 |
| 196 | 196 |
| 197 void HeapProfiler::WriteRoot(const RawObject* raw_obj) { | 197 void HeapProfiler::WriteRoot(const RawObject* raw_obj) { |
| 198 SubRecord sub(kRootUnknown, this); | 198 SubRecord sub(kRootUnknown, this); |
| 199 sub.WritePointer(ObjectId(raw_obj)); | 199 sub.WriteObjectId(ObjectId(raw_obj)); |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 void HeapProfiler::WriteObject(const RawObject* raw_obj) { | 203 void HeapProfiler::WriteObject(const RawObject* raw_obj) { |
| 204 ASSERT(raw_obj->IsHeapObject()); | 204 ASSERT(raw_obj->IsHeapObject()); |
| 205 intptr_t class_id = raw_obj->GetClassId(); | 205 intptr_t class_id = raw_obj->GetClassId(); |
| 206 switch (class_id) { | 206 switch (class_id) { |
| 207 case kFreeListElement: { | 207 case kFreeListElement: { |
| 208 // Free space has an object-like encoding. Heap profiles only | 208 // Free space has an object-like encoding. Heap profiles only |
| 209 // care about live objects so we skip over these records. | 209 // care about live objects so we skip over these records. |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 for (intptr_t i = 0; i < Smi::Value(twostr->ptr()->length_); ++i) { | 361 for (intptr_t i = 0; i < Smi::Value(twostr->ptr()->length_); ++i) { |
| 362 length += Utf8::Length(twostr->ptr()->data_[i]); | 362 length += Utf8::Length(twostr->ptr()->data_[i]); |
| 363 } | 363 } |
| 364 characters = new char[length]; | 364 characters = new char[length]; |
| 365 for (intptr_t i = 0, j = 0; i < Smi::Value(twostr->ptr()->length_); ++i) { | 365 for (intptr_t i = 0, j = 0; i < Smi::Value(twostr->ptr()->length_); ++i) { |
| 366 int32_t ch = twostr->ptr()->data_[i]; | 366 int32_t ch = twostr->ptr()->data_[i]; |
| 367 j += Utf8::Encode(ch, &characters[j]); | 367 j += Utf8::Encode(ch, &characters[j]); |
| 368 } | 368 } |
| 369 } | 369 } |
| 370 Record record(kStringInUtf8, this); | 370 Record record(kStringInUtf8, this); |
| 371 record.WritePointer(ObjectId(raw_string)); | 371 record.WriteObjectId(ObjectId(raw_string)); |
| 372 for (intptr_t i = 0; i < length; ++i) { | 372 for (intptr_t i = 0; i < length; ++i) { |
| 373 record.Write8(characters[i]); | 373 record.Write8(characters[i]); |
| 374 } | 374 } |
| 375 delete[] characters; | 375 delete[] characters; |
| 376 } | 376 } |
| 377 | 377 |
| 378 | 378 |
| 379 void HeapProfiler::WriteStringInUtf8(const char* c_string) { | 379 void HeapProfiler::WriteStringInUtf8(const char* c_string) { |
| 380 Record record(kStringInUtf8, this); | 380 Record record(kStringInUtf8, this); |
| 381 record.WritePointer(c_string); | 381 record.WriteObjectId(c_string); |
| 382 for (; *c_string != '\0'; ++c_string) { | 382 for (; *c_string != '\0'; ++c_string) { |
| 383 record.Write8(*c_string); | 383 record.Write8(*c_string); |
| 384 } | 384 } |
| 385 } | 385 } |
| 386 | 386 |
| 387 | 387 |
| 388 // LOAD CLASS - 0x02 | 388 // LOAD CLASS - 0x02 |
| 389 // | 389 // |
| 390 // Format: | 390 // Format: |
| 391 // u4 - class serial number (always > 0) | 391 // u4 - class serial number (always > 0) |
| 392 // ID - class object ID | 392 // ID - class object ID |
| 393 // u4 - stack trace serial number | 393 // u4 - stack trace serial number |
| 394 // ID - class name string ID | 394 // ID - class name string ID |
| 395 void HeapProfiler::WriteLoadClass(const RawClass* raw_class) { | 395 void HeapProfiler::WriteLoadClass(const RawClass* raw_class) { |
| 396 Record record(kLoadClass, this); | 396 Record record(kLoadClass, this); |
| 397 // class serial number (always > 0) | 397 // class serial number (always > 0) |
| 398 record.Write32(1); | 398 record.Write32(1); |
| 399 // class object ID | 399 // class object ID |
| 400 record.WritePointer(raw_class); | 400 record.WriteObjectId(raw_class); |
| 401 // stack trace serial number | 401 // stack trace serial number |
| 402 record.Write32(0); | 402 record.Write32(0); |
| 403 // class name string ID | 403 // class name string ID |
| 404 if (raw_class->ptr()->name_ != String::null()) { | 404 if (raw_class->ptr()->name_ != String::null()) { |
| 405 record.WritePointer(StringId(raw_class->ptr()->name_)); | 405 record.WriteObjectId(StringId(raw_class->ptr()->name_)); |
| 406 } else { | 406 } else { |
| 407 const char* format = "<an unnamed class with id %d>"; | 407 const char* format = "<an unnamed class with id %d>"; |
| 408 intptr_t len = OS::SNPrint(NULL, 0, format, raw_class->ptr()->id_); | 408 intptr_t len = OS::SNPrint(NULL, 0, format, raw_class->ptr()->id_); |
| 409 char* str = new char[len + 1]; | 409 char* str = new char[len + 1]; |
| 410 OS::SNPrint(str, len + 1, format, raw_class->ptr()->id_); | 410 OS::SNPrint(str, len + 1, format, raw_class->ptr()->id_); |
| 411 record.WritePointer(StringId(str)); | 411 record.WriteObjectId(StringId(str)); |
| 412 delete[] str; | 412 delete[] str; |
| 413 } | 413 } |
| 414 } | 414 } |
| 415 | 415 |
| 416 | 416 |
| 417 // STACK TRACE - 0x05 | 417 // STACK TRACE - 0x05 |
| 418 // | 418 // |
| 419 // u4 - stack trace serial number | 419 // u4 - stack trace serial number |
| 420 // u4 - thread serial number | 420 // u4 - thread serial number |
| 421 // u4 - number of frames | 421 // u4 - number of frames |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 // u2 - Number of static fields: | 478 // u2 - Number of static fields: |
| 479 // ID - static field name string ID | 479 // ID - static field name string ID |
| 480 // u1 - type of field: (See Basic Type) | 480 // u1 - type of field: (See Basic Type) |
| 481 // value - value of entry (u1, u2, u4, or u8 based on type of field) | 481 // value - value of entry (u1, u2, u4, or u8 based on type of field) |
| 482 // u2 - Number of instance fields (not including super class's) | 482 // u2 - Number of instance fields (not including super class's) |
| 483 // ID - field name string ID | 483 // ID - field name string ID |
| 484 // u1 - type of field: (See Basic Type) | 484 // u1 - type of field: (See Basic Type) |
| 485 void HeapProfiler::WriteClassDump(const RawClass* raw_class) { | 485 void HeapProfiler::WriteClassDump(const RawClass* raw_class) { |
| 486 SubRecord sub(kClassDump, this); | 486 SubRecord sub(kClassDump, this); |
| 487 // class object ID | 487 // class object ID |
| 488 sub.WritePointer(ClassId(raw_class)); | 488 sub.WriteObjectId(ClassId(raw_class)); |
| 489 // stack trace serial number | 489 // stack trace serial number |
| 490 sub.Write32(0); | 490 sub.Write32(0); |
| 491 // super class object ID | 491 // super class object ID |
| 492 const RawClass* super_class = GetSuperClass(raw_class); | 492 const RawClass* super_class = GetSuperClass(raw_class); |
| 493 if (super_class == Class::null()) { | 493 if (super_class == Class::null()) { |
| 494 sub.WritePointer(NULL); | 494 sub.WriteObjectId(NULL); |
| 495 } else { | 495 } else { |
| 496 sub.WritePointer(ClassId(super_class)); | 496 sub.WriteObjectId(ClassId(super_class)); |
| 497 } | 497 } |
| 498 // class loader object ID | 498 // class loader object ID |
| 499 sub.WritePointer(NULL); | 499 sub.WriteObjectId(NULL); |
| 500 // signers object ID | 500 // signers object ID |
| 501 sub.WritePointer(NULL); | 501 sub.WriteObjectId(NULL); |
| 502 // protection domain object ID | 502 // protection domain object ID |
| 503 sub.WritePointer(NULL); | 503 sub.WriteObjectId(NULL); |
| 504 // reserved | 504 // reserved |
| 505 sub.WritePointer(NULL); | 505 sub.WriteObjectId(NULL); |
| 506 // reserved | 506 // reserved |
| 507 sub.WritePointer(NULL); | 507 sub.WriteObjectId(NULL); |
| 508 | 508 |
| 509 intptr_t num_static_fields = 0; | 509 intptr_t num_static_fields = 0; |
| 510 intptr_t num_instance_fields = 0; | 510 intptr_t num_instance_fields = 0; |
| 511 | 511 |
| 512 RawArray* raw_array = raw_class->ptr()->fields_; | 512 RawArray* raw_array = raw_class->ptr()->fields_; |
| 513 if (raw_array != Array::null()) { | 513 if (raw_array != Array::null()) { |
| 514 for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) { | 514 for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) { |
| 515 RawField* raw_field = | 515 RawField* raw_field = |
| 516 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); | 516 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); |
| 517 if (Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { | 517 if (Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 529 // Number of static fields | 529 // Number of static fields |
| 530 sub.Write16(num_static_fields); | 530 sub.Write16(num_static_fields); |
| 531 // Static fields: | 531 // Static fields: |
| 532 if (raw_array != Array::null()) { | 532 if (raw_array != Array::null()) { |
| 533 for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) { | 533 for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) { |
| 534 RawField* raw_field = | 534 RawField* raw_field = |
| 535 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); | 535 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); |
| 536 if (Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { | 536 if (Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { |
| 537 ASSERT(raw_field->ptr()->name_ != String::null()); | 537 ASSERT(raw_field->ptr()->name_ != String::null()); |
| 538 // static field name string ID | 538 // static field name string ID |
| 539 sub.WritePointer(StringId(raw_field->ptr()->name_)); | 539 sub.WriteObjectId(StringId(raw_field->ptr()->name_)); |
| 540 // type of static field | 540 // type of static field |
| 541 sub.Write8(kObject); | 541 sub.Write8(kObject); |
| 542 // value of entry | 542 // value of entry |
| 543 sub.WritePointer(ObjectId(raw_field->ptr()->value_)); | 543 sub.WriteObjectId(ObjectId(raw_field->ptr()->value_)); |
| 544 } | 544 } |
| 545 } | 545 } |
| 546 } | 546 } |
| 547 // Number of instance fields (not include super class's) | 547 // Number of instance fields (not include super class's) |
| 548 sub.Write16(num_instance_fields); | 548 sub.Write16(num_instance_fields); |
| 549 // Instance fields: | 549 // Instance fields: |
| 550 if (raw_array != Array::null()) { | 550 if (raw_array != Array::null()) { |
| 551 for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) { | 551 for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) { |
| 552 RawField* raw_field = | 552 RawField* raw_field = |
| 553 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); | 553 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); |
| 554 if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { | 554 if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { |
| 555 ASSERT(raw_field->ptr()->name_ != String::null()); | 555 ASSERT(raw_field->ptr()->name_ != String::null()); |
| 556 // field name string ID | 556 // field name string ID |
| 557 sub.WritePointer(StringId(raw_field->ptr()->name_)); | 557 sub.WriteObjectId(StringId(raw_field->ptr()->name_)); |
| 558 // type of field | 558 // type of field |
| 559 sub.Write8(kObject); | 559 sub.Write8(kObject); |
| 560 } | 560 } |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 } | 563 } |
| 564 | 564 |
| 565 | 565 |
| 566 // INSTANCE DUMP - 0x21 | 566 // INSTANCE DUMP - 0x21 |
| 567 // | 567 // |
| 568 // Format: | 568 // Format: |
| 569 // ID - object ID | 569 // ID - object ID |
| 570 // u4 - stack trace serial number | 570 // u4 - stack trace serial number |
| 571 // ID - class object ID | 571 // ID - class object ID |
| 572 // u4 - number of bytes that follow | 572 // u4 - number of bytes that follow |
| 573 // [value]* - instance field values (this class, followed by super class, etc) | 573 // [value]* - instance field values (this class, followed by super class, etc) |
| 574 void HeapProfiler::WriteInstanceDump(const RawObject* raw_obj) { | 574 void HeapProfiler::WriteInstanceDump(const RawObject* raw_obj) { |
| 575 SubRecord sub(kInstanceDump, this); | 575 SubRecord sub(kInstanceDump, this); |
| 576 // object ID | 576 // object ID |
| 577 sub.WritePointer(raw_obj); | 577 sub.WriteObjectId(raw_obj); |
| 578 // stack trace serial number | 578 // stack trace serial number |
| 579 sub.Write32(0); | 579 sub.Write32(0); |
| 580 // class object ID | 580 // class object ID |
| 581 sub.WritePointer(ClassId(GetClass(raw_obj))); | 581 sub.WriteObjectId(ClassId(GetClass(raw_obj))); |
| 582 // number of bytes that follow | 582 // number of bytes that follow |
| 583 intptr_t num_instance_fields = 0; | 583 intptr_t num_instance_fields = 0; |
| 584 for (const RawClass* cls = GetClass(raw_obj); | 584 for (const RawClass* cls = GetClass(raw_obj); |
| 585 cls != Class::null(); | 585 cls != Class::null(); |
| 586 cls = GetSuperClass(cls)) { | 586 cls = GetSuperClass(cls)) { |
| 587 RawArray* raw_array = cls->ptr()->fields_; | 587 RawArray* raw_array = cls->ptr()->fields_; |
| 588 if (raw_array != Array::null()) { | 588 if (raw_array != Array::null()) { |
| 589 intptr_t length = Smi::Value(raw_array->ptr()->length_); | 589 intptr_t length = Smi::Value(raw_array->ptr()->length_); |
| 590 for (intptr_t i = 0; i < length; ++i) { | 590 for (intptr_t i = 0; i < length; ++i) { |
| 591 RawField* raw_field = | 591 RawField* raw_field = |
| 592 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); | 592 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); |
| 593 if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { | 593 if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { |
| 594 ++num_instance_fields; | 594 ++num_instance_fields; |
| 595 } | 595 } |
| 596 } | 596 } |
| 597 } | 597 } |
| 598 } | 598 } |
| 599 sub.Write32(num_instance_fields * kWordSize); | 599 int64_t num_instance_bytes = num_instance_fields * kObjectIdSize; |
| 600 ASSERT(num_instance_bytes <= kMaxUint32); |
| 601 sub.Write32(num_instance_bytes); |
| 600 // instance field values (this class, followed by super class, etc) | 602 // instance field values (this class, followed by super class, etc) |
| 601 for (const RawClass* cls = GetClass(raw_obj); | 603 for (const RawClass* cls = GetClass(raw_obj); |
| 602 cls != Class::null(); | 604 cls != Class::null(); |
| 603 cls = GetSuperClass(cls)) { | 605 cls = GetSuperClass(cls)) { |
| 604 RawArray* raw_array = cls->ptr()->fields_; | 606 RawArray* raw_array = cls->ptr()->fields_; |
| 605 if (raw_array != Array::null()) { | 607 if (raw_array != Array::null()) { |
| 606 intptr_t length = Smi::Value(raw_array->ptr()->length_); | 608 intptr_t length = Smi::Value(raw_array->ptr()->length_); |
| 607 uint8_t* base = reinterpret_cast<uint8_t*>(raw_obj->ptr()); | 609 uint8_t* base = reinterpret_cast<uint8_t*>(raw_obj->ptr()); |
| 608 for (intptr_t i = 0; i < length; ++i) { | 610 for (intptr_t i = 0; i < length; ++i) { |
| 609 RawField* raw_field = | 611 RawField* raw_field = |
| 610 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); | 612 reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]); |
| 611 if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { | 613 if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) { |
| 612 intptr_t offset_in_words = | 614 intptr_t offset_in_words = |
| 613 Smi::Value(reinterpret_cast<RawSmi*>(raw_field->ptr()->value_)); | 615 Smi::Value(reinterpret_cast<RawSmi*>(raw_field->ptr()->value_)); |
| 614 intptr_t offset = offset_in_words * kWordSize; | 616 intptr_t offset = offset_in_words * kWordSize; |
| 615 RawObject* ptr = *reinterpret_cast<RawObject**>(base + offset); | 617 RawObject* ptr = *reinterpret_cast<RawObject**>(base + offset); |
| 616 sub.WritePointer(ObjectId(ptr)); | 618 sub.WriteObjectId(ObjectId(ptr)); |
| 617 } | 619 } |
| 618 } | 620 } |
| 619 } | 621 } |
| 620 } | 622 } |
| 621 } | 623 } |
| 622 | 624 |
| 623 | 625 |
| 624 // OBJECT ARRAY DUMP - 0x22 | 626 // OBJECT ARRAY DUMP - 0x22 |
| 625 // | 627 // |
| 626 // Format: | 628 // Format: |
| 627 // ID - array object ID | 629 // ID - array object ID |
| 628 // u4 - stack trace serial number | 630 // u4 - stack trace serial number |
| 629 // u4 - number of elements | 631 // u4 - number of elements |
| 630 // ID - array class object ID | 632 // ID - array class object ID |
| 631 // [ID]* - elements | 633 // [ID]* - elements |
| 632 void HeapProfiler::WriteObjectArrayDump(const RawArray* raw_array) { | 634 void HeapProfiler::WriteObjectArrayDump(const RawArray* raw_array) { |
| 633 SubRecord sub(kObjectArrayDump, this); | 635 SubRecord sub(kObjectArrayDump, this); |
| 634 // array object ID | 636 // array object ID |
| 635 sub.WritePointer(raw_array); | 637 sub.WriteObjectId(raw_array); |
| 636 // stack trace serial number | 638 // stack trace serial number |
| 637 sub.Write32(0); | 639 sub.Write32(0); |
| 638 // number of elements | 640 // number of elements |
| 639 intptr_t length = Smi::Value(raw_array->ptr()->length_); | 641 intptr_t length = Smi::Value(raw_array->ptr()->length_); |
| 640 sub.Write32(length); | 642 sub.Write32(length); |
| 641 // array class object ID | 643 // array class object ID |
| 642 sub.WritePointer(NULL); | 644 sub.WriteObjectId(NULL); |
| 643 // elements | 645 // elements |
| 644 for (intptr_t i = 0; i < length; ++i) { | 646 for (intptr_t i = 0; i < length; ++i) { |
| 645 sub.WritePointer(ObjectId(raw_array->ptr()->data()[i])); | 647 sub.WriteObjectId(ObjectId(raw_array->ptr()->data()[i])); |
| 646 } | 648 } |
| 647 } | 649 } |
| 648 | 650 |
| 649 | 651 |
| 650 // PRIMITIVE ARRAY DUMP - 0x23 | 652 // PRIMITIVE ARRAY DUMP - 0x23 |
| 651 // | 653 // |
| 652 // Format: | 654 // Format: |
| 653 // ID - array object ID | 655 // ID - array object ID |
| 654 // u4 - stack trace serial number | 656 // u4 - stack trace serial number |
| 655 // u4 - number of elements | 657 // u4 - number of elements |
| 656 // u1 - element type | 658 // u1 - element type |
| 657 // [u1]* - elements | 659 // [u1]* - elements |
| 658 void HeapProfiler::WritePrimitiveArrayDump(const RawByteArray* raw_byte_array, | 660 void HeapProfiler::WritePrimitiveArrayDump(const RawByteArray* raw_byte_array, |
| 659 uint8_t tag, | 661 uint8_t tag, |
| 660 const void* data) { | 662 const void* data) { |
| 661 SubRecord sub(kPrimitiveArrayDump, this); | 663 SubRecord sub(kPrimitiveArrayDump, this); |
| 662 // array object ID | 664 // array object ID |
| 663 sub.WritePointer(raw_byte_array); | 665 sub.WriteObjectId(raw_byte_array); |
| 664 // stack trace serial number | 666 // stack trace serial number |
| 665 sub.Write32(0); | 667 sub.Write32(0); |
| 666 // number of elements | 668 // number of elements |
| 667 intptr_t length = Smi::Value(raw_byte_array->ptr()->length_); | 669 intptr_t length = Smi::Value(raw_byte_array->ptr()->length_); |
| 668 sub.Write32(length); | 670 sub.Write32(length); |
| 669 // element type | 671 // element type |
| 670 sub.Write8(tag); | 672 sub.Write8(tag); |
| 671 // elements (packed) | 673 // elements (packed) |
| 672 for (intptr_t i = 0; i < length; ++i) { | 674 for (intptr_t i = 0; i < length; ++i) { |
| 673 if (tag == kByte) { | 675 if (tag == kByte) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 RawObject* raw_obj = handle->raw(); | 715 RawObject* raw_obj = handle->raw(); |
| 714 visitor_->VisitPointer(&raw_obj); | 716 visitor_->VisitPointer(&raw_obj); |
| 715 } | 717 } |
| 716 | 718 |
| 717 | 719 |
| 718 void HeapProfilerObjectVisitor::VisitObject(RawObject* raw_obj) { | 720 void HeapProfilerObjectVisitor::VisitObject(RawObject* raw_obj) { |
| 719 profiler_->WriteObject(raw_obj); | 721 profiler_->WriteObject(raw_obj); |
| 720 } | 722 } |
| 721 | 723 |
| 722 } // namespace dart | 724 } // namespace dart |
| OLD | NEW |