main

square/leakcanary

Last updated at: 29/12/2023 09:39

HprofRecord.kt

TLDR

The file HprofRecord.kt in the Demo Projects project contains the definition of various classes and sealed subclasses related to parsing and processing Hprof records. These classes represent different types of records and their associated data structures found in Hprof files.

Classes

HprofRecord

This sealed class represents a Hprof record. It is the base class for all the record types defined in this file.

StringRecord

This class represents a Hprof string record. It contains an ID and the actual string value.

LoadClassRecord

This class represents a Hprof load class record. It contains the class serial number, ID, stack trace serial number, and the ID of the class name string.

HeapDumpEndRecord

This object represents the end of a series of heap dump segments. It signifies the end of a heap dump.

StackFrameRecord

This class represents a Hprof stack frame record. It contains an ID, method name string ID, method signature string ID, source file name string ID, class serial number, and line number information.

StackTraceRecord

This class represents a Hprof stack trace record. It contains the stack trace serial number, thread serial number, and an array of stack frame IDs.

GcRootRecord

This class represents a Hprof GC root record. It contains the GC root.

ClassDumpRecord

This class represents a Hprof class dump record. It contains the ID, stack trace serial number, superclass ID, class loader ID, signers ID, protection domain ID, instance size, a list of static field records, and a list of field records.

InstanceDumpRecord

This class represents a Hprof instance dump record. It contains the ID, stack trace serial number, class ID, and an array of field values.

ObjectArrayDumpRecord

This class represents a Hprof object array dump record. It contains the ID, stack trace serial number, array class ID, and an array of element IDs.

PrimitiveArrayDumpRecord

This sealed class represents a Hprof primitive array dump record. It is the base class for primitive array dump records of different types.

  • BooleanArrayDump: This subclass represents a Hprof boolean array dump record.
  • CharArrayDump: This subclass represents a Hprof char array dump record.
  • FloatArrayDump: This subclass represents a Hprof float array dump record.
  • DoubleArrayDump: This subclass represents a Hprof double array dump record.
  • ByteArrayDump: This subclass represents a Hprof byte array dump record.
  • ShortArrayDump: This subclass represents a Hprof short array dump record.
  • IntArrayDump: This subclass represents a Hprof int array dump record.
  • LongArrayDump: This subclass represents a Hprof long array dump record.

HeapDumpInfoRecord

This class represents a Hprof heap dump info record. It contains the heap ID and the ID of the heap name string.

package shark

/**
 * A Hprof record. These data structure map 1:1 with how records are written in hprof files.
 */
sealed class HprofRecord {
  class StringRecord(
    val id: Long,
    val string: String
  ) : HprofRecord()

  class LoadClassRecord(
    val classSerialNumber: Int,
    val id: Long,
    val stackTraceSerialNumber: Int,
    val classNameStringId: Long
  ) : HprofRecord()

  /**
   * Terminates a series of heap dump segments. Concatenation of heap dump segments equals a
   * heap dump.
   */
  object HeapDumpEndRecord : HprofRecord()

  class StackFrameRecord(
    val id: Long,
    val methodNameStringId: Long,
    val methodSignatureStringId: Long,
    val sourceFileNameStringId: Long,
    val classSerialNumber: Int,
    /**
     * >0 line number
     * 0 no line information available
     * -1 unknown location
     * -2 compiled method (Not implemented)
     * -3 native method (Not implemented)
     */
    val lineNumber: Int
  ) : HprofRecord()

  class StackTraceRecord(
    val stackTraceSerialNumber: Int,
    val threadSerialNumber: Int,
    val stackFrameIds: LongArray
  ) : HprofRecord()

  sealed class HeapDumpRecord : HprofRecord() {
    class GcRootRecord(
      val gcRoot: GcRoot
    ) : HeapDumpRecord()

    sealed class ObjectRecord : HeapDumpRecord() {
      class ClassDumpRecord(
        val id: Long,
        val stackTraceSerialNumber: Int,
        val superclassId: Long,
        val classLoaderId: Long,
        val signersId: Long,
        val protectionDomainId: Long,
        val instanceSize: Int,
        val staticFields: List<StaticFieldRecord>,
        val fields: List<FieldRecord>
      ) : ObjectRecord() {
        data class StaticFieldRecord(
          val nameStringId: Long,
          val type: Int,
          val value: ValueHolder
        )

        data class FieldRecord(
          val nameStringId: Long,
          val type: Int
        )
      }

      class InstanceDumpRecord(
        val id: Long,
        val stackTraceSerialNumber: Int,
        val classId: Long,
        /**
         * Instance field values (this class, followed by super class, etc)
         */
        val fieldValues: ByteArray
      ) : ObjectRecord()

      class ObjectArrayDumpRecord(
        val id: Long,
        val stackTraceSerialNumber: Int,
        val arrayClassId: Long,
        val elementIds: LongArray
      ) : ObjectRecord()

      sealed class PrimitiveArrayDumpRecord : ObjectRecord() {
        abstract val id: Long
        abstract val stackTraceSerialNumber: Int
        abstract val size: Int

        class BooleanArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: BooleanArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class CharArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: CharArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class FloatArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: FloatArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class DoubleArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: DoubleArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class ByteArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: ByteArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class ShortArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: ShortArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class IntArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: IntArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }

        class LongArrayDump(
          override val id: Long,
          override val stackTraceSerialNumber: Int,
          val array: LongArray
        ) : PrimitiveArrayDumpRecord() {
          override val size: Int
            get() = array.size
        }
      }
    }

    class HeapDumpInfoRecord(
      val heapId: Int,
      val heapNameStringId: Long
    ) : HeapDumpRecord()
  }
}