diff options
author | 2015-10-29 13:02:42 -0700 | |
---|---|---|
committer | 2015-11-03 10:34:20 -0800 | |
commit | b357730dd691e608f8a3d155330ab3763ce912cf (patch) | |
tree | ab84425d3dd7b1adf6f2f35cea705da7ecd54512 | |
parent | 3f922d1f3ccd7a1341f887ac3e8176b5208ecf6d (diff) |
Annotate References with their referent.
Also, don't include annotations in an object's link. That way we can
distinguish between the object link and any links in the annotations.
Change-Id: I3fef3f5b2c343699f527cad9efa7c93a4b35a3a4
-rw-r--r-- | tools/ahat/src/InstanceUtils.java | 18 | ||||
-rw-r--r-- | tools/ahat/src/Value.java | 23 | ||||
-rw-r--r-- | tools/ahat/test-dump/Main.java | 6 | ||||
-rw-r--r-- | tools/ahat/test/InstanceUtilsTest.java | 15 |
4 files changed, 56 insertions, 6 deletions
diff --git a/tools/ahat/src/InstanceUtils.java b/tools/ahat/src/InstanceUtils.java index c2d75c4ad7..7fa53c78b5 100644 --- a/tools/ahat/src/InstanceUtils.java +++ b/tools/ahat/src/InstanceUtils.java @@ -244,6 +244,24 @@ class InstanceUtils { return null; } + private static boolean isJavaLangRefReference(Instance inst) { + ClassObj cls = (inst == null) ? null : inst.getClassObj(); + while (cls != null) { + if ("java.lang.ref.Reference".equals(cls.getClassName())) { + return true; + } + cls = cls.getSuperClassObj(); + } + return false; + } + + public static Instance getReferent(Instance inst) { + if (isJavaLangRefReference(inst)) { + return getRefField(inst, "referent"); + } + return null; + } + /** * Assuming inst represents a DexCache object, return the dex location for * that dex cache. Returns null if the given instance doesn't represent a diff --git a/tools/ahat/src/Value.java b/tools/ahat/src/Value.java index 4eb27b1052..7c969b3645 100644 --- a/tools/ahat/src/Value.java +++ b/tools/ahat/src/Value.java @@ -45,25 +45,36 @@ class Value { } link.append(inst.toString()); + URI objTarget = DocString.formattedUri("object?id=%d", inst.getId()); + DocString formatted = DocString.link(objTarget, link); // Annotate Strings with their values. String stringValue = InstanceUtils.asString(inst, kMaxChars); if (stringValue != null) { - link.appendFormat("\"%s", stringValue); - link.append(kMaxChars == stringValue.length() ? "..." : "\""); + formatted.appendFormat(" \"%s", stringValue); + formatted.append(kMaxChars == stringValue.length() ? "..." : "\""); + } + + // Annotate Reference with its referent + Instance referent = InstanceUtils.getReferent(inst); + if (referent != null) { + formatted.append(" for "); + + // It should not be possible for a referent to refer back to the + // reference object, even indirectly, so there shouldn't be any issues + // with infinite recursion here. + formatted.append(renderInstance(referent)); } // Annotate DexCache with its location. String dexCacheLocation = InstanceUtils.getDexCacheLocation(inst, kMaxChars); if (dexCacheLocation != null) { - link.appendFormat(" for %s", dexCacheLocation); + formatted.appendFormat(" for %s", dexCacheLocation); if (kMaxChars == dexCacheLocation.length()) { - link.append("..."); + formatted.append("..."); } } - URI objTarget = DocString.formattedUri("object?id=%d", inst.getId()); - DocString formatted = DocString.link(objTarget, link); // Annotate bitmaps with a thumbnail. Instance bitmap = InstanceUtils.getAssociatedBitmapInstance(inst); diff --git a/tools/ahat/test-dump/Main.java b/tools/ahat/test-dump/Main.java index cea1dc179e..7b8774a34d 100644 --- a/tools/ahat/test-dump/Main.java +++ b/tools/ahat/test-dump/Main.java @@ -16,6 +16,9 @@ import dalvik.system.VMDebug; import java.io.IOException; +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; /** * Program used to create a heap dump for test purposes. @@ -33,6 +36,9 @@ public class Main { public String basicString = "hello, world"; public String nullString = null; public Object anObject = new Object(); + public ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); + public PhantomReference aPhantomReference = new PhantomReference(anObject, referenceQueue); + public WeakReference aWeakReference = new WeakReference(anObject, referenceQueue); } public static void main(String[] args) throws IOException { diff --git a/tools/ahat/test/InstanceUtilsTest.java b/tools/ahat/test/InstanceUtilsTest.java index 11f82a2301..32f48ce560 100644 --- a/tools/ahat/test/InstanceUtilsTest.java +++ b/tools/ahat/test/InstanceUtilsTest.java @@ -73,4 +73,19 @@ public class InstanceUtilsTest { assertNotNull(obj); assertNull(InstanceUtils.asString(obj)); } + + @Test + public void basicReference() throws IOException { + TestDump dump = TestDump.getTestDump(); + + Instance pref = (Instance)dump.getDumpedThing("aPhantomReference"); + Instance wref = (Instance)dump.getDumpedThing("aWeakReference"); + Instance referent = (Instance)dump.getDumpedThing("anObject"); + assertNotNull(pref); + assertNotNull(wref); + assertNotNull(referent); + assertEquals(referent, InstanceUtils.getReferent(pref)); + assertEquals(referent, InstanceUtils.getReferent(wref)); + assertNull(InstanceUtils.getReferent(referent)); + } } |