-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2365 from square/py/ids
Introduce additional ways to represent object ids
- Loading branch information
Showing
8 changed files
with
154 additions
and
1 deletion.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
leakcanary-android-core/src/androidTest/java/leakcanary/AndroidExtensionsTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package leakcanary | ||
|
||
import android.os.Build.VERSION.SDK_INT | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.Assume.assumeTrue | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.rules.TemporaryFolder | ||
import shark.HprofHeapGraph.Companion.openHeapGraph | ||
import shark.hexIdentityHashCode | ||
|
||
class AndroidExtensionsTest { | ||
|
||
@get:Rule | ||
var testFolder = TemporaryFolder() | ||
|
||
@Test fun identityHashCode() { | ||
assumeTrue("SDK_INT is $SDK_INT, shadow\$_monitor_ was introduced in 21", SDK_INT >= 24) | ||
|
||
// leakcanary.AndroidExtensionsTest@c559955 | ||
val thisToString = toString() | ||
|
||
val heapDumpFile = testFolder.newFile() | ||
AndroidDebugHeapDumper.dumpHeap(heapDumpFile) | ||
|
||
val testClassName = this::class.java.name | ||
|
||
val identityHashCodeFromDump = heapDumpFile.openHeapGraph().use { graph -> | ||
val testClass = graph.findClassByName(testClassName)!! | ||
val testInstance = testClass.instances.single() | ||
testInstance.hexIdentityHashCode | ||
} | ||
|
||
assertThat("$testClassName@$identityHashCodeFromDump").isEqualTo(thisToString) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package shark | ||
|
||
import shark.HeapObject.HeapInstance | ||
|
||
/** | ||
* The system identity hash code, or null if it couldn't be found. | ||
* | ||
* Based on the Object.identityHashCode implementation in AOSP. | ||
* | ||
* Backing field shadow$_monitor_ was added in API 24. | ||
* https://cs.android.com/android/_/android/platform/libcore/+ | ||
* /de626ec8a109ea18283d96c720cc57e2f32f67fa:ojluni/src/main/java/java/lang/Object.java; | ||
* dlc=ba7cc9f5357c323a1006119a20ce025fd4c57fd2 | ||
*/ | ||
val HeapInstance.identityHashCode: Int? | ||
get() { | ||
// Top 2 bits. | ||
val lockWordStateMask = -0x40000000 | ||
// Top 2 bits are value 2 (kStateHash). | ||
val lockWordStateHash = -0x80000000 | ||
// Low 28 bits. | ||
val lockWordHashMask = 0x0FFFFFFF | ||
val lockWord = this["java.lang.Object", "shadow\$_monitor_"]?.value?.asInt | ||
return if (lockWord != null && lockWord and lockWordStateMask == lockWordStateHash) { | ||
lockWord and lockWordHashMask | ||
} else null | ||
} | ||
|
||
/** | ||
* The system identity hashCode represented as hex, or null if it couldn't be found. | ||
* This is the string identifier you see when calling Object.toString() at runtime on a class that | ||
* does not override its hashCode() method, e.g. com.example.MyThing@6bd57cf | ||
*/ | ||
val HeapInstance.hexIdentityHashCode: String? | ||
get() { | ||
val hashCode = identityHashCode ?: return null | ||
return Integer.toHexString(hashCode) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters