Use unique location catalogs to encode Dex register maps.

- For each CodeInfo object (i.e. for each method), compute a
  variable index size location catalog  of unique Dex
  register locations.  In Dex register maps, instead of
  storing the actual location of a (live) Dex register,
  store the index of the location catalog entry containing
  that Dex register location.
- Adjust art::StackMapStream,
  art::CheckReferenceMapVisitor::CheckOptimizedMethod,
  art::StackVisitor::GetVRegFromOptimizedCode, and
  art::StackVisitor::SetVRegFromOptimizedCode.
- Add LoadBits and StoreBits methods to art::MemoryRegion
  to load and store a block of adjacent bits in a memory
  region.
- Update compiler/optimizing/stack_map_test.cc.
- Remove the default value for parameter EmptyFn of
  art::HashMap.  This default value did not seem to make
  sense, as it would create an "empty function" for type Key
  by default, whereas art::HashMap expects an "empty
  function" for type std::pair<Key, Value>.

Change-Id: Id9e49d7756c253ce41c36630cd832208d06c2e28
diff --git a/runtime/memory_region.h b/runtime/memory_region.h
index 3dcb0dd..e275f0f 100644
--- a/runtime/memory_region.h
+++ b/runtime/memory_region.h
@@ -113,6 +113,31 @@
     }
   }
 
+  // Load `length` bits from the region starting at bit offset `bit_offset`.
+  // The bit at the smallest offset is the least significant bit in the
+  // loaded value.  `length` must not be larger than the number of bits
+  // contained in the return value (32).
+  uint32_t LoadBits(uintptr_t bit_offset, size_t length) const {
+    CHECK_LE(length, sizeof(uint32_t) * kBitsPerByte);
+    uint32_t value = 0u;
+    for (size_t i = 0; i < length; ++i) {
+      value |= LoadBit(bit_offset + i) << i;
+    }
+    return value;
+  }
+
+  // Store `value` on `length` bits in the region starting at bit offset
+  // `bit_offset`.  The bit at the smallest offset is the least significant
+  // bit of the stored `value`.  `value` must not be larger than `length`
+  // bits.
+  void StoreBits(uintptr_t bit_offset, uint32_t value, size_t length) {
+    CHECK_LT(value, 2u << length);
+    for (size_t i = 0; i < length; ++i) {
+      bool ith_bit = value & (1 << i);
+      StoreBit(bit_offset + i, ith_bit);
+    }
+  }
+
   void CopyFrom(size_t offset, const MemoryRegion& from) const;
 
   // Compute a sub memory region based on an existing one.