Added method fields for register map. Populated by verifier.

The register map consists of 2 ByteArrays, 1 for the header and 1 for
the actual data.

Change-Id: Ibd7455a2eff7572587dabff7dd67fd810ce21f84
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 4b48892..f43e47c 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -545,6 +545,8 @@
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_strings_),                    "shadow$_dex_cache_strings_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_array_),                    "shadow$_invoke_stub_array_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, mapping_table_),                        "shadow$_mapping_table_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, register_map_data_),                    "shadow$_register_map_data_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, register_map_header_),                  "shadow$_register_map_header_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, shorty_),                               "shadow$_shorty_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, signature_),                            "shadow$_signature_"));
 
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 5d622f9..b6739f8 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -351,13 +351,19 @@
 
   /* Generate a register map. */
   if (generate_register_map) {
-    RegisterMap* map = GenerateRegisterMapV(vdata);
+    UniquePtr<RegisterMap> map(GenerateRegisterMapV(vdata));
     /*
      * Tuck the map into the Method. It will either get used directly or, if
      * we're in dexopt, will be packed up and appended to the DEX file.
      */
-    // TODO: Put the map somewhere...
-    delete map;
+    ByteArray* header = ByteArray::Alloc(sizeof(RegisterMapHeader));
+    ByteArray* data = ByteArray::Alloc(ComputeRegisterMapSize(map.get()));
+
+    memcpy(header->GetData(), map.get()->header_, sizeof(RegisterMapHeader));
+    memcpy(data->GetData(), map.get()->data_, ComputeRegisterMapSize(map.get()));
+
+    method->SetRegisterMapHeader(header);
+    method->SetRegisterMapData(data);
   }
 
   return true;
@@ -5302,7 +5308,7 @@
       true, data_size);
 
   /* Populate it. */
-  uint8_t* map_data = map->data_.get();
+  uint8_t* map_data = map->data_;
   for (i = 0; i < (int) vdata->code_item_->insns_size_; i++) {
     if (InsnIsGcPoint(vdata->insn_flags_.get(), i)) {
       assert(vdata->register_lines_[i].reg_types_.get() != NULL);
@@ -5318,7 +5324,7 @@
     }
   }
 
-  assert((uint32_t) map_data - (uint32_t) map->data_.get() == data_size);
+  assert((uint32_t) map_data - (uint32_t) map->data_ == data_size);
 
   // TODO: Remove this check when it's really running...
 #if 1
