Merge "Don't prefix GC map by length."
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index a682d58..5d78ed5 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -747,7 +747,8 @@
   }
   MethodReference method_ref(cu_->dex_file, cu_->method_idx);
   const std::vector<uint8_t>* gc_map_raw = verifier::MethodVerifier::GetDexGcMap(method_ref);
-  verifier::DexPcToReferenceMap dex_gc_map(&(*gc_map_raw)[4], gc_map_raw->size() - 4);
+  verifier::DexPcToReferenceMap dex_gc_map(&(*gc_map_raw)[0]);
+  DCHECK_EQ(gc_map_raw->size(), dex_gc_map.RawSize());
   // Compute native offset to references size.
   NativePcToReferenceMapBuilder native_gc_map_builder(&native_gc_map_,
                                                       mapping_table.PcToDexSize(),
diff --git a/runtime/entrypoints/portable/portable_thread_entrypoints.cc b/runtime/entrypoints/portable/portable_thread_entrypoints.cc
index 8a2c899..4f19964 100644
--- a/runtime/entrypoints/portable/portable_thread_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_thread_entrypoints.cc
@@ -36,11 +36,7 @@
       ShadowFrame* new_frame = ShadowFrame::Create(num_regs, NULL, method, dex_pc);
 
       const uint8_t* gc_map = method->GetNativeGcMap();
-      uint32_t gc_map_length = static_cast<uint32_t>((gc_map[0] << 24) |
-                                                     (gc_map[1] << 16) |
-                                                     (gc_map[2] << 8) |
-                                                     (gc_map[3] << 0));
-      verifier::DexPcToReferenceMap dex_gc_map(gc_map + 4, gc_map_length);
+      verifier::DexPcToReferenceMap dex_gc_map(gc_map);
       const uint8_t* reg_bitmap = dex_gc_map.FindBitMap(dex_pc);
       for (size_t reg = 0; reg < num_regs; ++reg) {
         if (TestBitmap(reg, reg_bitmap)) {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index fa49faa..715be99 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1994,11 +1994,7 @@
         // Portable path use DexGcMap and store in Method.native_gc_map_.
         const uint8_t* gc_map = m->GetNativeGcMap();
         CHECK(gc_map != NULL) << PrettyMethod(m);
-        uint32_t gc_map_length = static_cast<uint32_t>((gc_map[0] << 24) |
-                                                       (gc_map[1] << 16) |
-                                                       (gc_map[2] << 8) |
-                                                       (gc_map[3] << 0));
-        verifier::DexPcToReferenceMap dex_gc_map(gc_map + 4, gc_map_length);
+        verifier::DexPcToReferenceMap dex_gc_map(gc_map);
         uint32_t dex_pc = GetDexPc();
         const uint8_t* reg_bitmap = dex_gc_map.FindBitMap(dex_pc);
         DCHECK(reg_bitmap != NULL);
diff --git a/runtime/verifier/dex_gc_map.h b/runtime/verifier/dex_gc_map.h
index 2a95ba2..a045a9e 100644
--- a/runtime/verifier/dex_gc_map.h
+++ b/runtime/verifier/dex_gc_map.h
@@ -38,11 +38,13 @@
 // Lightweight wrapper for Dex PC to reference bit maps.
 class DexPcToReferenceMap {
  public:
-  DexPcToReferenceMap(const uint8_t* data, size_t data_length) : data_(data) {
+  DexPcToReferenceMap(const uint8_t* data) : data_(data) {
     CHECK(data_ != NULL);
-    // Check the size of the table agrees with the number of entries
-    size_t data_size = data_length - 4;
-    DCHECK_EQ(EntryWidth() * NumEntries(), data_size);
+  }
+
+  // The total size of the reference bit map including header.
+  size_t RawSize() const {
+    return EntryWidth() * NumEntries() + 4u /* header */;
   }
 
   // The number of entries in the table
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 1e45c60..5f5d865 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -1068,13 +1068,13 @@
     bool compile = IsCandidateForCompilation(ref, method_access_flags_);
     if (compile) {
       /* Generate a register map and add it to the method. */
-      const std::vector<uint8_t>* dex_gc_map = GenerateLengthPrefixedGcMap();
+      const std::vector<uint8_t>* dex_gc_map = GenerateGcMap();
       if (dex_gc_map == NULL) {
         DCHECK_NE(failures_.size(), 0U);
         return false;  // Not a real failure, but a failure to encode
       }
       if (kIsDebugBuild) {
-        VerifyLengthPrefixedGcMap(*dex_gc_map);
+        VerifyGcMap(*dex_gc_map);
       }
       verifier::MethodVerifier::SetDexGcMap(ref, dex_gc_map);
     }
@@ -4054,7 +4054,7 @@
   return pc_to_concrete_method_map.release();
 }
 
-const std::vector<uint8_t>* MethodVerifier::GenerateLengthPrefixedGcMap() {
+const std::vector<uint8_t>* MethodVerifier::GenerateGcMap() {
   size_t num_entries, ref_bitmap_bits, pc_bits;
   ComputeGcMapSizes(&num_entries, &ref_bitmap_bits, &pc_bits);
   // There's a single byte to encode the size of each bitmap
@@ -4092,12 +4092,7 @@
     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Failed to encode GC map (size=" << table_size << ")";
     return NULL;
   }
-  table->reserve(table_size + 4);  // table_size plus the length prefix
-  // Write table size
-  table->push_back((table_size & 0xff000000) >> 24);
-  table->push_back((table_size & 0x00ff0000) >> 16);
-  table->push_back((table_size & 0x0000ff00) >> 8);
-  table->push_back((table_size & 0x000000ff) >> 0);
+  table->reserve(table_size);
   // Write table header
   table->push_back(format | ((ref_bitmap_bytes >> DexPcToReferenceMap::kRegMapFormatShift) &
                              ~DexPcToReferenceMap::kRegMapFormatMask));
@@ -4115,18 +4110,15 @@
       line->WriteReferenceBitMap(*table, ref_bitmap_bytes);
     }
   }
-  DCHECK_EQ(table->size(), table_size + 4);  // table_size plus the length prefix
+  DCHECK_EQ(table->size(), table_size);
   return table;
 }
 
-void MethodVerifier::VerifyLengthPrefixedGcMap(const std::vector<uint8_t>& data) {
+void MethodVerifier::VerifyGcMap(const std::vector<uint8_t>& data) {
   // Check that for every GC point there is a map entry, there aren't entries for non-GC points,
   // that the table data is well formed and all references are marked (or not) in the bitmap
-  DCHECK_GE(data.size(), 4u);
-  size_t table_size = data.size() - 4u;
-  DCHECK_EQ(table_size, static_cast<size_t>((data[0] << 24) | (data[1] << 16) |
-                                            (data[2] << 8) | (data[3] << 0)));
-  DexPcToReferenceMap map(&data[4], table_size);
+  DexPcToReferenceMap map(&data[0]);
+  DCHECK_EQ(data.size(), map.RawSize());
   size_t map_index = 0;
   for (size_t i = 0; i < code_item_->insns_size_in_code_units_; i++) {
     const uint8_t* reg_bitmap = map.FindBitMap(i, false);
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index f72898e..892b7a8 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -614,10 +614,10 @@
    * encode it in some clever fashion.
    * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
    */
-  const std::vector<uint8_t>* GenerateLengthPrefixedGcMap();
+  const std::vector<uint8_t>* GenerateGcMap();
 
   // Verify that the GC map associated with method_ is well formed
-  void VerifyLengthPrefixedGcMap(const std::vector<uint8_t>& data);
+  void VerifyGcMap(const std::vector<uint8_t>& data);
 
   // Compute sizes for GC map data
   void ComputeGcMapSizes(size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc);