Generate an hprof file to test ahat.

This change sets up the infrastructure to write test cases for ahat
that make use of an hprof file automatically generated from a sample
program.

Change-Id: Id11f656afb69c96a26655cc4caeb745ad844f431
diff --git a/tools/ahat/src/AhatSnapshot.java b/tools/ahat/src/AhatSnapshot.java
index 2437d03..3035ef7 100644
--- a/tools/ahat/src/AhatSnapshot.java
+++ b/tools/ahat/src/AhatSnapshot.java
@@ -18,13 +18,18 @@
 
 import com.android.tools.perflib.heap.ClassObj;
 import com.android.tools.perflib.heap.Heap;
+import com.android.tools.perflib.heap.HprofParser;
 import com.android.tools.perflib.heap.Instance;
 import com.android.tools.perflib.heap.RootObj;
 import com.android.tools.perflib.heap.Snapshot;
 import com.android.tools.perflib.heap.StackFrame;
 import com.android.tools.perflib.heap.StackTrace;
+import com.android.tools.perflib.heap.io.HprofBuffer;
+import com.android.tools.perflib.heap.io.MemoryMappedFileBuffer;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -47,7 +52,22 @@
   private Site mRootSite;
   private Map<Heap, Long> mHeapSizes;
 
-  public AhatSnapshot(Snapshot snapshot) {
+  /**
+   * Create an AhatSnapshot from an hprof file.
+   */
+  public static AhatSnapshot fromHprof(File hprof) throws IOException {
+    HprofBuffer buffer = new MemoryMappedFileBuffer(hprof);
+    Snapshot snapshot = (new HprofParser(buffer)).parse();
+    snapshot.computeDominators();
+    return new AhatSnapshot(snapshot);
+  }
+
+  /**
+   * Construct an AhatSnapshot for the given perflib snapshot.
+   * Ther user is responsible for calling snapshot.computeDominators before
+   * calling this AhatSnapshot constructor.
+   */
+  private AhatSnapshot(Snapshot snapshot) {
     mSnapshot = snapshot;
     mHeaps = new ArrayList<Heap>(mSnapshot.getHeaps());
     mDominated = new HashMap<Instance, List<Instance>>();
@@ -92,6 +112,11 @@
     }
   }
 
+  // Note: This method is exposed for testing purposes.
+  public ClassObj findClass(String name) {
+    return mSnapshot.findClass(name);
+  }
+
   public Instance findInstance(long id) {
     return mSnapshot.findInstance(id);
   }
diff --git a/tools/ahat/src/InstanceUtils.java b/tools/ahat/src/InstanceUtils.java
index 7ee3ff2..a6ac3b8 100644
--- a/tools/ahat/src/InstanceUtils.java
+++ b/tools/ahat/src/InstanceUtils.java
@@ -32,7 +32,7 @@
    * given name.
    */
   public static boolean isInstanceOfClass(Instance inst, String className) {
-    ClassObj cls = inst.getClassObj();
+    ClassObj cls = (inst == null) ? null : inst.getClassObj();
     return (cls != null && className.equals(cls.getClassName()));
   }
 
@@ -132,7 +132,7 @@
    * Read a field of an instance.
    * Returns null if the field value is null or if the field couldn't be read.
    */
-  private static Object getField(Instance inst, String fieldName) {
+  public static Object getField(Instance inst, String fieldName) {
     if (!(inst instanceof ClassInstance)) {
       return null;
     }
diff --git a/tools/ahat/src/Main.java b/tools/ahat/src/Main.java
index 2e2ddd2..1563aa0 100644
--- a/tools/ahat/src/Main.java
+++ b/tools/ahat/src/Main.java
@@ -16,10 +16,6 @@
 
 package com.android.ahat;
 
-import com.android.tools.perflib.heap.HprofParser;
-import com.android.tools.perflib.heap.Snapshot;
-import com.android.tools.perflib.heap.io.HprofBuffer;
-import com.android.tools.perflib.heap.io.MemoryMappedFileBuffer;
 import com.sun.net.httpserver.HttpServer;
 import java.io.File;
 import java.io.IOException;
@@ -71,15 +67,8 @@
       return;
     }
 
-    System.out.println("Reading hprof file...");
-    HprofBuffer buffer = new MemoryMappedFileBuffer(hprof);
-    Snapshot snapshot = (new HprofParser(buffer)).parse();
-
-    System.out.println("Computing Dominators...");
-    snapshot.computeDominators();
-
-    System.out.println("Processing snapshot for ahat...");
-    AhatSnapshot ahat = new AhatSnapshot(snapshot);
+    System.out.println("Processing hprof file...");
+    AhatSnapshot ahat = AhatSnapshot.fromHprof(hprof);
 
     InetAddress loopback = InetAddress.getLoopbackAddress();
     InetSocketAddress addr = new InetSocketAddress(loopback, port);