1 package shark 2 3 import shark.ValueHolder.BooleanHolder 4 import shark.ValueHolder.ByteHolder 5 import shark.ValueHolder.CharHolder 6 import shark.ValueHolder.DoubleHolder 7 import shark.ValueHolder.FloatHolder 8 import shark.ValueHolder.IntHolder 9 import shark.ValueHolder.LongHolder 10 import shark.ValueHolder.ReferenceHolder 11 import shark.ValueHolder.ShortHolder 12 13 /** 14 * Represents a value in the heap dump, which can be an object reference or 15 * a primitive type. 16 */ 17 class HeapValue( 18 /** 19 * The graph of objects in the heap, which you can use to navigate the heap. 20 */ 21 val graph: HeapGraph, 22 /** 23 * Holds the actual value that this [HeapValue] represents. 24 */ 25 val holder: ValueHolder 26 ) { 27 28 /** 29 * This [HeapValue] as a [Boolean] if it represents one, or null otherwise. 30 */ 31 val asBoolean: Boolean? 32 get() = if (holder is BooleanHolder) holder.value else null 33 34 /** 35 * This [HeapValue] as a [Char] if it represents one, or null otherwise. 36 */ 37 val asChar: Char? 38 get() = if (holder is CharHolder) holder.value else null 39 40 /** 41 * This [HeapValue] as a [Float] if it represents one, or null otherwise. 42 */ 43 val asFloat: Float? 44 get() = if (holder is FloatHolder) holder.value else null 45 46 /** 47 * This [HeapValue] as a [Double] if it represents one, or null otherwise. 48 */ 49 val asDouble: Double? 50 get() = if (holder is DoubleHolder) holder.value else null 51 52 /** 53 * This [HeapValue] as a [Byte] if it represents one, or null otherwise. 54 */ 55 val asByte: Byte? 56 get() = if (holder is ByteHolder) holder.value else null 57 58 /** 59 * This [HeapValue] as a [Short] if it represents one, or null otherwise. 60 */ 61 val asShort: Short? 62 get() = if (holder is ShortHolder) holder.value else null 63 64 /** 65 * This [HeapValue] as an [Int] if it represents one, or null otherwise. 66 */ 67 val asInt: Int? 68 get() = if (holder is IntHolder) holder.value else null 69 70 /** 71 * This [HeapValue] as a [Long] if it represents one, or null otherwise. 72 */ 73 val asLong: Long? 74 get() = if (holder is LongHolder) holder.value else null 75 76 /** 77 * This [HeapValue] as a [Long] if it represents an object reference, or null otherwise. 78 */ 79 val asObjectId: Long? 80 get() = if (holder is ReferenceHolder) holder.value else null 81 82 /** 83 * This [HeapValue] as a [Long] if it represents a non null object reference, or null otherwise. 84 */ 85 val asNonNullObjectId: Long? 86 get() = if (holder is ReferenceHolder && !holder.isNull) holder.value else null 87 88 /** 89 * True is this [HeapValue] represents a null object reference, false otherwise. 90 */ 91 val isNullReference: Boolean 92 get() = holder is ReferenceHolder && holder.isNull 93 94 /** 95 * True is this [HeapValue] represents a non null object reference, false otherwise. 96 */ 97 val isNonNullReference: Boolean 98 get() = holder is ReferenceHolder && !holder.isNull 99 100 /** 101 * The [HeapObject] referenced by this [HeapValue] if it represents a non null object reference, 102 * or null otherwise. 103 */ 104 val asObject: HeapObject? 105 get() { 106 return if (holder is ReferenceHolder && !holder.isNull) { 107 return graph.findObjectById(holder.value) 108 } else { 109 null 110 } 111 } 112 113 /** 114 * If this [HeapValue] if it represents a non null object reference to an instance of the 115 * [String] class that exists in the heap dump, returns a [String] instance with content that 116 * matches the string in the heap dump. Otherwise returns null. 117 * 118 * This may trigger IO reads. 119 */ readAsJavaStringnull120 fun readAsJavaString(): String? { 121 if (holder is ReferenceHolder && !holder.isNull) { 122 val heapObject = graph.findObjectByIdOrNull(holder.value) 123 return heapObject?.asInstance?.readAsJavaString() 124 } 125 return null 126 } 127 } 128