Move varint encoding/decoding to BitMemoryReader/Writer.

Test: test-art-host-gtest-bit_memory_region_test
Change-Id: I0f7d7dfc9efe9df0e3e746b1741c46f06a0bd3b4
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index 3918b65..60ca61c 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -296,10 +296,10 @@
 
   ScopedArenaVector<uint8_t> buffer(allocator_->Adapter(kArenaAllocStackMapStream));
   BitMemoryWriter<ScopedArenaVector<uint8_t>> out(&buffer);
-  EncodeVarintBits(out, packed_frame_size_);
-  EncodeVarintBits(out, core_spill_mask_);
-  EncodeVarintBits(out, fp_spill_mask_);
-  EncodeVarintBits(out, num_dex_registers_);
+  out.WriteVarint(packed_frame_size_);
+  out.WriteVarint(core_spill_mask_);
+  out.WriteVarint(fp_spill_mask_);
+  out.WriteVarint(num_dex_registers_);
   EncodeTable(out, stack_maps_);
   EncodeTable(out, register_masks_);
   EncodeTable(out, stack_masks_);
diff --git a/libartbase/base/bit_memory_region.h b/libartbase/base/bit_memory_region.h
index f9b643e..bcdc573 100644
--- a/libartbase/base/bit_memory_region.h
+++ b/libartbase/base/bit_memory_region.h
@@ -202,6 +202,9 @@
   size_t bit_size_ = 0;
 };
 
+constexpr uint32_t kVarintHeaderBits = 4;
+constexpr uint32_t kVarintSmallValue = 11;  // Maximum value which is stored as-is.
+
 class BitMemoryReader {
  public:
   BitMemoryReader(BitMemoryReader&&) = default;
@@ -230,6 +233,18 @@
     return ReadRegion(/* bit_length */ 1).LoadBit(/* bit_offset */ 0);
   }
 
+  // Read variable-length bit-packed integer.
+  // The first four bits determine the variable length of the encoded integer:
+  //   Values 0..11 represent the result as-is, with no further following bits.
+  //   Values 12..15 mean the result is in the next 8/16/24/32-bits respectively.
+  ALWAYS_INLINE uint32_t ReadVarint() {
+    uint32_t x = ReadBits(kVarintHeaderBits);
+    if (x > kVarintSmallValue) {
+      x = ReadBits((x - kVarintSmallValue) * kBitsPerByte);
+    }
+    return x;
+  }
+
  private:
   // Represents all of the bits which were read so far. There is no upper bound.
   // Therefore, by definition, the "cursor" is always at the end of the region.
@@ -274,6 +289,18 @@
     Allocate(1).StoreBit(/* bit_offset */ 0, value);
   }
 
+  // Write variable-length bit-packed integer.
+  ALWAYS_INLINE void WriteVarint(uint32_t value) {
+    if (value <= kVarintSmallValue) {
+      WriteBits(value, kVarintHeaderBits);
+    } else {
+      uint32_t num_bits = RoundUp(MinimumBitsToStore(value), kBitsPerByte);
+      uint32_t header = kVarintSmallValue + num_bits / kBitsPerByte;
+      WriteBits(header, kVarintHeaderBits);
+      WriteBits(value, num_bits);
+    }
+  }
+
   ALWAYS_INLINE void ByteAlign() {
     size_t end = bit_start_ + bit_offset_;
     bit_offset_ += RoundUp(end, kBitsPerByte) - end;
diff --git a/libartbase/base/bit_memory_region_test.cc b/libartbase/base/bit_memory_region_test.cc
index b754698..02623bf 100644
--- a/libartbase/base/bit_memory_region_test.cc
+++ b/libartbase/base/bit_memory_region_test.cc
@@ -33,6 +33,24 @@
   }
 }
 
