1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Preparation and completion of hprof data generation. The output is 19 * written into two files and then combined. This is necessary because 20 * we generate some of the data (strings and classes) while we dump the 21 * heap, and some analysis tools require that the class and string data 22 * appear first. 23 */ 24 25 #include "hprof.h" 26 27 #include <cutils/open_memstream.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <sys/time.h> 33 #include <sys/uio.h> 34 #include <time.h> 35 #include <time.h> 36 #include <unistd.h> 37 38 #include <set> 39 40 #include "art_field-inl.h" 41 #include "base/logging.h" 42 #include "base/stringprintf.h" 43 #include "base/time_utils.h" 44 #include "base/unix_file/fd_file.h" 45 #include "class_linker.h" 46 #include "common_throws.h" 47 #include "debugger.h" 48 #include "dex_file-inl.h" 49 #include "gc_root.h" 50 #include "gc/accounting/heap_bitmap.h" 51 #include "gc/allocation_record.h" 52 #include "gc/heap.h" 53 #include "gc/space/space.h" 54 #include "globals.h" 55 #include "jdwp/jdwp.h" 56 #include "jdwp/jdwp_priv.h" 57 #include "mirror/class.h" 58 #include "mirror/class-inl.h" 59 #include "mirror/object-inl.h" 60 #include "os.h" 61 #include "safe_map.h" 62 #include "scoped_thread_state_change.h" 63 #include "thread_list.h" 64 65 namespace art { 66 67 namespace hprof { 68 69 static constexpr bool kDirectStream = true; 70 71 static constexpr uint32_t kHprofTime = 0; 72 static constexpr uint32_t kHprofNullThread = 0; 73 74 static constexpr size_t kMaxObjectsPerSegment = 128; 75 static constexpr size_t kMaxBytesPerSegment = 4096; 76 77 // The static field-name for the synthetic object generated to account for class static overhead. 78 static constexpr const char* kClassOverheadName = "$classOverhead"; 79 80 enum HprofTag { 81 HPROF_TAG_STRING = 0x01, 82 HPROF_TAG_LOAD_CLASS = 0x02, 83 HPROF_TAG_UNLOAD_CLASS = 0x03, 84 HPROF_TAG_STACK_FRAME = 0x04, 85 HPROF_TAG_STACK_TRACE = 0x05, 86 HPROF_TAG_ALLOC_SITES = 0x06, 87 HPROF_TAG_HEAP_SUMMARY = 0x07, 88 HPROF_TAG_START_THREAD = 0x0A, 89 HPROF_TAG_END_THREAD = 0x0B, 90 HPROF_TAG_HEAP_DUMP = 0x0C, 91 HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1C, 92 HPROF_TAG_HEAP_DUMP_END = 0x2C, 93 HPROF_TAG_CPU_SAMPLES = 0x0D, 94 HPROF_TAG_CONTROL_SETTINGS = 0x0E, 95 }; 96 97 // Values for the first byte of HEAP_DUMP and HEAP_DUMP_SEGMENT records: 98 enum HprofHeapTag { 99 // Traditional. 100 HPROF_ROOT_UNKNOWN = 0xFF, 101 HPROF_ROOT_JNI_GLOBAL = 0x01, 102 HPROF_ROOT_JNI_LOCAL = 0x02, 103 HPROF_ROOT_JAVA_FRAME = 0x03, 104 HPROF_ROOT_NATIVE_STACK = 0x04, 105 HPROF_ROOT_STICKY_CLASS = 0x05, 106 HPROF_ROOT_THREAD_BLOCK = 0x06, 107 HPROF_ROOT_MONITOR_USED = 0x07, 108 HPROF_ROOT_THREAD_OBJECT = 0x08, 109 HPROF_CLASS_DUMP = 0x20, 110 HPROF_INSTANCE_DUMP = 0x21, 111 HPROF_OBJECT_ARRAY_DUMP = 0x22, 112 HPROF_PRIMITIVE_ARRAY_DUMP = 0x23, 113 114 // Android. 115 HPROF_HEAP_DUMP_INFO = 0xfe, 116 HPROF_ROOT_INTERNED_STRING = 0x89, 117 HPROF_ROOT_FINALIZING = 0x8a, // Obsolete. 118 HPROF_ROOT_DEBUGGER = 0x8b, 119 HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, // Obsolete. 120 HPROF_ROOT_VM_INTERNAL = 0x8d, 121 HPROF_ROOT_JNI_MONITOR = 0x8e, 122 HPROF_UNREACHABLE = 0x90, // Obsolete. 123 HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3, // Obsolete. 124 }; 125 126 enum HprofHeapId { 127 HPROF_HEAP_DEFAULT = 0, 128 HPROF_HEAP_ZYGOTE = 'Z', 129 HPROF_HEAP_APP = 'A', 130 HPROF_HEAP_IMAGE = 'I', 131 }; 132 133 enum HprofBasicType { 134 hprof_basic_object = 2, 135 hprof_basic_boolean = 4, 136 hprof_basic_char = 5, 137 hprof_basic_float = 6, 138 hprof_basic_double = 7, 139 hprof_basic_byte = 8, 140 hprof_basic_short = 9, 141 hprof_basic_int = 10, 142 hprof_basic_long = 11, 143 }; 144 145 typedef uint32_t HprofStringId; 146 typedef uint32_t HprofClassObjectId; 147 typedef uint32_t HprofClassSerialNumber; 148 typedef uint32_t HprofStackTraceSerialNumber; 149 typedef uint32_t HprofStackFrameId; 150 static constexpr HprofStackTraceSerialNumber kHprofNullStackTrace = 0; 151 152 class EndianOutput { 153 public: 154 EndianOutput() : length_(0), sum_length_(0), max_length_(0), started_(false) {} 155 virtual ~EndianOutput() {} 156 157 void StartNewRecord(uint8_t tag, uint32_t time) { 158 if (length_ > 0) { 159 EndRecord(); 160 } 161 DCHECK_EQ(length_, 0U); 162 AddU1(tag); 163 AddU4(time); 164 AddU4(0xdeaddead); // Length, replaced on flush. 165 started_ = true; 166 } 167 168 void EndRecord() { 169 // Replace length in header. 170 if (started_) { 171 UpdateU4(sizeof(uint8_t) + sizeof(uint32_t), 172 length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 173 } 174 175 HandleEndRecord(); 176 177 sum_length_ += length_; 178 max_length_ = std::max(max_length_, length_); 179 length_ = 0; 180 started_ = false; 181 } 182 183 void AddU1(uint8_t value) { 184 AddU1List(&value, 1); 185 } 186 void AddU2(uint16_t value) { 187 AddU2List(&value, 1); 188 } 189 void AddU4(uint32_t value) { 190 AddU4List(&value, 1); 191 } 192 193 void AddU8(uint64_t value) { 194 AddU8List(&value, 1); 195 } 196 197 void AddObjectId(const mirror::Object* value) { 198 AddU4(PointerToLowMemUInt32(value)); 199 } 200 201 void AddStackTraceSerialNumber(HprofStackTraceSerialNumber value) { 202 AddU4(value); 203 } 204 205 // The ID for the synthetic object generated to account for class static overhead. 206 void AddClassStaticsId(const mirror::Class* value) { 207 AddU4(1 | PointerToLowMemUInt32(value)); 208 } 209 210 void AddJniGlobalRefId(jobject value) { 211 AddU4(PointerToLowMemUInt32(value)); 212 } 213 214 void AddClassId(HprofClassObjectId value) { 215 AddU4(value); 216 } 217 218 void AddStringId(HprofStringId value) { 219 AddU4(value); 220 } 221 222 void AddU1List(const uint8_t* values, size_t count) { 223 HandleU1List(values, count); 224 length_ += count; 225 } 226 void AddU2List(const uint16_t* values, size_t count) { 227 HandleU2List(values, count); 228 length_ += count * sizeof(uint16_t); 229 } 230 void AddU4List(const uint32_t* values, size_t count) { 231 HandleU4List(values, count); 232 length_ += count * sizeof(uint32_t); 233 } 234 virtual void UpdateU4(size_t offset, uint32_t new_value ATTRIBUTE_UNUSED) { 235 DCHECK_LE(offset, length_ - 4); 236 } 237 void AddU8List(const uint64_t* values, size_t count) { 238 HandleU8List(values, count); 239 length_ += count * sizeof(uint64_t); 240 } 241 242 void AddIdList(mirror::ObjectArray<mirror::Object>* values) 243 SHARED_REQUIRES(Locks::mutator_lock_) { 244 const int32_t length = values->GetLength(); 245 for (int32_t i = 0; i < length; ++i) { 246 AddObjectId(values->GetWithoutChecks(i)); 247 } 248 } 249 250 void AddUtf8String(const char* str) { 251 // The terminating NUL character is NOT written. 252 AddU1List((const uint8_t*)str, strlen(str)); 253 } 254 255 size_t Length() const { 256 return length_; 257 } 258 259 size_t SumLength() const { 260 return sum_length_; 261 } 262 263 size_t MaxLength() const { 264 return max_length_; 265 } 266 267 protected: 268 virtual void HandleU1List(const uint8_t* values ATTRIBUTE_UNUSED, 269 size_t count ATTRIBUTE_UNUSED) { 270 } 271 virtual void HandleU2List(const uint16_t* values ATTRIBUTE_UNUSED, 272 size_t count ATTRIBUTE_UNUSED) { 273 } 274 virtual void HandleU4List(const uint32_t* values ATTRIBUTE_UNUSED, 275 size_t count ATTRIBUTE_UNUSED) { 276 } 277 virtual void HandleU8List(const uint64_t* values ATTRIBUTE_UNUSED, 278 size_t count ATTRIBUTE_UNUSED) { 279 } 280 virtual void HandleEndRecord() { 281 } 282 283 size_t length_; // Current record size. 284 size_t sum_length_; // Size of all data. 285 size_t max_length_; // Maximum seen length. 286 bool started_; // Was StartRecord called? 287 }; 288 289 // This keeps things buffered until flushed. 290 class EndianOutputBuffered : public EndianOutput { 291 public: 292 explicit EndianOutputBuffered(size_t reserve_size) { 293 buffer_.reserve(reserve_size); 294 } 295 virtual ~EndianOutputBuffered() {} 296 297 void UpdateU4(size_t offset, uint32_t new_value) OVERRIDE { 298 DCHECK_LE(offset, length_ - 4); 299 buffer_[offset + 0] = static_cast<uint8_t>((new_value >> 24) & 0xFF); 300 buffer_[offset + 1] = static_cast<uint8_t>((new_value >> 16) & 0xFF); 301 buffer_[offset + 2] = static_cast<uint8_t>((new_value >> 8) & 0xFF); 302 buffer_[offset + 3] = static_cast<uint8_t>((new_value >> 0) & 0xFF); 303 } 304 305 protected: 306 void HandleU1List(const uint8_t* values, size_t count) OVERRIDE { 307 DCHECK_EQ(length_, buffer_.size()); 308 buffer_.insert(buffer_.end(), values, values + count); 309 } 310 311 void HandleU2List(const uint16_t* values, size_t count) OVERRIDE { 312 DCHECK_EQ(length_, buffer_.size()); 313 for (size_t i = 0; i < count; ++i) { 314 uint16_t value = *values; 315 buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 316 buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 317 values++; 318 } 319 } 320 321 void HandleU4List(const uint32_t* values, size_t count) OVERRIDE { 322 DCHECK_EQ(length_, buffer_.size()); 323 for (size_t i = 0; i < count; ++i) { 324 uint32_t value = *values; 325 buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 326 buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 327 buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 328 buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 329 values++; 330 } 331 } 332 333 void HandleU8List(const uint64_t* values, size_t count) OVERRIDE { 334 DCHECK_EQ(length_, buffer_.size()); 335 for (size_t i = 0; i < count; ++i) { 336 uint64_t value = *values; 337 buffer_.push_back(static_cast<uint8_t>((value >> 56) & 0xFF)); 338 buffer_.push_back(static_cast<uint8_t>((value >> 48) & 0xFF)); 339 buffer_.push_back(static_cast<uint8_t>((value >> 40) & 0xFF)); 340 buffer_.push_back(static_cast<uint8_t>((value >> 32) & 0xFF)); 341 buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 342 buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 343 buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 344 buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 345 values++; 346 } 347 } 348 349 void HandleEndRecord() OVERRIDE { 350 DCHECK_EQ(buffer_.size(), length_); 351 if (kIsDebugBuild && started_) { 352 uint32_t stored_length = 353 static_cast<uint32_t>(buffer_[5]) << 24 | 354 static_cast<uint32_t>(buffer_[6]) << 16 | 355 static_cast<uint32_t>(buffer_[7]) << 8 | 356 static_cast<uint32_t>(buffer_[8]); 357 DCHECK_EQ(stored_length, length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 358 } 359 HandleFlush(buffer_.data(), length_); 360 buffer_.clear(); 361 } 362 363 virtual void HandleFlush(const uint8_t* buffer ATTRIBUTE_UNUSED, size_t length ATTRIBUTE_UNUSED) { 364 } 365 366 std::vector<uint8_t> buffer_; 367 }; 368 369 class FileEndianOutput FINAL : public EndianOutputBuffered { 370 public: 371 FileEndianOutput(File* fp, size_t reserved_size) 372 : EndianOutputBuffered(reserved_size), fp_(fp), errors_(false) { 373 DCHECK(fp != nullptr); 374 } 375 ~FileEndianOutput() { 376 } 377 378 bool Errors() { 379 return errors_; 380 } 381 382 protected: 383 void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 384 if (!errors_) { 385 errors_ = !fp_->WriteFully(buffer, length); 386 } 387 } 388 389 private: 390 File* fp_; 391 bool errors_; 392 }; 393 394 class NetStateEndianOutput FINAL : public EndianOutputBuffered { 395 public: 396 NetStateEndianOutput(JDWP::JdwpNetStateBase* net_state, size_t reserved_size) 397 : EndianOutputBuffered(reserved_size), net_state_(net_state) { 398 DCHECK(net_state != nullptr); 399 } 400 ~NetStateEndianOutput() {} 401 402 protected: 403 void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 404 std::vector<iovec> iov; 405 iov.push_back(iovec()); 406 iov[0].iov_base = const_cast<void*>(reinterpret_cast<const void*>(buffer)); 407 iov[0].iov_len = length; 408 net_state_->WriteBufferedPacketLocked(iov); 409 } 410 411 private: 412 JDWP::JdwpNetStateBase* net_state_; 413 }; 414 415 #define __ output_-> 416 417 class Hprof : public SingleRootVisitor { 418 public: 419 Hprof(const char* output_filename, int fd, bool direct_to_ddms) 420 : filename_(output_filename), 421 fd_(fd), 422 direct_to_ddms_(direct_to_ddms) { 423 LOG(INFO) << "hprof: heap dump \"" << filename_ << "\" starting..."; 424 } 425 426 void Dump() 427 REQUIRES(Locks::mutator_lock_) 428 REQUIRES(!Locks::heap_bitmap_lock_, !Locks::alloc_tracker_lock_) { 429 { 430 MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_); 431 if (Runtime::Current()->GetHeap()->IsAllocTrackingEnabled()) { 432 PopulateAllocationTrackingTraces(); 433 } 434 } 435 436 // First pass to measure the size of the dump. 437 size_t overall_size; 438 size_t max_length; 439 { 440 EndianOutput count_output; 441 output_ = &count_output; 442 ProcessHeap(false); 443 overall_size = count_output.SumLength(); 444 max_length = count_output.MaxLength(); 445 output_ = nullptr; 446 } 447 448 bool okay; 449 if (direct_to_ddms_) { 450 if (kDirectStream) { 451 okay = DumpToDdmsDirect(overall_size, max_length, CHUNK_TYPE("HPDS")); 452 } else { 453 okay = DumpToDdmsBuffered(overall_size, max_length); 454 } 455 } else { 456 okay = DumpToFile(overall_size, max_length); 457 } 458 459 if (okay) { 460 const uint64_t duration = NanoTime() - start_ns_; 461 LOG(INFO) << "hprof: heap dump completed (" << PrettySize(RoundUp(overall_size, KB)) 462 << ") in " << PrettyDuration(duration) 463 << " objects " << total_objects_ 464 << " objects with stack traces " << total_objects_with_stack_trace_; 465 } 466 } 467 468 private: 469 static void VisitObjectCallback(mirror::Object* obj, void* arg) 470 SHARED_REQUIRES(Locks::mutator_lock_) { 471 DCHECK(obj != nullptr); 472 DCHECK(arg != nullptr); 473 reinterpret_cast<Hprof*>(arg)->DumpHeapObject(obj); 474 } 475 476 void DumpHeapObject(mirror::Object* obj) 477 SHARED_REQUIRES(Locks::mutator_lock_); 478 479 void DumpHeapClass(mirror::Class* klass) 480 SHARED_REQUIRES(Locks::mutator_lock_); 481 482 void DumpHeapArray(mirror::Array* obj, mirror::Class* klass) 483 SHARED_REQUIRES(Locks::mutator_lock_); 484 485 void DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) 486 SHARED_REQUIRES(Locks::mutator_lock_); 487 488 void ProcessHeap(bool header_first) 489 REQUIRES(Locks::mutator_lock_) { 490 // Reset current heap and object count. 491 current_heap_ = HPROF_HEAP_DEFAULT; 492 objects_in_segment_ = 0; 493 494 if (header_first) { 495 ProcessHeader(true); 496 ProcessBody(); 497 } else { 498 ProcessBody(); 499 ProcessHeader(false); 500 } 501 } 502 503 void ProcessBody() REQUIRES(Locks::mutator_lock_) { 504 Runtime* const runtime = Runtime::Current(); 505 // Walk the roots and the heap. 506 output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 507 508 simple_roots_.clear(); 509 runtime->VisitRoots(this); 510 runtime->VisitImageRoots(this); 511 runtime->GetHeap()->VisitObjectsPaused(VisitObjectCallback, this); 512 513 output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_END, kHprofTime); 514 output_->EndRecord(); 515 } 516 517 void ProcessHeader(bool string_first) REQUIRES(Locks::mutator_lock_) { 518 // Write the header. 519 WriteFixedHeader(); 520 // Write the string and class tables, and any stack traces, to the header. 521 // (jhat requires that these appear before any of the data in the body that refers to them.) 522 // jhat also requires the string table appear before class table and stack traces. 523 // However, WriteStackTraces() can modify the string table, so it's necessary to call 524 // WriteStringTable() last in the first pass, to compute the correct length of the output. 525 if (string_first) { 526 WriteStringTable(); 527 } 528 WriteClassTable(); 529 WriteStackTraces(); 530 if (!string_first) { 531 WriteStringTable(); 532 } 533 output_->EndRecord(); 534 } 535 536 void WriteClassTable() SHARED_REQUIRES(Locks::mutator_lock_) { 537 for (const auto& p : classes_) { 538 mirror::Class* c = p.first; 539 HprofClassSerialNumber sn = p.second; 540 CHECK(c != nullptr); 541 output_->StartNewRecord(HPROF_TAG_LOAD_CLASS, kHprofTime); 542 // LOAD CLASS format: 543 // U4: class serial number (always > 0) 544 // ID: class object ID. We use the address of the class object structure as its ID. 545 // U4: stack trace serial number 546 // ID: class name string ID 547 __ AddU4(sn); 548 __ AddObjectId(c); 549 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(c)); 550 __ AddStringId(LookupClassNameId(c)); 551 } 552 } 553 554 void WriteStringTable() { 555 for (const std::pair<std::string, HprofStringId>& p : strings_) { 556 const std::string& string = p.first; 557 const size_t id = p.second; 558 559 output_->StartNewRecord(HPROF_TAG_STRING, kHprofTime); 560 561 // STRING format: 562 // ID: ID for this string 563 // U1*: UTF8 characters for string (NOT null terminated) 564 // (the record format encodes the length) 565 __ AddU4(id); 566 __ AddUtf8String(string.c_str()); 567 } 568 } 569 570 void StartNewHeapDumpSegment() { 571 // This flushes the old segment and starts a new one. 572 output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 573 objects_in_segment_ = 0; 574 // Starting a new HEAP_DUMP resets the heap to default. 575 current_heap_ = HPROF_HEAP_DEFAULT; 576 } 577 578 void CheckHeapSegmentConstraints() { 579 if (objects_in_segment_ >= kMaxObjectsPerSegment || output_->Length() >= kMaxBytesPerSegment) { 580 StartNewHeapDumpSegment(); 581 } 582 } 583 584 void VisitRoot(mirror::Object* obj, const RootInfo& root_info) 585 OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_); 586 void MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 587 uint32_t thread_serial); 588 589 HprofClassObjectId LookupClassId(mirror::Class* c) SHARED_REQUIRES(Locks::mutator_lock_) { 590 if (c != nullptr) { 591 auto it = classes_.find(c); 592 if (it == classes_.end()) { 593 // first time to see this class 594 HprofClassSerialNumber sn = next_class_serial_number_++; 595 classes_.Put(c, sn); 596 // Make sure that we've assigned a string ID for this class' name 597 LookupClassNameId(c); 598 } 599 } 600 return PointerToLowMemUInt32(c); 601 } 602 603 HprofStackTraceSerialNumber LookupStackTraceSerialNumber(const mirror::Object* obj) 604 SHARED_REQUIRES(Locks::mutator_lock_) { 605 auto r = allocation_records_.find(obj); 606 if (r == allocation_records_.end()) { 607 return kHprofNullStackTrace; 608 } else { 609 const gc::AllocRecordStackTrace* trace = r->second; 610 auto result = traces_.find(trace); 611 CHECK(result != traces_.end()); 612 return result->second; 613 } 614 } 615 616 HprofStringId LookupStringId(mirror::String* string) SHARED_REQUIRES(Locks::mutator_lock_) { 617 return LookupStringId(string->ToModifiedUtf8()); 618 } 619 620 HprofStringId LookupStringId(const char* string) { 621 return LookupStringId(std::string(string)); 622 } 623 624 HprofStringId LookupStringId(const std::string& string) { 625 auto it = strings_.find(string); 626 if (it != strings_.end()) { 627 return it->second; 628 } 629 HprofStringId id = next_string_id_++; 630 strings_.Put(string, id); 631 return id; 632 } 633 634 HprofStringId LookupClassNameId(mirror::Class* c) SHARED_REQUIRES(Locks::mutator_lock_) { 635 return LookupStringId(PrettyDescriptor(c)); 636 } 637 638 void WriteFixedHeader() { 639 // Write the file header. 640 // U1: NUL-terminated magic string. 641 const char magic[] = "JAVA PROFILE 1.0.3"; 642 __ AddU1List(reinterpret_cast<const uint8_t*>(magic), sizeof(magic)); 643 644 // U4: size of identifiers. We're using addresses as IDs and our heap references are stored 645 // as uint32_t. 646 // Note of warning: hprof-conv hard-codes the size of identifiers to 4. 647 static_assert(sizeof(mirror::HeapReference<mirror::Object>) == sizeof(uint32_t), 648 "Unexpected HeapReference size"); 649 __ AddU4(sizeof(uint32_t)); 650 651 // The current time, in milliseconds since 0:00 GMT, 1/1/70. 652 timeval now; 653 const uint64_t nowMs = (gettimeofday(&now, nullptr) < 0) ? 0 : 654 (uint64_t)now.tv_sec * 1000 + now.tv_usec / 1000; 655 // TODO: It seems it would be correct to use U8. 656 // U4: high word of the 64-bit time. 657 __ AddU4(static_cast<uint32_t>(nowMs >> 32)); 658 // U4: low word of the 64-bit time. 659 __ AddU4(static_cast<uint32_t>(nowMs & 0xFFFFFFFF)); 660 } 661 662 void WriteStackTraces() SHARED_REQUIRES(Locks::mutator_lock_) { 663 // Write a dummy stack trace record so the analysis tools don't freak out. 664 output_->StartNewRecord(HPROF_TAG_STACK_TRACE, kHprofTime); 665 __ AddStackTraceSerialNumber(kHprofNullStackTrace); 666 __ AddU4(kHprofNullThread); 667 __ AddU4(0); // no frames 668 669 // TODO: jhat complains "WARNING: Stack trace not found for serial # -1", but no trace should 670 // have -1 as its serial number (as long as HprofStackTraceSerialNumber doesn't overflow). 671 for (const auto& it : traces_) { 672 const gc::AllocRecordStackTrace* trace = it.first; 673 HprofStackTraceSerialNumber trace_sn = it.second; 674 size_t depth = trace->GetDepth(); 675 676 // First write stack frames of the trace 677 for (size_t i = 0; i < depth; ++i) { 678 const gc::AllocRecordStackTraceElement* frame = &trace->GetStackElement(i); 679 ArtMethod* method = frame->GetMethod(); 680 CHECK(method != nullptr); 681 output_->StartNewRecord(HPROF_TAG_STACK_FRAME, kHprofTime); 682 // STACK FRAME format: 683 // ID: stack frame ID. We use the address of the AllocRecordStackTraceElement object as its ID. 684 // ID: method name string ID 685 // ID: method signature string ID 686 // ID: source file name string ID 687 // U4: class serial number 688 // U4: >0, line number; 0, no line information available; -1, unknown location 689 auto frame_result = frames_.find(frame); 690 CHECK(frame_result != frames_.end()); 691 __ AddU4(frame_result->second); 692 __ AddStringId(LookupStringId(method->GetName())); 693 __ AddStringId(LookupStringId(method->GetSignature().ToString())); 694 const char* source_file = method->GetDeclaringClassSourceFile(); 695 if (source_file == nullptr) { 696 source_file = ""; 697 } 698 __ AddStringId(LookupStringId(source_file)); 699 auto class_result = classes_.find(method->GetDeclaringClass()); 700 CHECK(class_result != classes_.end()); 701 __ AddU4(class_result->second); 702 __ AddU4(frame->ComputeLineNumber()); 703 } 704 705 // Then write the trace itself 706 output_->StartNewRecord(HPROF_TAG_STACK_TRACE, kHprofTime); 707 // STACK TRACE format: 708 // U4: stack trace serial number. We use the address of the AllocRecordStackTrace object as its serial number. 709 // U4: thread serial number. We use Thread::GetTid(). 710 // U4: number of frames 711 // [ID]*: series of stack frame ID's 712 __ AddStackTraceSerialNumber(trace_sn); 713 __ AddU4(trace->GetTid()); 714 __ AddU4(depth); 715 for (size_t i = 0; i < depth; ++i) { 716 const gc::AllocRecordStackTraceElement* frame = &trace->GetStackElement(i); 717 auto frame_result = frames_.find(frame); 718 CHECK(frame_result != frames_.end()); 719 __ AddU4(frame_result->second); 720 } 721 } 722 } 723 724 bool DumpToDdmsBuffered(size_t overall_size ATTRIBUTE_UNUSED, size_t max_length ATTRIBUTE_UNUSED) 725 REQUIRES(Locks::mutator_lock_) { 726 LOG(FATAL) << "Unimplemented"; 727 UNREACHABLE(); 728 // // Send the data off to DDMS. 729 // iovec iov[2]; 730 // iov[0].iov_base = header_data_ptr_; 731 // iov[0].iov_len = header_data_size_; 732 // iov[1].iov_base = body_data_ptr_; 733 // iov[1].iov_len = body_data_size_; 734 // Dbg::DdmSendChunkV(CHUNK_TYPE("HPDS"), iov, 2); 735 } 736 737 bool DumpToFile(size_t overall_size, size_t max_length) 738 REQUIRES(Locks::mutator_lock_) { 739 // Where exactly are we writing to? 740 int out_fd; 741 if (fd_ >= 0) { 742 out_fd = dup(fd_); 743 if (out_fd < 0) { 744 ThrowRuntimeException("Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno)); 745 return false; 746 } 747 } else { 748 out_fd = open(filename_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644); 749 if (out_fd < 0) { 750 ThrowRuntimeException("Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(), 751 strerror(errno)); 752 return false; 753 } 754 } 755 756 std::unique_ptr<File> file(new File(out_fd, filename_, true)); 757 bool okay; 758 { 759 FileEndianOutput file_output(file.get(), max_length); 760 output_ = &file_output; 761 ProcessHeap(true); 762 okay = !file_output.Errors(); 763 764 if (okay) { 765 // Check for expected size. Output is expected to be less-or-equal than first phase, see 766 // b/23521263. 767 DCHECK_LE(file_output.SumLength(), overall_size); 768 } 769 output_ = nullptr; 770 } 771 772 if (okay) { 773 okay = file->FlushCloseOrErase() == 0; 774 } else { 775 file->Erase(); 776 } 777 if (!okay) { 778 std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", 779 filename_.c_str(), strerror(errno))); 780 ThrowRuntimeException("%s", msg.c_str()); 781 LOG(ERROR) << msg; 782 } 783 784 return okay; 785 } 786 787 bool DumpToDdmsDirect(size_t overall_size, size_t max_length, uint32_t chunk_type) 788 REQUIRES(Locks::mutator_lock_) { 789 CHECK(direct_to_ddms_); 790 JDWP::JdwpState* state = Dbg::GetJdwpState(); 791 CHECK(state != nullptr); 792 JDWP::JdwpNetStateBase* net_state = state->netState; 793 CHECK(net_state != nullptr); 794 795 // Hold the socket lock for the whole time since we want this to be atomic. 796 MutexLock mu(Thread::Current(), *net_state->GetSocketLock()); 797 798 // Prepare the Ddms chunk. 799 constexpr size_t kChunkHeaderSize = kJDWPHeaderLen + 8; 800 uint8_t chunk_header[kChunkHeaderSize] = { 0 }; 801 state->SetupChunkHeader(chunk_type, overall_size, kChunkHeaderSize, chunk_header); 802 803 // Prepare the output and send the chunk header. 804 NetStateEndianOutput net_output(net_state, max_length); 805 output_ = &net_output; 806 net_output.AddU1List(chunk_header, kChunkHeaderSize); 807 808 // Write the dump. 809 ProcessHeap(true); 810 811 // Check for expected size. See DumpToFile for comment. 812 DCHECK_LE(net_output.SumLength(), overall_size + kChunkHeaderSize); 813 output_ = nullptr; 814 815 return true; 816 } 817 818 void PopulateAllocationTrackingTraces() 819 REQUIRES(Locks::mutator_lock_, Locks::alloc_tracker_lock_) { 820 gc::AllocRecordObjectMap* records = Runtime::Current()->GetHeap()->GetAllocationRecords(); 821 CHECK(records != nullptr); 822 HprofStackTraceSerialNumber next_trace_sn = kHprofNullStackTrace + 1; 823 HprofStackFrameId next_frame_id = 0; 824 size_t count = 0; 825 826 for (auto it = records->Begin(), end = records->End(); it != end; ++it) { 827 const mirror::Object* obj = it->first.Read(); 828 if (obj == nullptr) { 829 continue; 830 } 831 ++count; 832 const gc::AllocRecordStackTrace* trace = it->second.GetStackTrace(); 833 834 // Copy the pair into a real hash map to speed up look up. 835 auto records_result = allocation_records_.emplace(obj, trace); 836 // The insertion should always succeed, i.e. no duplicate object pointers in "records" 837 CHECK(records_result.second); 838 839 // Generate serial numbers for traces, and IDs for frames. 840 auto traces_result = traces_.find(trace); 841 if (traces_result == traces_.end()) { 842 traces_.emplace(trace, next_trace_sn++); 843 // only check frames if the trace is newly discovered 844 for (size_t i = 0, depth = trace->GetDepth(); i < depth; ++i) { 845 const gc::AllocRecordStackTraceElement* frame = &trace->GetStackElement(i); 846 auto frames_result = frames_.find(frame); 847 if (frames_result == frames_.end()) { 848 frames_.emplace(frame, next_frame_id++); 849 } 850 } 851 } 852 } 853 CHECK_EQ(traces_.size(), next_trace_sn - kHprofNullStackTrace - 1); 854 CHECK_EQ(frames_.size(), next_frame_id); 855 total_objects_with_stack_trace_ = count; 856 } 857 858 // If direct_to_ddms_ is set, "filename_" and "fd" will be ignored. 859 // Otherwise, "filename_" must be valid, though if "fd" >= 0 it will 860 // only be used for debug messages. 861 std::string filename_; 862 int fd_; 863 bool direct_to_ddms_; 864 865 uint64_t start_ns_ = NanoTime(); 866 867 EndianOutput* output_ = nullptr; 868 869 HprofHeapId current_heap_ = HPROF_HEAP_DEFAULT; // Which heap we're currently dumping. 870 size_t objects_in_segment_ = 0; 871 872 size_t total_objects_ = 0u; 873 size_t total_objects_with_stack_trace_ = 0u; 874 875 HprofStringId next_string_id_ = 0x400000; 876 SafeMap<std::string, HprofStringId> strings_; 877 HprofClassSerialNumber next_class_serial_number_ = 1; 878 SafeMap<mirror::Class*, HprofClassSerialNumber> classes_; 879 880 std::unordered_map<const gc::AllocRecordStackTrace*, HprofStackTraceSerialNumber, 881 gc::HashAllocRecordTypesPtr<gc::AllocRecordStackTrace>, 882 gc::EqAllocRecordTypesPtr<gc::AllocRecordStackTrace>> traces_; 883 std::unordered_map<const gc::AllocRecordStackTraceElement*, HprofStackFrameId, 884 gc::HashAllocRecordTypesPtr<gc::AllocRecordStackTraceElement>, 885 gc::EqAllocRecordTypesPtr<gc::AllocRecordStackTraceElement>> frames_; 886 std::unordered_map<const mirror::Object*, const gc::AllocRecordStackTrace*> allocation_records_; 887 888 // Set used to keep track of what simple root records we have already 889 // emitted, to avoid emitting duplicate entries. The simple root records are 890 // those that contain no other information than the root type and the object 891 // id. A pair of root type and object id is packed into a uint64_t, with 892 // the root type in the upper 32 bits and the object id in the lower 32 893 // bits. 894 std::unordered_set<uint64_t> simple_roots_; 895 896 friend class GcRootVisitor; 897 DISALLOW_COPY_AND_ASSIGN(Hprof); 898 }; 899 900 static HprofBasicType SignatureToBasicTypeAndSize(const char* sig, size_t* size_out) { 901 char c = sig[0]; 902 HprofBasicType ret; 903 size_t size; 904 905 switch (c) { 906 case '[': 907 case 'L': 908 ret = hprof_basic_object; 909 size = 4; 910 break; 911 case 'Z': 912 ret = hprof_basic_boolean; 913 size = 1; 914 break; 915 case 'C': 916 ret = hprof_basic_char; 917 size = 2; 918 break; 919 case 'F': 920 ret = hprof_basic_float; 921 size = 4; 922 break; 923 case 'D': 924 ret = hprof_basic_double; 925 size = 8; 926 break; 927 case 'B': 928 ret = hprof_basic_byte; 929 size = 1; 930 break; 931 case 'S': 932 ret = hprof_basic_short; 933 size = 2; 934 break; 935 case 'I': 936 ret = hprof_basic_int; 937 size = 4; 938 break; 939 case 'J': 940 ret = hprof_basic_long; 941 size = 8; 942 break; 943 default: 944 LOG(FATAL) << "UNREACHABLE"; 945 UNREACHABLE(); 946 } 947 948 if (size_out != nullptr) { 949 *size_out = size; 950 } 951 952 return ret; 953 } 954 955 // Always called when marking objects, but only does 956 // something when ctx->gc_scan_state_ is non-zero, which is usually 957 // only true when marking the root set or unreachable 958 // objects. Used to add rootset references to obj. 959 void Hprof::MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 960 uint32_t thread_serial) { 961 if (heap_tag == 0) { 962 return; 963 } 964 965 CheckHeapSegmentConstraints(); 966 967 switch (heap_tag) { 968 // ID: object ID 969 case HPROF_ROOT_UNKNOWN: 970 case HPROF_ROOT_STICKY_CLASS: 971 case HPROF_ROOT_MONITOR_USED: 972 case HPROF_ROOT_INTERNED_STRING: 973 case HPROF_ROOT_DEBUGGER: 974 case HPROF_ROOT_VM_INTERNAL: { 975 uint64_t key = (static_cast<uint64_t>(heap_tag) << 32) | PointerToLowMemUInt32(obj); 976 if (simple_roots_.insert(key).second) { 977 __ AddU1(heap_tag); 978 __ AddObjectId(obj); 979 } 980 break; 981 } 982 983 // ID: object ID 984 // ID: JNI global ref ID 985 case HPROF_ROOT_JNI_GLOBAL: 986 __ AddU1(heap_tag); 987 __ AddObjectId(obj); 988 __ AddJniGlobalRefId(jni_obj); 989 break; 990 991 // ID: object ID 992 // U4: thread serial number 993 // U4: frame number in stack trace (-1 for empty) 994 case HPROF_ROOT_JNI_LOCAL: 995 case HPROF_ROOT_JNI_MONITOR: 996 case HPROF_ROOT_JAVA_FRAME: 997 __ AddU1(heap_tag); 998 __ AddObjectId(obj); 999 __ AddU4(thread_serial); 1000 __ AddU4((uint32_t)-1); 1001 break; 1002 1003 // ID: object ID 1004 // U4: thread serial number 1005 case HPROF_ROOT_NATIVE_STACK: 1006 case HPROF_ROOT_THREAD_BLOCK: 1007 __ AddU1(heap_tag); 1008 __ AddObjectId(obj); 1009 __ AddU4(thread_serial); 1010 break; 1011 1012 // ID: thread object ID 1013 // U4: thread serial number 1014 // U4: stack trace serial number 1015 case HPROF_ROOT_THREAD_OBJECT: 1016 __ AddU1(heap_tag); 1017 __ AddObjectId(obj); 1018 __ AddU4(thread_serial); 1019 __ AddU4((uint32_t)-1); // xxx 1020 break; 1021 1022 case HPROF_CLASS_DUMP: 1023 case HPROF_INSTANCE_DUMP: 1024 case HPROF_OBJECT_ARRAY_DUMP: 1025 case HPROF_PRIMITIVE_ARRAY_DUMP: 1026 case HPROF_HEAP_DUMP_INFO: 1027 case HPROF_PRIMITIVE_ARRAY_NODATA_DUMP: 1028 // Ignored. 1029 break; 1030 1031 case HPROF_ROOT_FINALIZING: 1032 case HPROF_ROOT_REFERENCE_CLEANUP: 1033 case HPROF_UNREACHABLE: 1034 LOG(FATAL) << "obsolete tag " << static_cast<int>(heap_tag); 1035 break; 1036 } 1037 1038 ++objects_in_segment_; 1039 } 1040 1041 // Use for visiting the GcRoots held live by ArtFields, ArtMethods, and ClassLoaders. 1042 class GcRootVisitor { 1043 public: 1044 explicit GcRootVisitor(Hprof* hprof) : hprof_(hprof) {} 1045 1046 void operator()(mirror::Object* obj ATTRIBUTE_UNUSED, 1047 MemberOffset offset ATTRIBUTE_UNUSED, 1048 bool is_static ATTRIBUTE_UNUSED) const {} 1049 1050 // Note that these don't have read barriers. Its OK however since the GC is guaranteed to not be 1051 // running during the hprof dumping process. 1052 void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const 1053 SHARED_REQUIRES(Locks::mutator_lock_) { 1054 if (!root->IsNull()) { 1055 VisitRoot(root); 1056 } 1057 } 1058 1059 void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const 1060 SHARED_REQUIRES(Locks::mutator_lock_) { 1061 mirror::Object* obj = root->AsMirrorPtr(); 1062 // The two cases are either classes or dex cache arrays. If it is a dex cache array, then use 1063 // VM internal. Otherwise the object is a declaring class of an ArtField or ArtMethod or a 1064 // class from a ClassLoader. 1065 hprof_->VisitRoot(obj, RootInfo(obj->IsClass() ? kRootStickyClass : kRootVMInternal)); 1066 } 1067 1068 1069 private: 1070 Hprof* const hprof_; 1071 }; 1072 1073 void Hprof::DumpHeapObject(mirror::Object* obj) { 1074 // Ignore classes that are retired. 1075 if (obj->IsClass() && obj->AsClass()->IsRetired()) { 1076 return; 1077 } 1078 1079 ++total_objects_; 1080 1081 GcRootVisitor visitor(this); 1082 obj->VisitReferences(visitor, VoidFunctor()); 1083 1084 gc::Heap* const heap = Runtime::Current()->GetHeap(); 1085 const gc::space::ContinuousSpace* const space = heap->FindContinuousSpaceFromObject(obj, true); 1086 HprofHeapId heap_type = HPROF_HEAP_APP; 1087 if (space != nullptr) { 1088 if (space->IsZygoteSpace()) { 1089 heap_type = HPROF_HEAP_ZYGOTE; 1090 } else if (space->IsImageSpace()) { 1091 heap_type = HPROF_HEAP_IMAGE; 1092 } 1093 } else { 1094 const auto* los = heap->GetLargeObjectsSpace(); 1095 if (los->Contains(obj) && los->IsZygoteLargeObject(Thread::Current(), obj)) { 1096 heap_type = HPROF_HEAP_ZYGOTE; 1097 } 1098 } 1099 CheckHeapSegmentConstraints(); 1100 1101 if (heap_type != current_heap_) { 1102 HprofStringId nameId; 1103 1104 // This object is in a different heap than the current one. 1105 // Emit a HEAP_DUMP_INFO tag to change heaps. 1106 __ AddU1(HPROF_HEAP_DUMP_INFO); 1107 __ AddU4(static_cast<uint32_t>(heap_type)); // uint32_t: heap type 1108 switch (heap_type) { 1109 case HPROF_HEAP_APP: 1110 nameId = LookupStringId("app"); 1111 break; 1112 case HPROF_HEAP_ZYGOTE: 1113 nameId = LookupStringId("zygote"); 1114 break; 1115 case HPROF_HEAP_IMAGE: 1116 nameId = LookupStringId("image"); 1117 break; 1118 default: 1119 // Internal error 1120 LOG(ERROR) << "Unexpected desiredHeap"; 1121 nameId = LookupStringId("<ILLEGAL>"); 1122 break; 1123 } 1124 __ AddStringId(nameId); 1125 current_heap_ = heap_type; 1126 } 1127 1128 mirror::Class* c = obj->GetClass(); 1129 if (c == nullptr) { 1130 // This object will bother HprofReader, because it has a null 1131 // class, so just don't dump it. It could be 1132 // gDvm.unlinkedJavaLangClass or it could be an object just 1133 // allocated which hasn't been initialized yet. 1134 } else { 1135 if (obj->IsClass()) { 1136 DumpHeapClass(obj->AsClass()); 1137 } else if (c->IsArrayClass()) { 1138 DumpHeapArray(obj->AsArray(), c); 1139 } else { 1140 DumpHeapInstanceObject(obj, c); 1141 } 1142 } 1143 1144 ++objects_in_segment_; 1145 } 1146 1147 void Hprof::DumpHeapClass(mirror::Class* klass) { 1148 if (!klass->IsLoaded() && !klass->IsErroneous()) { 1149 // Class is allocated but not yet loaded: we cannot access its fields or super class. 1150 return; 1151 } 1152 const size_t num_static_fields = klass->NumStaticFields(); 1153 // Total class size including embedded IMT, embedded vtable, and static fields. 1154 const size_t class_size = klass->GetClassSize(); 1155 // Class size excluding static fields (relies on reference fields being the first static fields). 1156 const size_t class_size_without_overhead = sizeof(mirror::Class); 1157 CHECK_LE(class_size_without_overhead, class_size); 1158 const size_t overhead_size = class_size - class_size_without_overhead; 1159 1160 if (overhead_size != 0) { 1161 // Create a byte array to reflect the allocation of the 1162 // StaticField array at the end of this class. 1163 __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 1164 __ AddClassStaticsId(klass); 1165 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(klass)); 1166 __ AddU4(overhead_size); 1167 __ AddU1(hprof_basic_byte); 1168 for (size_t i = 0; i < overhead_size; ++i) { 1169 __ AddU1(0); 1170 } 1171 } 1172 1173 __ AddU1(HPROF_CLASS_DUMP); 1174 __ AddClassId(LookupClassId(klass)); 1175 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(klass)); 1176 __ AddClassId(LookupClassId(klass->GetSuperClass())); 1177 __ AddObjectId(klass->GetClassLoader()); 1178 __ AddObjectId(nullptr); // no signer 1179 __ AddObjectId(nullptr); // no prot domain 1180 __ AddObjectId(nullptr); // reserved 1181 __ AddObjectId(nullptr); // reserved 1182 if (klass->IsClassClass()) { 1183 // ClassObjects have their static fields appended, so aren't all the same size. 1184 // But they're at least this size. 1185 __ AddU4(class_size_without_overhead); // instance size 1186 } else if (klass->IsStringClass()) { 1187 // Strings are variable length with character data at the end like arrays. 1188 // This outputs the size of an empty string. 1189 __ AddU4(sizeof(mirror::String)); 1190 } else if (klass->IsArrayClass() || klass->IsPrimitive()) { 1191 __ AddU4(0); 1192 } else { 1193 __ AddU4(klass->GetObjectSize()); // instance size 1194 } 1195 1196 __ AddU2(0); // empty const pool 1197 1198 // Static fields 1199 if (overhead_size == 0) { 1200 __ AddU2(static_cast<uint16_t>(0)); 1201 } else { 1202 __ AddU2(static_cast<uint16_t>(num_static_fields + 1)); 1203 __ AddStringId(LookupStringId(kClassOverheadName)); 1204 __ AddU1(hprof_basic_object); 1205 __ AddClassStaticsId(klass); 1206 1207 for (size_t i = 0; i < num_static_fields; ++i) { 1208 ArtField* f = klass->GetStaticField(i); 1209 1210 size_t size; 1211 HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 1212 __ AddStringId(LookupStringId(f->GetName())); 1213 __ AddU1(t); 1214 switch (t) { 1215 case hprof_basic_byte: 1216 __ AddU1(f->GetByte(klass)); 1217 break; 1218 case hprof_basic_boolean: 1219 __ AddU1(f->GetBoolean(klass)); 1220 break; 1221 case hprof_basic_char: 1222 __ AddU2(f->GetChar(klass)); 1223 break; 1224 case hprof_basic_short: 1225 __ AddU2(f->GetShort(klass)); 1226 break; 1227 case hprof_basic_float: 1228 case hprof_basic_int: 1229 case hprof_basic_object: 1230 __ AddU4(f->Get32(klass)); 1231 break; 1232 case hprof_basic_double: 1233 case hprof_basic_long: 1234 __ AddU8(f->Get64(klass)); 1235 break; 1236 default: 1237 LOG(FATAL) << "Unexpected size " << size; 1238 UNREACHABLE(); 1239 } 1240 } 1241 } 1242 1243 // Instance fields for this class (no superclass fields) 1244 int iFieldCount = klass->NumInstanceFields(); 1245 if (klass->IsStringClass()) { 1246 __ AddU2((uint16_t)iFieldCount + 1); 1247 } else { 1248 __ AddU2((uint16_t)iFieldCount); 1249 } 1250 for (int i = 0; i < iFieldCount; ++i) { 1251 ArtField* f = klass->GetInstanceField(i); 1252 __ AddStringId(LookupStringId(f->GetName())); 1253 HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), nullptr); 1254 __ AddU1(t); 1255 } 1256 // Add native value character array for strings. 1257 if (klass->IsStringClass()) { 1258 __ AddStringId(LookupStringId("value")); 1259 __ AddU1(hprof_basic_object); 1260 } 1261 } 1262 1263 void Hprof::DumpHeapArray(mirror::Array* obj, mirror::Class* klass) { 1264 uint32_t length = obj->GetLength(); 1265 1266 if (obj->IsObjectArray()) { 1267 // obj is an object array. 1268 __ AddU1(HPROF_OBJECT_ARRAY_DUMP); 1269 1270 __ AddObjectId(obj); 1271 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 1272 __ AddU4(length); 1273 __ AddClassId(LookupClassId(klass)); 1274 1275 // Dump the elements, which are always objects or null. 1276 __ AddIdList(obj->AsObjectArray<mirror::Object>()); 1277 } else { 1278 size_t size; 1279 HprofBasicType t = SignatureToBasicTypeAndSize( 1280 Primitive::Descriptor(klass->GetComponentType()->GetPrimitiveType()), &size); 1281 1282 // obj is a primitive array. 1283 __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 1284 1285 __ AddObjectId(obj); 1286 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 1287 __ AddU4(length); 1288 __ AddU1(t); 1289 1290 // Dump the raw, packed element values. 1291 if (size == 1) { 1292 __ AddU1List(reinterpret_cast<const uint8_t*>(obj->GetRawData(sizeof(uint8_t), 0)), length); 1293 } else if (size == 2) { 1294 __ AddU2List(reinterpret_cast<const uint16_t*>(obj->GetRawData(sizeof(uint16_t), 0)), length); 1295 } else if (size == 4) { 1296 __ AddU4List(reinterpret_cast<const uint32_t*>(obj->GetRawData(sizeof(uint32_t), 0)), length); 1297 } else if (size == 8) { 1298 __ AddU8List(reinterpret_cast<const uint64_t*>(obj->GetRawData(sizeof(uint64_t), 0)), length); 1299 } 1300 } 1301 } 1302 1303 void Hprof::DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) { 1304 // obj is an instance object. 1305 __ AddU1(HPROF_INSTANCE_DUMP); 1306 __ AddObjectId(obj); 1307 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 1308 __ AddClassId(LookupClassId(klass)); 1309 1310 // Reserve some space for the length of the instance data, which we won't 1311 // know until we're done writing it. 1312 size_t size_patch_offset = output_->Length(); 1313 __ AddU4(0x77777777); 1314 1315 // What we will use for the string value if the object is a string. 1316 mirror::Object* string_value = nullptr; 1317 1318 // Write the instance data; fields for this class, followed by super class fields, and so on. 1319 do { 1320 const size_t instance_fields = klass->NumInstanceFields(); 1321 for (size_t i = 0; i < instance_fields; ++i) { 1322 ArtField* f = klass->GetInstanceField(i); 1323 size_t size; 1324 HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 1325 switch (t) { 1326 case hprof_basic_byte: 1327 __ AddU1(f->GetByte(obj)); 1328 break; 1329 case hprof_basic_boolean: 1330 __ AddU1(f->GetBoolean(obj)); 1331 break; 1332 case hprof_basic_char: 1333 __ AddU2(f->GetChar(obj)); 1334 break; 1335 case hprof_basic_short: 1336 __ AddU2(f->GetShort(obj)); 1337 break; 1338 case hprof_basic_float: 1339 case hprof_basic_int: 1340 case hprof_basic_object: 1341 __ AddU4(f->Get32(obj)); 1342 break; 1343 case hprof_basic_double: 1344 case hprof_basic_long: 1345 __ AddU8(f->Get64(obj)); 1346 break; 1347 } 1348 } 1349 // Add value field for String if necessary. 1350 if (klass->IsStringClass()) { 1351 mirror::String* s = obj->AsString(); 1352 if (s->GetLength() == 0) { 1353 // If string is empty, use an object-aligned address within the string for the value. 1354 string_value = reinterpret_cast<mirror::Object*>( 1355 reinterpret_cast<uintptr_t>(s) + kObjectAlignment); 1356 } else { 1357 string_value = reinterpret_cast<mirror::Object*>(s->GetValue()); 1358 } 1359 __ AddObjectId(string_value); 1360 } 1361 1362 klass = klass->GetSuperClass(); 1363 } while (klass != nullptr); 1364 1365 // Patch the instance field length. 1366 __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4)); 1367 1368 // Output native value character array for strings. 1369 CHECK_EQ(obj->IsString(), string_value != nullptr); 1370 if (string_value != nullptr) { 1371 mirror::String* s = obj->AsString(); 1372 __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 1373 __ AddObjectId(string_value); 1374 __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 1375 __ AddU4(s->GetLength()); 1376 __ AddU1(hprof_basic_char); 1377 __ AddU2List(s->GetValue(), s->GetLength()); 1378 } 1379 } 1380 1381 void Hprof::VisitRoot(mirror::Object* obj, const RootInfo& info) { 1382 static const HprofHeapTag xlate[] = { 1383 HPROF_ROOT_UNKNOWN, 1384 HPROF_ROOT_JNI_GLOBAL, 1385 HPROF_ROOT_JNI_LOCAL, 1386 HPROF_ROOT_JAVA_FRAME, 1387 HPROF_ROOT_NATIVE_STACK, 1388 HPROF_ROOT_STICKY_CLASS, 1389 HPROF_ROOT_THREAD_BLOCK, 1390 HPROF_ROOT_MONITOR_USED, 1391 HPROF_ROOT_THREAD_OBJECT, 1392 HPROF_ROOT_INTERNED_STRING, 1393 HPROF_ROOT_FINALIZING, 1394 HPROF_ROOT_DEBUGGER, 1395 HPROF_ROOT_REFERENCE_CLEANUP, 1396 HPROF_ROOT_VM_INTERNAL, 1397 HPROF_ROOT_JNI_MONITOR, 1398 }; 1399 CHECK_LT(info.GetType(), sizeof(xlate) / sizeof(HprofHeapTag)); 1400 if (obj == nullptr) { 1401 return; 1402 } 1403 MarkRootObject(obj, 0, xlate[info.GetType()], info.GetThreadId()); 1404 } 1405 1406 // If "direct_to_ddms" is true, the other arguments are ignored, and data is 1407 // sent directly to DDMS. 1408 // If "fd" is >= 0, the output will be written to that file descriptor. 1409 // Otherwise, "filename" is used to create an output file. 1410 void DumpHeap(const char* filename, int fd, bool direct_to_ddms) { 1411 CHECK(filename != nullptr); 1412 1413 Thread* self = Thread::Current(); 1414 gc::Heap* heap = Runtime::Current()->GetHeap(); 1415 if (heap->IsGcConcurrentAndMoving()) { 1416 // Need to take a heap dump while GC isn't running. See the 1417 // comment in Heap::VisitObjects(). 1418 heap->IncrementDisableMovingGC(self); 1419 } 1420 { 1421 ScopedSuspendAll ssa(__FUNCTION__, true /* long suspend */); 1422 Hprof hprof(filename, fd, direct_to_ddms); 1423 hprof.Dump(); 1424 } 1425 if (heap->IsGcConcurrentAndMoving()) { 1426 heap->DecrementDisableMovingGC(self); 1427 } 1428 } 1429 1430 } // namespace hprof 1431 } // namespace art 1432