Merge "ahat: annotate char[] objects with their string values."
diff --git a/tools/ahat/README.txt b/tools/ahat/README.txt
index da5225c..d9b26bc 100644
--- a/tools/ahat/README.txt
+++ b/tools/ahat/README.txt
@@ -78,6 +78,7 @@
 
 Release History:
  0.4 Pending
+   Annotate char[] objects with their string values.
    Show registered native allocations for heap dumps that support it.
 
  0.3 Dec 15, 2015
diff --git a/tools/ahat/src/InstanceUtils.java b/tools/ahat/src/InstanceUtils.java
index 8b7f9ea..d7b64e2 100644
--- a/tools/ahat/src/InstanceUtils.java
+++ b/tools/ahat/src/InstanceUtils.java
@@ -76,11 +76,15 @@
    * If maxChars is negative, the returned string is not truncated.
    */
   public static String asString(Instance inst, int maxChars) {
-    if (!isInstanceOfClass(inst, "java.lang.String")) {
-      return null;
+    // The inst object could either be a java.lang.String or a char[]. If it
+    // is a char[], use that directly as the value, otherwise use the value
+    // field of the string object. The field accesses for count and offset
+    // later on will work okay regardless of what type the inst object is.
+    Object value = inst;
+    if (isInstanceOfClass(inst, "java.lang.String")) {
+      value = getField(inst, "value");
     }
 
-    Object value = getField(inst, "value");
     if (!(value instanceof ArrayInstance)) {
       return null;
     }
diff --git a/tools/ahat/test-dump/Main.java b/tools/ahat/test-dump/Main.java
index 701d60e..d61a98d 100644
--- a/tools/ahat/test-dump/Main.java
+++ b/tools/ahat/test-dump/Main.java
@@ -35,6 +35,7 @@
   // class and reading the desired field.
   public static class DumpedStuff {
     public String basicString = "hello, world";
+    public char[] charArray = "char thing".toCharArray();
     public String nullString = null;
     public Object anObject = new Object();
     public ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
diff --git a/tools/ahat/test/InstanceUtilsTest.java b/tools/ahat/test/InstanceUtilsTest.java
index 32f48ce..59b1c90 100644
--- a/tools/ahat/test/InstanceUtilsTest.java
+++ b/tools/ahat/test/InstanceUtilsTest.java
@@ -32,6 +32,13 @@
   }
 
   @Test
+  public void asStringCharArray() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance str = (Instance)dump.getDumpedThing("charArray");
+    assertEquals("char thing", InstanceUtils.asString(str));
+  }
+
+  @Test
   public void asStringTruncated() throws IOException {
     TestDump dump = TestDump.getTestDump();
     Instance str = (Instance)dump.getDumpedThing("basicString");
@@ -39,6 +46,13 @@
   }
 
   @Test
+  public void asStringCharArrayTruncated() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance str = (Instance)dump.getDumpedThing("charArray");
+    assertEquals("char ", InstanceUtils.asString(str, 5));
+  }
+
+  @Test
   public void asStringExactMax() throws IOException {
     TestDump dump = TestDump.getTestDump();
     Instance str = (Instance)dump.getDumpedThing("basicString");
@@ -46,6 +60,13 @@
   }
 
   @Test
+  public void asStringCharArrayExactMax() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance str = (Instance)dump.getDumpedThing("charArray");
+    assertEquals("char thing", InstanceUtils.asString(str, 10));
+  }
+
+  @Test
   public void asStringNotTruncated() throws IOException {
     TestDump dump = TestDump.getTestDump();
     Instance str = (Instance)dump.getDumpedThing("basicString");
@@ -53,6 +74,13 @@
   }
 
   @Test
+  public void asStringCharArrayNotTruncated() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance str = (Instance)dump.getDumpedThing("charArray");
+    assertEquals("char thing", InstanceUtils.asString(str, 50));
+  }
+
+  @Test
   public void asStringNegativeMax() throws IOException {
     TestDump dump = TestDump.getTestDump();
     Instance str = (Instance)dump.getDumpedThing("basicString");
@@ -60,6 +88,13 @@
   }
 
   @Test
+  public void asStringCharArrayNegativeMax() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance str = (Instance)dump.getDumpedThing("charArray");
+    assertEquals("char thing", InstanceUtils.asString(str, -3));
+  }
+
+  @Test
   public void asStringNull() throws IOException {
     TestDump dump = TestDump.getTestDump();
     Instance obj = (Instance)dump.getDumpedThing("nullString");