Implement BitMemory{Reader,Writer}

Two simple classes which replace the need to pass
the (BitMemoryRegion, bit_offset) tuple everywhere.

The slightly simplifies the code and it also makes
it possible to optimize those classes in the future.

Test: test-art-host-gtest-stack_map_test
Test: test-art-host-gtest-bit_table_test
Change-Id: I4806c805149a07e1a11b76405ca27960a0012c69
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index f40168b..f9e2d27 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -26,6 +26,23 @@
 
 namespace art {
 
+void CodeInfo::Decode(const uint8_t* data) {
+  size_t non_header_size = DecodeUnsignedLeb128(&data);
+  size_ = UnsignedLeb128Size(non_header_size) + non_header_size;
+  MemoryRegion region(const_cast<uint8_t*>(data), non_header_size);
+  BitMemoryReader reader(BitMemoryRegion(region), /* bit_offset */ 0);
+  stack_maps_.Decode(reader);
+  register_masks_.Decode(reader);
+  stack_masks_.Decode(reader);
+  invoke_infos_.Decode(reader);
+  inline_infos_.Decode(reader);
+  dex_register_masks_.Decode(reader);
+  dex_register_maps_.Decode(reader);
+  dex_register_catalog_.Decode(reader);
+  number_of_dex_registers_ = DecodeVarintBits(reader);
+  CHECK_EQ(non_header_size, BitsToBytesRoundUp(reader.GetBitOffset())) << "Invalid CodeInfo";
+}
+
 BitTable<StackMap>::const_iterator CodeInfo::BinarySearchNativePc(uint32_t packed_pc) const {
   return std::partition_point(
       stack_maps_.begin(),
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index 7aac792..e94f71a 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -445,22 +445,7 @@
                             uint32_t first_dex_register,
                             /*out*/ DexRegisterMap* map) const;
 
-  void Decode(const uint8_t* data) {
-    size_t non_header_size = DecodeUnsignedLeb128(&data);
-    BitMemoryRegion region(MemoryRegion(const_cast<uint8_t*>(data), non_header_size));
-    size_t bit_offset = 0;
-    size_ = UnsignedLeb128Size(non_header_size) + non_header_size;
-    stack_maps_.Decode(region, &bit_offset);
-    register_masks_.Decode(region, &bit_offset);
-    stack_masks_.Decode(region, &bit_offset);
-    invoke_infos_.Decode(region, &bit_offset);
-    inline_infos_.Decode(region, &bit_offset);
-    dex_register_masks_.Decode(region, &bit_offset);
-    dex_register_maps_.Decode(region, &bit_offset);
-    dex_register_catalog_.Decode(region, &bit_offset);
-    number_of_dex_registers_ = DecodeVarintBits(region, &bit_offset);
-    CHECK_EQ(non_header_size, BitsToBytesRoundUp(bit_offset)) << "Invalid CodeInfo";
-  }
+  void Decode(const uint8_t* data);
 
   size_t size_;
   BitTable<StackMap> stack_maps_;