Encode frame info using varints.

This saves 0.3% of oat file size.

Test: test-art-host-gtest-stack_map_test
Change-Id: I85003946a9579f03cb1ed2b5e9b2c62b3efe6734
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index 429054c..b26b53f 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -45,9 +45,10 @@
                                  uint32_t num_dex_registers) {
   DCHECK(!in_method_) << "Mismatched Begin/End calls";
   in_method_ = true;
-  DCHECK_EQ(frame_size_in_bytes_, 0u) << "BeginMethod was already called";
+  DCHECK_EQ(packed_frame_size_, 0u) << "BeginMethod was already called";
 
-  frame_size_in_bytes_ = frame_size_in_bytes;
+  DCHECK_ALIGNED(frame_size_in_bytes, kStackAlignment);
+  packed_frame_size_ = frame_size_in_bytes / kStackAlignment;
   core_spill_mask_ = core_spill_mask;
   fp_spill_mask_ = fp_spill_mask;
   num_dex_registers_ = num_dex_registers;
@@ -292,11 +293,11 @@
     }
   }
 
-  EncodeUnsignedLeb128(&out_, frame_size_in_bytes_);
-  EncodeUnsignedLeb128(&out_, core_spill_mask_);
-  EncodeUnsignedLeb128(&out_, fp_spill_mask_);
-  EncodeUnsignedLeb128(&out_, num_dex_registers_);
-  BitMemoryWriter<ScopedArenaVector<uint8_t>> out(&out_, out_.size() * kBitsPerByte);
+  BitMemoryWriter<ScopedArenaVector<uint8_t>> out(&out_);
+  EncodeVarintBits(out, packed_frame_size_);
+  EncodeVarintBits(out, core_spill_mask_);
+  EncodeVarintBits(out, fp_spill_mask_);
+  EncodeVarintBits(out, num_dex_registers_);
   EncodeTable(out, stack_maps_);
   EncodeTable(out, inline_infos_);
   EncodeTable(out, method_infos_);
diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h
index de79f49..a5f7ff3 100644
--- a/compiler/optimizing/stack_map_stream.h
+++ b/compiler/optimizing/stack_map_stream.h
@@ -98,7 +98,7 @@
   void CreateDexRegisterMap();
 
   const InstructionSet instruction_set_;
-  uint32_t frame_size_in_bytes_ = 0;
+  uint32_t packed_frame_size_ = 0;
   uint32_t core_spill_mask_ = 0;
   uint32_t fp_spill_mask_ = 0;
   uint32_t num_dex_registers_ = 0;
diff --git a/runtime/oat.h b/runtime/oat.h
index 69aaceb..4ad065a 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,8 +32,8 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
-  // Last oat version changed reason: Move MethodInfo into CodeInfo.
-  static constexpr uint8_t kOatVersion[] = { '1', '5', '8', '\0' };
+  // Last oat version changed reason: Encode frame info using varints.
+  static constexpr uint8_t kOatVersion[] = { '1', '5', '9', '\0' };
 
   static constexpr const char* kImageLocationKey = "image-location";
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index cd82284..1b78b5a 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -50,12 +50,11 @@
 }
 
 void CodeInfo::Decode(const uint8_t* data, DecodeFlags flags) {
-  const uint8_t* begin = data;
-  frame_size_in_bytes_ = DecodeUnsignedLeb128(&data);
-  core_spill_mask_ = DecodeUnsignedLeb128(&data);
-  fp_spill_mask_ = DecodeUnsignedLeb128(&data);
-  number_of_dex_registers_ = DecodeUnsignedLeb128(&data);
-  BitMemoryReader reader(data, /* bit_offset */ 0);
+  BitMemoryReader reader(data);
+  packed_frame_size_ = DecodeVarintBits(reader);
+  core_spill_mask_ = DecodeVarintBits(reader);
+  fp_spill_mask_ = DecodeVarintBits(reader);
+  number_of_dex_registers_ = DecodeVarintBits(reader);
   DecodeTable(stack_maps_, reader, data);
   DecodeTable(inline_infos_, reader, data);
   DecodeTable(method_infos_, reader, data);
@@ -67,7 +66,7 @@
   DecodeTable(dex_register_masks_, reader, data);
   DecodeTable(dex_register_maps_, reader, data);
   DecodeTable(dex_register_catalog_, reader, data);
-  size_in_bits_ = (data - begin) * kBitsPerByte + reader.GetBitOffset();
+  size_in_bits_ = reader.GetBitOffset();
 }
 
 template<typename Accessor>
@@ -91,13 +90,12 @@
 size_t CodeInfo::Dedupe(std::vector<uint8_t>* out, const uint8_t* in, DedupeMap* dedupe_map) {
   // Remember the current offset in the output buffer so that we can return it later.
   const size_t result = out->size();
-  // Copy the header which encodes QuickMethodFrameInfo.
-  EncodeUnsignedLeb128(out, DecodeUnsignedLeb128(&in));
-  EncodeUnsignedLeb128(out, DecodeUnsignedLeb128(&in));
-  EncodeUnsignedLeb128(out, DecodeUnsignedLeb128(&in));
-  EncodeUnsignedLeb128(out, DecodeUnsignedLeb128(&in));
-  BitMemoryReader reader(in, /* bit_offset */ 0);
+  BitMemoryReader reader(in);
   BitMemoryWriter<std::vector<uint8_t>> writer(out, /* bit_offset */ out->size() * kBitsPerByte);
+  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_.
   DedupeTable<StackMap>(writer, reader, dedupe_map);
   DedupeTable<InlineInfo>(writer, reader, dedupe_map);
   DedupeTable<MethodInfo>(writer, reader, dedupe_map);
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index 8bfae7c..0b1c4f9 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -416,10 +416,11 @@
   void AddSizeStats(/*out*/ Stats* parent) const;
 
   ALWAYS_INLINE static QuickMethodFrameInfo DecodeFrameInfo(const uint8_t* data) {
+    BitMemoryReader reader(data);
     return QuickMethodFrameInfo(
-        DecodeUnsignedLeb128(&data),
-        DecodeUnsignedLeb128(&data),
-        DecodeUnsignedLeb128(&data));
+        DecodeVarintBits(reader) * kStackAlignment,  // Decode packed_frame_size_ and unpack.
+        DecodeVarintBits(reader),  // core_spill_mask_.
+        DecodeVarintBits(reader));  // fp_spill_mask_.
   }
 
   typedef std::map<BitMemoryRegion, uint32_t, BitMemoryRegion::Less> DedupeMap;
@@ -444,7 +445,7 @@
 
   void Decode(const uint8_t* data, DecodeFlags flags);
 
-  uint32_t frame_size_in_bytes_;
+  uint32_t packed_frame_size_;  // Frame size in kStackAlignment units.
   uint32_t core_spill_mask_;
   uint32_t fp_spill_mask_;
   uint32_t number_of_dex_registers_;