ahat: Switch to a custom dominators implementation.

Rather than relying on perflib's dominators computation, use our own.
Benefits:
* Over 25% improvement in heap dump processing performance, improving
  ahat startup time by around 1 to 3 seconds on typical Android heap
  dumps.
* Provides more flexibility if we want to tweak the dominators
  computation in the future, for example by treating different
  soft/weak/finalizer differently or additional performance tuning.
* Opens the door to future performance optimizations based around
  eliminating the impedance mismatch between perflib and ahat's
  internal representations of the heap dump.
* Opens the door to possible future features that involve computing
  dominators of non-heap objects, such as dex code items.
* Avoids a bug in perflib's dominators computation when there are
  duplicate class or instance dumps.

Also included in this change:
* Include "class" in toString for class objects.
* Compute Site ObjectsInfos bottom-up in a separate pass.

Bug: 34884751
Bug: 33957507
Test: m ahat-test, with new tests for incoming references and dominators.
Test: Confirm dominator parity with perflib's dominators computation on
      a number of real heap dumps.
Test: Visually compare information reported for overview, rooted, sites,
      object, and objects pages on a real heap dump against ahat-1.2.

Change-Id: I4cf8fb177a0aaaee07ad6fddbc574682f91cc0f7
diff --git a/tools/ahat/test/InstanceTest.java b/tools/ahat/test/InstanceTest.java
index 71b081c..f0e7f44 100644
--- a/tools/ahat/test/InstanceTest.java
+++ b/tools/ahat/test/InstanceTest.java
@@ -337,7 +337,7 @@
   public void classObjToString() throws IOException {
     TestDump dump = TestDump.getTestDump();
     AhatInstance obj = dump.getAhatSnapshot().findClass("Main");
-    assertEquals("Main", obj.toString());
+    assertEquals("class Main", obj.toString());
   }
 
   @Test
@@ -370,6 +370,18 @@
   }
 
   @Test
+  public void reverseReferences() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    AhatInstance obj = dump.getDumpedAhatInstance("anObject");
+    AhatInstance ref = dump.getDumpedAhatInstance("aReference");
+    AhatInstance weak = dump.getDumpedAhatInstance("aWeakReference");
+    assertTrue(obj.getHardReverseReferences().contains(ref));
+    assertFalse(obj.getHardReverseReferences().contains(weak));
+    assertFalse(obj.getSoftReverseReferences().contains(ref));
+    assertTrue(obj.getSoftReverseReferences().contains(weak));
+  }
+
+  @Test
   public void asStringEmbedded() throws IOException {
     // Set up a heap dump with an instance of java.lang.String of
     // "hello" with instance id 0x42 that is backed by a char array that is