Change hprof to use streaming

Previously, we compute the whole hprof dump in memory resulting in
> 50MB of memory usage for some apps (such as maps). This could
cause the app to get killed by the low memory killer.

The solution works by doing the dump in 2 passes.
The first pass calculates the size of the dump.
The second pass starts by sending the DDMS header with the correct
size, then does the rest of the hprof dump by streaming and sending
data one HprofRecord at a time.

Bug: 18921793
Change-Id: I7dd9f5cfe49799ba268095c994a8c2eb1fe493df
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index cb28ff0..a8eaa26 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -1257,6 +1257,22 @@
 }
 
 /*
+ * Setup the header for a chunk of DDM data.
+ */
+void JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size,
+                                 uint8_t* out_header) {
+  CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8));
+  /* form the header (JDWP plus DDMS) */
+  Set4BE(out_header, header_size + data_len);
+  Set4BE(out_header + 4, NextRequestSerial());
+  Set1(out_header + 8, 0);     /* flags */
+  Set1(out_header + 9, kJDWPDdmCmdSet);
+  Set1(out_header + 10, kJDWPDdmCmd);
+  Set4BE(out_header + 11, type);
+  Set4BE(out_header + 15, data_len);
+}
+
+/*
  * Send up a chunk of DDM data.
  *
  * While this takes the form of a JDWP "event", it doesn't interact with
@@ -1264,7 +1280,7 @@
  * the fun event token gymnastics.
  */
 void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
-  uint8_t header[kJDWPHeaderLen + 8];
+  uint8_t header[kJDWPHeaderLen + 8] = { 0 };
   size_t dataLen = 0;
 
   CHECK(iov != nullptr);
@@ -1282,14 +1298,7 @@
     dataLen += iov[i].iov_len;
   }
 
-  /* form the header (JDWP plus DDMS) */
-  Set4BE(header, sizeof(header) + dataLen);
-  Set4BE(header + 4, NextRequestSerial());
-  Set1(header + 8, 0);     /* flags */
-  Set1(header + 9, kJDWPDdmCmdSet);
-  Set1(header + 10, kJDWPDdmCmd);
-  Set4BE(header + 11, type);
-  Set4BE(header + 15, dataLen);
+  SetupChunkHeader(type, dataLen, sizeof(header), header);
 
   wrapiov[0].iov_base = header;
   wrapiov[0].iov_len = sizeof(header);