summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Richard Uhler <ruhler@google.com> 2015-10-29 13:02:42 -0700
committer Richard Uhler <ruhler@google.com> 2015-11-03 10:34:20 -0800
commitb357730dd691e608f8a3d155330ab3763ce912cf (patch)
treeab84425d3dd7b1adf6f2f35cea705da7ecd54512
parent3f922d1f3ccd7a1341f887ac3e8176b5208ecf6d (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.java18
-rw-r--r--tools/ahat/src/Value.java23
-rw-r--r--tools/ahat/test-dump/Main.java6
-rw-r--r--tools/ahat/test/InstanceUtilsTest.java15
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));
+ }
}