1 package shark 2 3 import shark.HeapObject.HeapInstance 4 5 /** 6 * The system identity hash code, or null if it couldn't be found. 7 * 8 * Based on the Object.identityHashCode implementation in AOSP. 9 * 10 * Backing field shadow$_monitor_ was added in API 24. 11 * https://cs.android.com/android/_/android/platform/libcore/+ 12 * /de626ec8a109ea18283d96c720cc57e2f32f67fa:ojluni/src/main/java/java/lang/Object.java; 13 * dlc=ba7cc9f5357c323a1006119a20ce025fd4c57fd2 14 */ 15 val HeapInstance.identityHashCode: Int? 16 get() { 17 // Top 2 bits. 18 val lockWordStateMask = -0x40000000 19 // Top 2 bits are value 2 (kStateHash). 20 val lockWordStateHash = -0x80000000 21 // Low 28 bits. 22 val lockWordHashMask = 0x0FFFFFFF 23 val lockWord = this["java.lang.Object", "shadow\$_monitor_"]?.value?.asInt 24 return if (lockWord != null && lockWord and lockWordStateMask == lockWordStateHash) { 25 lockWord and lockWordHashMask 26 } else null 27 } 28 29 /** 30 * The system identity hashCode represented as hex, or null if it couldn't be found. 31 * This is the string identifier you see when calling Object.toString() at runtime on a class that 32 * does not override its hashCode() method, e.g. com.example.MyThing@6bd57cf 33 */ 34 val HeapInstance.hexIdentityHashCode: String? 35 get() { 36 val hashCode = identityHashCode ?: return null 37 return Integer.toHexString(hashCode) 38 } 39