xref: /aosp_15_r20/external/leakcanary2/shark-hprof/src/main/java/shark/HprofRecord.kt (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)
1 package shark
2 
3 /**
4  * A Hprof record. These data structure map 1:1 with how records are written in hprof files.
5  */
6 sealed class HprofRecord {
7   class StringRecord(
8     val id: Long,
9     val string: String
10   ) : HprofRecord()
11 
12   class LoadClassRecord(
13     val classSerialNumber: Int,
14     val id: Long,
15     val stackTraceSerialNumber: Int,
16     val classNameStringId: Long
17   ) : HprofRecord()
18 
19   /**
20    * Terminates a series of heap dump segments. Concatenation of heap dump segments equals a
21    * heap dump.
22    */
23   object HeapDumpEndRecord : HprofRecord()
24 
25   class StackFrameRecord(
26     val id: Long,
27     val methodNameStringId: Long,
28     val methodSignatureStringId: Long,
29     val sourceFileNameStringId: Long,
30     val classSerialNumber: Int,
31     /**
32      * >0 line number
33      * 0 no line information available
34      * -1 unknown location
35      * -2 compiled method (Not implemented)
36      * -3 native method (Not implemented)
37      */
38     val lineNumber: Int
39   ) : HprofRecord()
40 
41   class StackTraceRecord(
42     val stackTraceSerialNumber: Int,
43     val threadSerialNumber: Int,
44     val stackFrameIds: LongArray
45   ) : HprofRecord()
46 
47   sealed class HeapDumpRecord : HprofRecord() {
48     class GcRootRecord(
49       val gcRoot: GcRoot
50     ) : HeapDumpRecord()
51 
52     sealed class ObjectRecord : HeapDumpRecord() {
53       class ClassDumpRecord(
54         val id: Long,
55         val stackTraceSerialNumber: Int,
56         val superclassId: Long,
57         val classLoaderId: Long,
58         val signersId: Long,
59         val protectionDomainId: Long,
60         val instanceSize: Int,
61         val staticFields: List<StaticFieldRecord>,
62         val fields: List<FieldRecord>
63       ) : ObjectRecord() {
64         data class StaticFieldRecord(
65           val nameStringId: Long,
66           val type: Int,
67           val value: ValueHolder
68         )
69 
70         data class FieldRecord(
71           val nameStringId: Long,
72           val type: Int
73         )
74       }
75 
76       class InstanceDumpRecord(
77         val id: Long,
78         val stackTraceSerialNumber: Int,
79         val classId: Long,
80         /**
81          * Instance field values (this class, followed by super class, etc)
82          */
83         val fieldValues: ByteArray
84       ) : ObjectRecord()
85 
86       class ObjectArrayDumpRecord(
87         val id: Long,
88         val stackTraceSerialNumber: Int,
89         val arrayClassId: Long,
90         val elementIds: LongArray
91       ) : ObjectRecord()
92 
93       sealed class PrimitiveArrayDumpRecord : ObjectRecord() {
94         abstract val id: Long
95         abstract val stackTraceSerialNumber: Int
96         abstract val size: Int
97 
98         class BooleanArrayDump(
99           override val id: Long,
100           override val stackTraceSerialNumber: Int,
101           val array: BooleanArray
102         ) : PrimitiveArrayDumpRecord() {
103           override val size: Int
104             get() = array.size
105         }
106 
107         class CharArrayDump(
108           override val id: Long,
109           override val stackTraceSerialNumber: Int,
110           val array: CharArray
111         ) : PrimitiveArrayDumpRecord() {
112           override val size: Int
113             get() = array.size
114         }
115 
116         class FloatArrayDump(
117           override val id: Long,
118           override val stackTraceSerialNumber: Int,
119           val array: FloatArray
120         ) : PrimitiveArrayDumpRecord() {
121           override val size: Int
122             get() = array.size
123         }
124 
125         class DoubleArrayDump(
126           override val id: Long,
127           override val stackTraceSerialNumber: Int,
128           val array: DoubleArray
129         ) : PrimitiveArrayDumpRecord() {
130           override val size: Int
131             get() = array.size
132         }
133 
134         class ByteArrayDump(
135           override val id: Long,
136           override val stackTraceSerialNumber: Int,
137           val array: ByteArray
138         ) : PrimitiveArrayDumpRecord() {
139           override val size: Int
140             get() = array.size
141         }
142 
143         class ShortArrayDump(
144           override val id: Long,
145           override val stackTraceSerialNumber: Int,
146           val array: ShortArray
147         ) : PrimitiveArrayDumpRecord() {
148           override val size: Int
149             get() = array.size
150         }
151 
152         class IntArrayDump(
153           override val id: Long,
154           override val stackTraceSerialNumber: Int,
155           val array: IntArray
156         ) : PrimitiveArrayDumpRecord() {
157           override val size: Int
158             get() = array.size
159         }
160 
161         class LongArrayDump(
162           override val id: Long,
163           override val stackTraceSerialNumber: Int,
164           val array: LongArray
165         ) : PrimitiveArrayDumpRecord() {
166           override val size: Int
167             get() = array.size
168         }
169       }
170     }
171 
172     class HeapDumpInfoRecord(
173       val heapId: Int,
174       val heapNameStringId: Long
175     ) : HeapDumpRecord()
176   }
177 }