Compress the Dex register maps built by the optimizing compiler.

- Replace the current list-based (fixed-size) Dex register
  encoding in stack maps emitted by the optimizing compiler
  with another list-based variable-size Dex register
  encoding compressing short locations on 1 byte (3 bits for
  the location kind, 5 bits for the value); other (large)
  values remain encoded on 5 bytes.
- In addition, use slot offsets instead of byte offsets to
  encode the location of Dex registers placed in stack
  slots at small offsets, as it enables more values to use
  the short (1-byte wide) encoding instead of the large
  (5-byte wide) one.
- Rename art::DexRegisterMap::LocationKind as
  art::DexRegisterLocation::Kind, turn it into a
  strongly-typed enum based on a uint8_t, and extend it to
  support new kinds (kInStackLargeOffset and
  kConstantLargeValue).
- Move art::DexRegisterEntry from
  compiler/optimizing/stack_map_stream.h to
  runtime/stack_map.h and rename it as
  art::DexRegisterLocation.
- Adjust art::StackMapStream,
  art::CodeGenerator::RecordPcInfo,
  art::CheckReferenceMapVisitor::CheckOptimizedMethod,
  art::StackVisitor::GetVRegFromOptimizedCode, and
  art::StackVisitor::SetVRegFromOptimizedCode.
- Implement unaligned memory accesses in art::MemoryRegion.
- Use them to manipulate data in Dex register maps.
- Adjust oatdump to support the new Dex register encoding.
- Update compiler/optimizing/stack_map_test.cc.

Change-Id: Icefaa2e2b36b3c80bb1b882fe7ea2f77ba85c505
diff --git a/runtime/memory_region_test.cc b/runtime/memory_region_test.cc
new file mode 100644
index 0000000..50575dd
--- /dev/null
+++ b/runtime/memory_region_test.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "memory_region.h"
+
+#include "gtest/gtest.h"
+
+namespace art {
+
+TEST(MemoryRegion, LoadUnaligned) {
+  const size_t n = 8;
+  uint8_t data[n] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  MemoryRegion region(&data, n);
+
+  ASSERT_EQ(0, region.LoadUnaligned<char>(0));
+  ASSERT_EQ(1u
+            + (2u << kBitsPerByte)
+            + (3u << 2 * kBitsPerByte)
+            + (4u << 3 * kBitsPerByte),
+            region.LoadUnaligned<uint32_t>(1));
+  ASSERT_EQ(5 + (6 << kBitsPerByte), region.LoadUnaligned<int16_t>(5));
+  ASSERT_EQ(7u, region.LoadUnaligned<unsigned char>(7));
+}
+
+TEST(MemoryRegion, StoreUnaligned) {
+  const size_t n = 8;
+  uint8_t data[n] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+  MemoryRegion region(&data, n);
+
+  region.StoreUnaligned<unsigned char>(0u, 7);
+  region.StoreUnaligned<int16_t>(1, 6 + (5 << kBitsPerByte));
+  region.StoreUnaligned<uint32_t>(3,
+                                  4u
+                                  + (3u << kBitsPerByte)
+                                  + (2u << 2 * kBitsPerByte)
+                                  + (1u << 3 * kBitsPerByte));
+  region.StoreUnaligned<char>(7, 0);
+
+  uint8_t expected[n] = { 7, 6, 5, 4, 3, 2, 1, 0 };
+  for (size_t i = 0; i < n; ++i) {
+    ASSERT_EQ(expected[i], data[i]);
+  }
+}
+}