+TEST(BitMemoryRegion, TestVarint) {
+  for (size_t start_bit_offset = 0; start_bit_offset <= 32; start_bit_offset++) {
+    uint32_t values[] = { 0, 1, 11, 12, 15, 16, 255, 256, 1u << 16, 1u << 24, ~1u, ~0u };
+    for (uint32_t value : values) {
+      std::vector<uint8_t> buffer;
+      BitMemoryWriter<std::vector<uint8_t>> writer(&buffer, start_bit_offset);
+      writer.WriteVarint(value);
+
+      BitMemoryReader reader(buffer.data(), start_bit_offset);
+      uint32_t result = reader.ReadVarint();
+      uint32_t upper_bound = RoundUp(MinimumBitsToStore(value), kBitsPerByte) + kVarintHeaderBits;
+      EXPECT_EQ(writer.NumberOfWrittenBits(), reader.NumberOfReadBits());
+      EXPECT_EQ(value, result);
+      EXPECT_GE(upper_bound, writer.NumberOfWrittenBits());
+    }
+  }
+}
+
 TEST(BitMemoryRegion, TestBit) {
   uint8_t data[sizeof(uint32_t) * 2];
   for (size_t bit_offset = 0; bit_offset < 2 * sizeof(uint32_t) * kBitsPerByte; ++bit_offset) {
diff --git a/libartbase/base/bit_table.h b/libartbase/base/bit_table.h
index 18de3d3..7fec51e 100644
--- a/libartbase/base/bit_table.h
+++ b/libartbase/base/bit_table.h
@@ -33,34 +33,6 @@
 
 namespace art {
 
-constexpr uint32_t kVarintHeaderBits = 4;
-constexpr uint32_t kVarintSmallValue = 11;  // Maximum value which is stored as-is.
-
-// Load variable-length bit-packed integer from `data` starting at `bit_offset`.
-// The first four bits determine the variable length of the encoded integer:
-//   Values 0..11 represent the result as-is, with no further following bits.
-//   Values 12..15 mean the result is in the next 8/16/24/32-bits respectively.
-ALWAYS_INLINE static inline uint32_t DecodeVarintBits(BitMemoryReader& reader) {
-  uint32_t x = reader.ReadBits(kVarintHeaderBits);
-  if (x > kVarintSmallValue) {
-    x = reader.ReadBits((x - kVarintSmallValue) * kBitsPerByte);
-  }
-  return x;
-}
-
-// Store variable-length bit-packed integer from `data` starting at `bit_offset`.
-template<typename Vector>
-ALWAYS_INLINE static inline void EncodeVarintBits(BitMemoryWriter<Vector>& out, uint32_t value) {
-  if (value <= kVarintSmallValue) {
-    out.WriteBits(value, kVarintHeaderBits);
-  } else {
-    uint32_t num_bits = RoundUp(MinimumBitsToStore(value), kBitsPerByte);
-    uint32_t header = kVarintSmallValue + num_bits / kBitsPerByte;
-    out.WriteBits(header, kVarintHeaderBits);
-    out.WriteBits(value, num_bits);
-  }
-}
-
 // Generic purpose table of uint32_t values, which are tightly packed at bit level.
 // It has its own header with the number of rows and the bit-widths of all columns.
 // The values are accessible by (row, column).  The value -1 is stored efficiently.
@@ -78,11 +50,11 @@
   ALWAYS_INLINE void Decode(BitMemoryReader& reader) {
     // Decode row count and column sizes from the table header.
     size_t initial_bit_offset = reader.NumberOfReadBits();
-    num_rows_ = DecodeVarintBits(reader);
+    num_rows_ = reader.ReadVarint();
     if (num_rows_ != 0) {
       column_offset_[0] = 0;
       for (uint32_t i = 0; i < kNumColumns; i++) {
-        size_t column_end = column_offset_[i] + DecodeVarintBits(reader);
+        size_t column_end = column_offset_[i] + reader.ReadVarint();
         column_offset_[i + 1] = dchecked_integral_cast<uint16_t>(column_end);
       }
     }
@@ -386,11 +358,11 @@
 
     std::array<uint32_t, kNumColumns> column_bits;
     Measure(&column_bits);
-    EncodeVarintBits(out, size());
+    out.WriteVarint(size());
     if (size() != 0) {
       // Write table header.
       for (uint32_t c = 0; c < kNumColumns; c++) {
-        EncodeVarintBits(out, column_bits[c]);
+        out.WriteVarint(column_bits[c]);
       }
 
       // Write table data.
@@ -475,9 +447,9 @@
   void Encode(BitMemoryWriter<Vector>& out) const {
     size_t initial_bit_offset = out.NumberOfWrittenBits();
 
-    EncodeVarintBits(out, size());
+    out.WriteVarint(size());
     if (size() != 0) {
-      EncodeVarintBits(out, max_num_bits_);
+      out.WriteVarint(max_num_bits_);
 
       // Write table data.
       for (MemoryRegion row : rows_) {
diff --git a/libartbase/base/bit_table_test.cc b/libartbase/base/bit_table_test.cc
index 4f25730..bf32dc6 100644
--- a/libartbase/base/bit_table_test.cc
+++ b/libartbase/base/bit_table_test.cc
@@ -26,22 +26,6 @@
 
 namespace art {
 
-TEST(BitTableTest, TestVarint) {
-  for (size_t start_bit_offset = 0; start_bit_offset <= 32; start_bit_offset++) {
-    uint32_t values[] = { 0, 1, 11, 12, 15, 16, 255, 256, ~1u, ~0u };
-    for (uint32_t value : values) {
-      std::vector<uint8_t> buffer;
-      BitMemoryWriter<std::vector<uint8_t>> writer(&buffer, start_bit_offset);
-      EncodeVarintBits(writer, value);
-
-      BitMemoryReader reader(buffer.data(), start_bit_offset);
-      uint32_t result = DecodeVarintBits(reader);
-      EXPECT_EQ(writer.NumberOfWrittenBits(), reader.NumberOfReadBits());
-      EXPECT_EQ(value, result);
-    }
-  }
-}
-
 TEST(BitTableTest, TestEmptyTable) {
   MallocArenaPool pool;
   ArenaStack arena_stack(&pool);
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index b0c59a6..689904a 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -36,7 +36,7 @@
                                       BitMemoryReader& reader,
                                       const uint8_t* reader_data) {
   if (reader.ReadBit() /* is_deduped */) {
-    ssize_t bit_offset = reader.NumberOfReadBits() - DecodeVarintBits(reader);
+    ssize_t bit_offset = reader.NumberOfReadBits() - reader.ReadVarint();
     BitMemoryReader reader2(reader_data, bit_offset);  // The offset is negative.
     table.Decode(reader2);
   } else {
@@ -46,10 +46,10 @@
 
 void CodeInfo::Decode(const uint8_t* data, DecodeFlags flags) {
   BitMemoryReader reader(data);
-  packed_frame_size_ = DecodeVarintBits(reader);
-  core_spill_mask_ = DecodeVarintBits(reader);
-  fp_spill_mask_ = DecodeVarintBits(reader);
-  number_of_dex_registers_ = DecodeVarintBits(reader);
+  packed_frame_size_ = reader.ReadVarint();
+  core_spill_mask_ = reader.ReadVarint();
+  fp_spill_mask_ = reader.ReadVarint();
+  number_of_dex_registers_ = reader.ReadVarint();
   DecodeTable(stack_maps_, reader, data);
   DecodeTable(register_masks_, reader, data);
   DecodeTable(stack_masks_, reader, data);
@@ -82,7 +82,7 @@
   } else {
     writer_.WriteBit(true);  // Is deduped.
     size_t bit_offset = writer_.NumberOfWrittenBits();
-    EncodeVarintBits(writer_, bit_offset - it.first->second);
+    writer_.WriteVarint(bit_offset - it.first->second);
   }
 }
 
@@ -90,10 +90,10 @@
   writer_.ByteAlign();
   size_t deduped_offset = writer_.NumberOfWrittenBits() / kBitsPerByte;
   BitMemoryReader reader(code_info);
-  EncodeVarintBits(writer_, DecodeVarintBits(reader));  // packed_frame_size_.
-  EncodeVarintBits(writer_, DecodeVarintBits(reader));  // core_spill_mask_.
-  EncodeVarintBits(writer_, DecodeVarintBits(reader));  // fp_spill_mask_.
-  EncodeVarintBits(writer_, DecodeVarintBits(reader));  // number_of_dex_registers_.
+  writer_.WriteVarint(reader.ReadVarint());  // packed_frame_size_.
+  writer_.WriteVarint(reader.ReadVarint());  // core_spill_mask_.
+  writer_.WriteVarint(reader.ReadVarint());  // fp_spill_mask_.
+  writer_.WriteVarint(reader.ReadVarint());  // number_of_dex_registers_.
   DedupeTable<StackMap>(reader);
   DedupeTable<RegisterMask>(reader);
   DedupeTable<MaskInfo>(reader);
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index cde08f3..bfd646d 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -436,9 +436,9 @@
   ALWAYS_INLINE static QuickMethodFrameInfo DecodeFrameInfo(const uint8_t* data) {
     BitMemoryReader reader(data);
     return QuickMethodFrameInfo(
-        DecodeVarintBits(reader) * kStackAlignment,  // Decode packed_frame_size_ and unpack.
-        DecodeVarintBits(reader),  // core_spill_mask_.
-        DecodeVarintBits(reader));  // fp_spill_mask_.
+        reader.ReadVarint() * kStackAlignment,  // Decode packed_frame_size_ and unpack.
+        reader.ReadVarint(),  // core_spill_mask_.
+        reader.ReadVarint());  // fp_spill_mask_.
   }
 
  private: