Separate HPROF from the GC.

In the beginning, the only way to traverse the roots and heap was to
piggyback off the garbage collector.  As such, HPROF was implemented
by instrumenting the root- and object traversal routines to check a
mode flag and call into HPROF during a GC when the flag was set.

This change moves the HPROF calls out of the GC and into callbacks
invoked through the visitor.  Notably, it allows HPROF dumps to be
computed at any point in time without invoking a GC and potentially
destroying evidence relating to the cause of an OOM.

Change-Id: I2b74c4f10f35af3ca33b7c0bbfe470a8b586ff66
diff --git a/vm/alloc/Visit.h b/vm/alloc/Visit.h
index 488c721..e7c52e5 100644
--- a/vm/alloc/Visit.h
+++ b/vm/alloc/Visit.h
@@ -19,6 +19,24 @@
 
 #include "Dalvik.h"
 
+typedef enum {
+  ROOT_UNKNOWN = 0,
+  ROOT_JNI_GLOBAL,
+  ROOT_JNI_LOCAL,
+  ROOT_JAVA_FRAME,
+  ROOT_NATIVE_STACK,
+  ROOT_STICKY_CLASS,
+  ROOT_THREAD_BLOCK,
+  ROOT_MONITOR_USED,
+  ROOT_THREAD_OBJECT,
+  ROOT_INTERNED_STRING,
+  ROOT_FINALIZING,
+  ROOT_DEBUGGER,
+  ROOT_REFERENCE_CLEANUP,
+  ROOT_VM_INTERNAL,
+  ROOT_JNI_MONITOR,
+} RootType;
+
 /*
  * Callback invoked with the address of a reference and a user
  * supplied context argument.
@@ -26,6 +44,13 @@
 typedef void Visitor(void *addr, void *arg);
 
 /*
+ * Like a Visitor, but passes root specific information such as the
+ * containing thread id and the root type.  In cases where a root is
+ * not specific to a thread, 0, an invalid thread id is provided.
+ */
+typedef void RootVisitor(void *addr, u4 threadId, RootType type, void *arg);
+
+/*
  * Visits references in an object.
  */
 void dvmVisitObject(Visitor *visitor, Object *obj, void *arg);
@@ -33,6 +58,6 @@
 /*
  * Visits references in the root set.
  */
-void dvmVisitRoots(Visitor *visitor, void *arg);
+void dvmVisitRoots(RootVisitor *visitor, void *arg);
 
 #endif /* _DALVIK_ALLOC_VISIT */