@@ -5387,14 +5393,14 @@
 }
 
 bool DexVerifier::VerifyMap(VerifierData* vdata, const RegisterMap* map) {
-  const uint8_t* raw_map = map->data_.get();
-  uint8_t format = map->format_;
-  const int num_entries = map->num_entries_;
+  const uint8_t* raw_map = map->data_;
+  uint8_t format = map->header_->format_;
+  const int num_entries = map->header_->num_entries_;
   int ent;
 
-  if ((vdata->code_item_->registers_size_ + 7) / 8 != map->reg_width_) {
+  if ((vdata->code_item_->registers_size_ + 7) / 8 != map->header_->reg_width_) {
     LOG(ERROR) << "GLITCH: registersSize=" << vdata->code_item_->registers_size_
-               << ", reg_width=" << map->reg_width_;
+               << ", reg_width=" << map->header_->reg_width_;
     return false;
   }
 
@@ -5461,12 +5467,13 @@
     return false;
   }
 
-  if (map1->format_ != map2->format_ || map1->reg_width_ != map2->reg_width_ ||
-      map1->num_entries_ != map2->num_entries_ ||
-      map1->format_on_heap_ != map2->format_on_heap_) {
+  if (map1->header_->format_ != map2->header_->format_ ||
+      map1->header_->reg_width_ != map2->header_->reg_width_ ||
+      map1->header_->num_entries_ != map2->header_->num_entries_ ||
+      map1->header_->format_on_heap_ != map2->header_->format_on_heap_) {
     LOG(ERROR) << "CompareMaps: fields mismatch";
   }
-  if (memcmp(map1->data_.get(), map2->data_.get(), size1) != 0) {
+  if (memcmp(map1->data_, map2->data_, size1) != 0) {
     LOG(ERROR) << "CompareMaps: data mismatch";
     return false;
   }
@@ -5475,8 +5482,8 @@
 }
 
 size_t DexVerifier::ComputeRegisterMapSize(const RegisterMap* map) {
-  uint8_t format = map->format_;
-  uint16_t num_entries = map->num_entries_;
+  uint8_t format = map->header_->format_;
+  uint16_t num_entries = map->header_->num_entries_;
 
   assert(map != NULL);
 
@@ -5484,13 +5491,13 @@
     case kRegMapFormatNone:
       return 1;
     case kRegMapFormatCompact8:
-      return (1 + map->reg_width_) * num_entries;
+      return (1 + map->header_->reg_width_) * num_entries;
     case kRegMapFormatCompact16:
-      return (2 + map->reg_width_) * num_entries;
+      return (2 + map->header_->reg_width_) * num_entries;
     case kRegMapFormatDifferential:
       {
         /* Decoded ULEB128 length. */
-        const uint8_t* ptr = map->data_.get();
+        const uint8_t* ptr = map->data_;
         return DecodeUnsignedLeb128(&ptr);
       }
     default:
@@ -5554,7 +5561,7 @@
   uint8_t* tmp_ptr;
   int addr_width;
 
-  uint8_t format = map->format_;
+  uint8_t format = map->header_->format_;
   switch (format) {
     case kRegMapFormatCompact8:
       addr_width = 1;
@@ -5567,8 +5574,8 @@
       return NULL;
   }
 
-  int reg_width = map->reg_width_;
-  int num_entries = map->num_entries_;
+  int reg_width = map->header_->reg_width_;
+  int num_entries = map->header_->num_entries_;
 
   if (num_entries <= 1) {
     return NULL;
@@ -5595,7 +5602,7 @@
 
   tmp_ptr = tmp_buf.get();
 
-  const uint8_t* map_data = map->data_.get();
+  const uint8_t* map_data = map->data_;
   const uint8_t* prev_bits;
   uint16_t addr, prev_addr;
 
@@ -5714,7 +5721,7 @@
   RegisterMap* new_map = new RegisterMap(kRegMapFormatDifferential, reg_width,
       num_entries, true, new_map_size);
 
-  tmp_ptr = new_map->data_.get();
+  tmp_ptr = new_map->data_;
   tmp_ptr = WriteUnsignedLeb128(tmp_ptr, new_data_size);
   memcpy(tmp_ptr, tmp_buf.get(), new_data_size);
 
@@ -5723,7 +5730,7 @@
 
 DexVerifier::RegisterMap* DexVerifier::UncompressMapDifferential(
     const RegisterMap* map) {
-  uint8_t format = map->format_;
+  uint8_t format = map->header_->format_;
   RegisterMapFormat new_format;
   int reg_width, num_entries, new_addr_width, new_data_size;
 
@@ -5732,11 +5739,11 @@
     return NULL;
   }
 
-  reg_width = map->reg_width_;
-  num_entries = map->num_entries_;
+  reg_width = map->header_->reg_width_;
+  num_entries = map->header_->num_entries_;
 
   /* Get the data size; we can check this at the end. */
-  const uint8_t* src_ptr = map->data_.get();
+  const uint8_t* src_ptr = map->data_;
   int expected_src_len = DecodeUnsignedLeb128(&src_ptr);
   const uint8_t* src_start = src_ptr;
 
@@ -5757,7 +5764,7 @@
       true, new_data_size);
 
   /* Write the start address and initial bits to the new map. */
-  uint8_t* dst_ptr = new_map->data_.get();
+  uint8_t* dst_ptr = new_map->data_;
 
   *dst_ptr++ = addr & 0xff;
   if (new_addr_width > 1)
@@ -5823,8 +5830,8 @@
     dst_ptr += reg_width;
   }
 
-  if (dst_ptr - new_map->data_.get() != new_data_size) {
-    LOG(ERROR) << "ERROR: output " << dst_ptr - new_map->data_.get()
+  if (dst_ptr - new_map->data_ != new_data_size) {
+    LOG(ERROR) << "ERROR: output " << dst_ptr - new_map->data_
                << " bytes, expected " << new_data_size;
     free(new_map);
     return NULL;
diff --git a/src/dex_verifier.h b/src/dex_verifier.h
index 41223b2..404227d 100644
--- a/src/dex_verifier.h
+++ b/src/dex_verifier.h
@@ -34,10 +34,6 @@
 
 class DexVerifier {
  public:
-  /* Verify a class. Returns "true" on success. */
-  static bool VerifyClass(Class* klass);
-
- private:
   /*
    * RegType holds information about the type of data held in a register.
    * For most types it's a simple enum. For reference types it holds a
@@ -361,6 +357,20 @@
     }
   };
 
+  /* Header for RegisterMap */
+  struct RegisterMapHeader {
+    uint8_t format_;          /* enum RegisterMapFormat; MUST be first entry */
+    uint8_t reg_width_;       /* bytes per register line, 1+ */
+    uint16_t num_entries_;    /* number of entries */
+    bool    format_on_heap_;  /* indicates allocation on heap */
+
+    RegisterMapHeader(uint8_t format, uint8_t reg_width, uint16_t num_entries,
+        bool format_on_heap)
+        : format_(format), reg_width_(reg_width), num_entries_(num_entries),
+          format_on_heap_(format_on_heap) {
+    }
+  };
+
   /*
    * This is a single variable-size structure. It may be allocated on the
    * heap or mapped out of a (post-dexopt) DEX file.
@@ -374,19 +384,29 @@
    * Size of (format==FormatCompact16): 4 + (2 + reg_width) * num_entries
    */
   struct RegisterMap {
-    /* header */
-    uint8_t format_;          /* enum RegisterMapFormat; MUST be first entry */
-    uint8_t reg_width_;       /* bytes per register line, 1+ */
-    uint16_t num_entries_;    /* number of entries */
-    bool    format_on_heap_;  /* indicates allocation on heap */
+    RegisterMapHeader* header_;
+    uint8_t* data_;
+    bool needs_free_;
 
-    /* raw data starts here; need not be aligned */
-    UniquePtr<uint8_t[]> data_;
+    RegisterMap(ByteArray* header, ByteArray* data) {
+      header_ = (RegisterMapHeader*) header->GetData();
+      data_ = (uint8_t*) data->GetData();
+      needs_free_ = false;
+    }
 
     RegisterMap(uint8_t format, uint8_t reg_width, uint16_t num_entries,
-        bool format_on_heap, uint32_t data_size)
-        : format_(format), reg_width_(reg_width), num_entries_(num_entries),
-          format_on_heap_(format_on_heap), data_(new uint8_t[data_size]()) {
+        bool format_on_heap, uint32_t data_size) {
+      header_ = new RegisterMapHeader(format, reg_width, num_entries,
+          format_on_heap);
+      data_ = new uint8_t[data_size]();
+      needs_free_ = true;
+    }
+
+    ~RegisterMap() {
+      if (needs_free_) {
+        delete header_;
+        delete [] data_;
+      }
     }
   };
 
@@ -541,6 +561,10 @@
     return (uint32_t) (kRegTypeUninit | (uidx << kRegTypeUninitShift));
   }
 
+  /* Verify a class. Returns "true" on success. */
+  static bool VerifyClass(Class* klass);
+
+ private:
   /*
    * Perform verification on a single method.
    *
diff --git a/src/object.h b/src/object.h
index 5e09f2e..3e154e4 100644
--- a/src/object.h
+++ b/src/object.h
@@ -636,6 +636,14 @@
 
   void SetName(String* new_name);
 
+  ByteArray* GetRegisterMapData() const;
+
+  void SetRegisterMapData(ByteArray* new_data);
+
+  ByteArray* GetRegisterMapHeader() const;
+
+  void SetRegisterMapHeader(ByteArray* new_header);
+
   String* GetShorty() const;
 
   void SetShorty(String* new_shorty);
@@ -1012,6 +1020,10 @@
   // Storage for mapping_table_
   const ByteArray* mapping_table_;
 
+  // Byte arrays that hold data for the register maps
+  const ByteArray* register_map_data_;
+  const ByteArray* register_map_header_;
+
   // The short-form method descriptor string.
   String* shorty_;
 
@@ -2515,6 +2527,26 @@
 
 }
 
+inline ByteArray* Method::GetRegisterMapData() const {
+  return GetFieldObject<ByteArray*>(
+      OFFSET_OF_OBJECT_MEMBER(Method, register_map_data_), false);
+}
+
+inline void Method::SetRegisterMapData(ByteArray* new_data) {
+  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, register_map_data_),
+                 new_data, false);
+}
+
+inline ByteArray* Method::GetRegisterMapHeader() const {
+  return GetFieldObject<ByteArray*>(
+      OFFSET_OF_OBJECT_MEMBER(Method, register_map_header_), false);
+}
+
+inline void Method::SetRegisterMapHeader(ByteArray* new_header) {
+  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, register_map_header_),
+                 new_header, false);
+}
+
 inline String* Method::GetShorty() const {
   DCHECK(GetDeclaringClass()->IsLoaded());
   return GetFieldObject<String*>(