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