Separate maps from code in oat file.

Write all GC maps first, then all mapping tables and then
all vmap tables and only then align the offset to page size
and write all method code chunks with headers.

Bug: 11767815
Change-Id: Ic83555c8303c5be119afc43e95e58c0a32ff2a4f
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index d5eccaf..5d62b88 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -22,6 +22,7 @@
 #include "dex_file.h"
 #include "entrypoints/entrypoint_utils.h"
 #include "object_array.h"
+#include "oat.h"
 #include "runtime.h"
 
 namespace art {
@@ -83,7 +84,7 @@
   }
   // TODO: make this Thumb2 specific
   code &= ~0x1;
-  return reinterpret_cast<uint32_t*>(code)[-1];
+  return reinterpret_cast<OatMethodHeader*>(code)[-1].code_size_;
 }
 
 inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index fd5ac19..ee23c40 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -270,9 +270,11 @@
       return pc == 0;
     }
     /*
-     * During a stack walk, a return PC may point to the end of the code + 1
-     * (in the case that the last instruction is a call that isn't expected to
+     * During a stack walk, a return PC may point past-the-end of the code
+     * in the case that the last instruction is a call that isn't expected to
      * return.  Thus, we check <= code + GetCodeSize().
+     *
+     * NOTE: For Thumb both pc and code are offset by 1 indicating the Thumb state.
      */
     return (code <= pc && pc <= code + GetCodeSize());
   }
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 246e090..d01dc72 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -22,7 +22,7 @@
 namespace art {
 
 const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '2', '0', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '2', '1', '\0' };
 
 OatHeader::OatHeader() {
   memset(this, 0, sizeof(*this));
@@ -372,4 +372,14 @@
 
 OatMethodOffsets::~OatMethodOffsets() {}
 
+OatMethodHeader::OatMethodHeader()
+  : code_size_(0)
+{}
+
+OatMethodHeader::OatMethodHeader(uint32_t code_size)
+  : code_size_(code_size)
+{}
+
+OatMethodHeader::~OatMethodHeader() {}
+
 }  // namespace art
diff --git a/runtime/oat.h b/runtime/oat.h
index 2851f5c..035aba1 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -155,6 +155,19 @@
   uint32_t gc_map_offset_;
 };
 
+// OatMethodHeader precedes the raw code chunk generated by the Quick compiler.
+class PACKED(4) OatMethodHeader {
+ public:
+  OatMethodHeader();
+
+  explicit OatMethodHeader(uint32_t code_size);
+
+  ~OatMethodHeader();
+
+  // The code size in bytes.
+  uint32_t code_size_;
+};
+
 }  // namespace art
 
 #endif  // ART_RUNTIME_OAT_H_