Merge "Avoid register pool allocations on the heap."
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index a50b90a..5340d83 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -25,42 +25,34 @@
 
 namespace art {
 
-// TODO: rework this when c++11 support allows.
-static const RegStorage core_regs_arr[] =
+static constexpr RegStorage core_regs_arr[] =
     {rs_r0, rs_r1, rs_r2, rs_r3, rs_rARM_SUSPEND, rs_r5, rs_r6, rs_r7, rs_r8, rs_rARM_SELF,
      rs_r10, rs_r11, rs_r12, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC};
-static const RegStorage sp_regs_arr[] =
+static constexpr RegStorage sp_regs_arr[] =
     {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, rs_fr8, rs_fr9, rs_fr10,
      rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15, rs_fr16, rs_fr17, rs_fr18, rs_fr19, rs_fr20,
      rs_fr21, rs_fr22, rs_fr23, rs_fr24, rs_fr25, rs_fr26, rs_fr27, rs_fr28, rs_fr29, rs_fr30,
      rs_fr31};
-static const RegStorage dp_regs_arr[] =
+static constexpr RegStorage dp_regs_arr[] =
     {rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, rs_dr8, rs_dr9, rs_dr10,
      rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15};
-static const RegStorage reserved_regs_arr[] =
+static constexpr RegStorage reserved_regs_arr[] =
     {rs_rARM_SUSPEND, rs_rARM_SELF, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC};
-static const RegStorage core_temps_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_r12};
-static const RegStorage sp_temps_arr[] =
+static constexpr RegStorage core_temps_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_r12};
+static constexpr RegStorage sp_temps_arr[] =
     {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, rs_fr8, rs_fr9, rs_fr10,
      rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15};
-static const RegStorage dp_temps_arr[] =
+static constexpr RegStorage dp_temps_arr[] =
     {rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7};
 
-static const std::vector<RegStorage> empty_pool;
-static const std::vector<RegStorage> core_regs(core_regs_arr,
-    core_regs_arr + sizeof(core_regs_arr) / sizeof(core_regs_arr[0]));
-static const std::vector<RegStorage> sp_regs(sp_regs_arr,
-    sp_regs_arr + sizeof(sp_regs_arr) / sizeof(sp_regs_arr[0]));
-static const std::vector<RegStorage> dp_regs(dp_regs_arr,
-    dp_regs_arr + sizeof(dp_regs_arr) / sizeof(dp_regs_arr[0]));
-static const std::vector<RegStorage> reserved_regs(reserved_regs_arr,
-    reserved_regs_arr + sizeof(reserved_regs_arr) / sizeof(reserved_regs_arr[0]));
-static const std::vector<RegStorage> core_temps(core_temps_arr,
-    core_temps_arr + sizeof(core_temps_arr) / sizeof(core_temps_arr[0]));
-static const std::vector<RegStorage> sp_temps(sp_temps_arr,
-    sp_temps_arr + sizeof(sp_temps_arr) / sizeof(sp_temps_arr[0]));
-static const std::vector<RegStorage> dp_temps(dp_temps_arr,
-    dp_temps_arr + sizeof(dp_temps_arr) / sizeof(dp_temps_arr[0]));
+static constexpr ArrayRef<const RegStorage> empty_pool;
+static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr);
+static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr);
+static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr);
+static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr);
+static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr);
+static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr);
+static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr);
 
 RegLocation ArmMir2Lir::LocCReturn() {
   return arm_loc_c_return;
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index 0524191..b287399 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -25,72 +25,63 @@
 
 namespace art {
 
-// TODO: rework this when c++11 support allows.
-static const RegStorage core_regs_arr[] =
+static constexpr RegStorage core_regs_arr[] =
     {rs_w0, rs_w1, rs_w2, rs_w3, rs_w4, rs_w5, rs_w6, rs_w7,
      rs_w8, rs_w9, rs_w10, rs_w11, rs_w12, rs_w13, rs_w14, rs_w15,
      rs_w16, rs_w17, rs_w18, rs_w19, rs_w20, rs_w21, rs_w22, rs_w23,
      rs_w24, rs_w25, rs_w26, rs_w27, rs_w28, rs_w29, rs_w30, rs_w31,
      rs_wzr};
-static const RegStorage core64_regs_arr[] =
+static constexpr RegStorage core64_regs_arr[] =
     {rs_x0, rs_x1, rs_x2, rs_x3, rs_x4, rs_x5, rs_x6, rs_x7,
      rs_x8, rs_x9, rs_x10, rs_x11, rs_x12, rs_x13, rs_x14, rs_x15,
      rs_x16, rs_x17, rs_x18, rs_x19, rs_x20, rs_x21, rs_x22, rs_x23,
      rs_x24, rs_x25, rs_x26, rs_x27, rs_x28, rs_x29, rs_x30, rs_x31,
      rs_xzr};
-static const RegStorage sp_regs_arr[] =
+static constexpr RegStorage sp_regs_arr[] =
     {rs_f0, rs_f1, rs_f2, rs_f3, rs_f4, rs_f5, rs_f6, rs_f7,
      rs_f8, rs_f9, rs_f10, rs_f11, rs_f12, rs_f13, rs_f14, rs_f15,
      rs_f16, rs_f17, rs_f18, rs_f19, rs_f20, rs_f21, rs_f22, rs_f23,
      rs_f24, rs_f25, rs_f26, rs_f27, rs_f28, rs_f29, rs_f30, rs_f31};
-static const RegStorage dp_regs_arr[] =
+static constexpr RegStorage dp_regs_arr[] =
     {rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7,
      rs_d8, rs_d9, rs_d10, rs_d11, rs_d12, rs_d13, rs_d14, rs_d15,
      rs_d16, rs_d17, rs_d18, rs_d19, rs_d20, rs_d21, rs_d22, rs_d23,
      rs_d24, rs_d25, rs_d26, rs_d27, rs_d28, rs_d29, rs_d30, rs_d31};
-static const RegStorage reserved_regs_arr[] =
+static constexpr RegStorage reserved_regs_arr[] =
     {rs_rA32_SUSPEND, rs_rA32_SELF, rs_rA32_SP, rs_rA32_LR, rs_wzr};
-static const RegStorage reserved64_regs_arr[] =
+static constexpr RegStorage reserved64_regs_arr[] =
     {rs_rA64_SUSPEND, rs_rA64_SELF, rs_rA64_SP, rs_rA64_LR, rs_xzr};
 // TUNING: Are there too many temp registers and too less promote target?
 // This definition need to be matched with runtime.cc, quick entry assembly and JNI compiler
 // Note: we are not able to call to C function directly if it un-match C ABI.
 // Currently, rs_rA64_SELF is not a callee save register which does not match C ABI.
-static const RegStorage core_temps_arr[] =
+static constexpr RegStorage core_temps_arr[] =
     {rs_w0, rs_w1, rs_w2, rs_w3, rs_w4, rs_w5, rs_w6, rs_w7,
      rs_w8, rs_w9, rs_w10, rs_w11, rs_w12, rs_w13, rs_w14, rs_w15, rs_w16,
      rs_w17};
-static const RegStorage core64_temps_arr[] =
+static constexpr RegStorage core64_temps_arr[] =
     {rs_x0, rs_x1, rs_x2, rs_x3, rs_x4, rs_x5, rs_x6, rs_x7,
      rs_x8, rs_x9, rs_x10, rs_x11, rs_x12, rs_x13, rs_x14, rs_x15, rs_x16,
      rs_x17};
-static const RegStorage sp_temps_arr[] =
+static constexpr RegStorage sp_temps_arr[] =
     {rs_f0, rs_f1, rs_f2, rs_f3, rs_f4, rs_f5, rs_f6, rs_f7,
      rs_f16, rs_f17, rs_f18, rs_f19, rs_f20, rs_f21, rs_f22, rs_f23,
      rs_f24, rs_f25, rs_f26, rs_f27, rs_f28, rs_f29, rs_f30, rs_f31};
-static const RegStorage dp_temps_arr[] =
+static constexpr RegStorage dp_temps_arr[] =
     {rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7,
      rs_d16, rs_d17, rs_d18, rs_d19, rs_d20, rs_d21, rs_d22, rs_d23,
      rs_d24, rs_d25, rs_d26, rs_d27, rs_d28, rs_d29, rs_d30, rs_d31};
 
-static const std::vector<RegStorage> core_regs(core_regs_arr,
-    core_regs_arr + arraysize(core_regs_arr));
-static const std::vector<RegStorage> core64_regs(core64_regs_arr,
-    core64_regs_arr + arraysize(core64_regs_arr));
-static const std::vector<RegStorage> sp_regs(sp_regs_arr,
-    sp_regs_arr + arraysize(sp_regs_arr));
-static const std::vector<RegStorage> dp_regs(dp_regs_arr,
-    dp_regs_arr + arraysize(dp_regs_arr));
-static const std::vector<RegStorage> reserved_regs(reserved_regs_arr,
-    reserved_regs_arr + arraysize(reserved_regs_arr));
-static const std::vector<RegStorage> reserved64_regs(reserved64_regs_arr,
-    reserved64_regs_arr + arraysize(reserved64_regs_arr));
-static const std::vector<RegStorage> core_temps(core_temps_arr,
-    core_temps_arr + arraysize(core_temps_arr));
-static const std::vector<RegStorage> core64_temps(core64_temps_arr,
-    core64_temps_arr + arraysize(core64_temps_arr));
-static const std::vector<RegStorage> sp_temps(sp_temps_arr, sp_temps_arr + arraysize(sp_temps_arr));
-static const std::vector<RegStorage> dp_temps(dp_temps_arr, dp_temps_arr + arraysize(dp_temps_arr));
+static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr);
+static constexpr ArrayRef<const RegStorage> core64_regs(core64_regs_arr);
+static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr);
+static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr);
+static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr);
+static constexpr ArrayRef<const RegStorage> reserved64_regs(reserved64_regs_arr);
+static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr);
+static constexpr ArrayRef<const RegStorage> core64_temps(core64_temps_arr);
+static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr);
+static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr);
 
 RegLocation Arm64Mir2Lir::LocCReturn() {
   return arm_loc_c_return;
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index fcf5f94..c1a7c99 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -26,41 +26,34 @@
 
 namespace art {
 
-static const RegStorage core_regs_arr[] =
+static constexpr RegStorage core_regs_arr[] =
     {rs_rZERO, rs_rAT, rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2,
      rs_rT3, rs_rT4, rs_rT5, rs_rT6, rs_rT7, rs_rS0, rs_rS1, rs_rS2, rs_rS3, rs_rS4, rs_rS5,
      rs_rS6, rs_rS7, rs_rT8, rs_rT9, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rFP, rs_rRA};
-static RegStorage sp_regs_arr[] =
+static constexpr RegStorage sp_regs_arr[] =
     {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
      rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
-static RegStorage dp_regs_arr[] =
+static constexpr RegStorage dp_regs_arr[] =
     {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
-static const RegStorage reserved_regs_arr[] =
+static constexpr RegStorage reserved_regs_arr[] =
     {rs_rZERO, rs_rAT, rs_rS0, rs_rS1, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rRA};
-static RegStorage core_temps_arr[] =
+static constexpr RegStorage core_temps_arr[] =
     {rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2, rs_rT3, rs_rT4,
      rs_rT5, rs_rT6, rs_rT7, rs_rT8};
-static RegStorage sp_temps_arr[] =
+static constexpr RegStorage sp_temps_arr[] =
     {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
      rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
-static RegStorage dp_temps_arr[] =
+static constexpr RegStorage dp_temps_arr[] =
     {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
 
-static const std::vector<RegStorage> empty_pool;
-static const std::vector<RegStorage> core_regs(core_regs_arr,
-    core_regs_arr + sizeof(core_regs_arr) / sizeof(core_regs_arr[0]));
-static const std::vector<RegStorage> sp_regs(sp_regs_arr,
-    sp_regs_arr + sizeof(sp_regs_arr) / sizeof(sp_regs_arr[0]));
-static const std::vector<RegStorage> dp_regs(dp_regs_arr,
-    dp_regs_arr + sizeof(dp_regs_arr) / sizeof(dp_regs_arr[0]));
-static const std::vector<RegStorage> reserved_regs(reserved_regs_arr,
-    reserved_regs_arr + sizeof(reserved_regs_arr) / sizeof(reserved_regs_arr[0]));
-static const std::vector<RegStorage> core_temps(core_temps_arr,
-    core_temps_arr + sizeof(core_temps_arr) / sizeof(core_temps_arr[0]));
-static const std::vector<RegStorage> sp_temps(sp_temps_arr,
-    sp_temps_arr + sizeof(sp_temps_arr) / sizeof(sp_temps_arr[0]));
-static const std::vector<RegStorage> dp_temps(dp_temps_arr,
-    dp_temps_arr + sizeof(dp_temps_arr) / sizeof(dp_temps_arr[0]));
+static constexpr ArrayRef<const RegStorage> empty_pool;
+static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr);
+static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr);
+static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr);
+static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr);
+static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr);
+static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr);
+static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr);
 
 RegLocation MipsMir2Lir::LocCReturn() {
   return mips_loc_c_return;
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 1281d45..ed94a8d 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -26,6 +26,7 @@
 #include "driver/compiler_driver.h"
 #include "leb128.h"
 #include "safe_map.h"
+#include "utils/array_ref.h"
 #include "utils/arena_allocator.h"
 #include "utils/growable_array.h"
 
@@ -429,16 +430,16 @@
     class RegisterPool {
      public:
       RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena,
-                   const std::vector<RegStorage>& core_regs,
-                   const std::vector<RegStorage>& core64_regs,
-                   const std::vector<RegStorage>& sp_regs,
-                   const std::vector<RegStorage>& dp_regs,
-                   const std::vector<RegStorage>& reserved_regs,
-                   const std::vector<RegStorage>& reserved64_regs,
-                   const std::vector<RegStorage>& core_temps,
-                   const std::vector<RegStorage>& core64_temps,
-                   const std::vector<RegStorage>& sp_temps,
-                   const std::vector<RegStorage>& dp_temps);
+                   const ArrayRef<const RegStorage>& core_regs,
+                   const ArrayRef<const RegStorage>& core64_regs,
+                   const ArrayRef<const RegStorage>& sp_regs,
+                   const ArrayRef<const RegStorage>& dp_regs,
+                   const ArrayRef<const RegStorage>& reserved_regs,
+                   const ArrayRef<const RegStorage>& reserved64_regs,
+                   const ArrayRef<const RegStorage>& core_temps,
+                   const ArrayRef<const RegStorage>& core64_temps,
+                   const ArrayRef<const RegStorage>& sp_temps,
+                   const ArrayRef<const RegStorage>& dp_temps);
       ~RegisterPool() {}
       static void* operator new(size_t size, ArenaAllocator* arena) {
         return arena->Alloc(size, kArenaAllocRegAlloc);
diff --git a/compiler/dex/quick/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc
index 2303c62..bbeef50 100644
--- a/compiler/dex/quick/ralloc_util.cc
+++ b/compiler/dex/quick/ralloc_util.cc
@@ -56,16 +56,16 @@
 }
 
 Mir2Lir::RegisterPool::RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena,
-                                    const std::vector<RegStorage>& core_regs,
-                                    const std::vector<RegStorage>& core64_regs,
-                                    const std::vector<RegStorage>& sp_regs,
-                                    const std::vector<RegStorage>& dp_regs,
-                                    const std::vector<RegStorage>& reserved_regs,
-                                    const std::vector<RegStorage>& reserved64_regs,
-                                    const std::vector<RegStorage>& core_temps,
-                                    const std::vector<RegStorage>& core64_temps,
-                                    const std::vector<RegStorage>& sp_temps,
-                                    const std::vector<RegStorage>& dp_temps) :
+                                    const ArrayRef<const RegStorage>& core_regs,
+                                    const ArrayRef<const RegStorage>& core64_regs,
+                                    const ArrayRef<const RegStorage>& sp_regs,
+                                    const ArrayRef<const RegStorage>& dp_regs,
+                                    const ArrayRef<const RegStorage>& reserved_regs,
+                                    const ArrayRef<const RegStorage>& reserved64_regs,
+                                    const ArrayRef<const RegStorage>& core_temps,
+                                    const ArrayRef<const RegStorage>& core64_temps,
+                                    const ArrayRef<const RegStorage>& sp_temps,
+                                    const ArrayRef<const RegStorage>& dp_temps) :
     core_regs_(arena, core_regs.size()), next_core_reg_(0),
     core64_regs_(arena, core64_regs.size()), next_core64_reg_(0),
     sp_regs_(arena, sp_regs.size()), next_sp_reg_(0),
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 79081c8..6a3ec67 100644
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -26,124 +26,105 @@
 
 namespace art {
 
-static const RegStorage core_regs_arr_32[] = {
+static constexpr RegStorage core_regs_arr_32[] = {
     rs_rAX, rs_rCX, rs_rDX, rs_rBX, rs_rX86_SP_32, rs_rBP, rs_rSI, rs_rDI,
 };
-static const RegStorage core_regs_arr_64[] = {
+static constexpr RegStorage core_regs_arr_64[] = {
     rs_rAX, rs_rCX, rs_rDX, rs_rBX, rs_rX86_SP_64, rs_rBP, rs_rSI, rs_rDI,
 #ifdef TARGET_REX_SUPPORT
     rs_r8, rs_r9, rs_r10, rs_r11, rs_r12, rs_r13, rs_r14, rs_r15
 #endif
 };
-static const RegStorage core_regs_arr_64q[] = {
+static constexpr RegStorage core_regs_arr_64q[] = {
     rs_r0q, rs_r1q, rs_r2q, rs_r3q, rs_rX86_SP_64, rs_r5q, rs_r6q, rs_r7q,
 #ifdef TARGET_REX_SUPPORT
     rs_r8q, rs_r9q, rs_r10q, rs_r11q, rs_r12q, rs_r13q, rs_r14q, rs_r15q
 #endif
 };
-static const RegStorage sp_regs_arr_32[] = {
+static constexpr RegStorage sp_regs_arr_32[] = {
     rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7,
 };
-static const RegStorage sp_regs_arr_64[] = {
+static constexpr RegStorage sp_regs_arr_64[] = {
     rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7,
 #ifdef TARGET_REX_SUPPORT
     rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15
 #endif
 };
-static const RegStorage dp_regs_arr_32[] = {
+static constexpr RegStorage dp_regs_arr_32[] = {
     rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7,
 };
-static const RegStorage dp_regs_arr_64[] = {
+static constexpr RegStorage dp_regs_arr_64[] = {
     rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7,
 #ifdef TARGET_REX_SUPPORT
     rs_dr8, rs_dr9, rs_dr10, rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15
 #endif
 };
-static const RegStorage reserved_regs_arr_32[] = {rs_rX86_SP_32};
-static const RegStorage reserved_regs_arr_64[] = {rs_rX86_SP_64};
-static const RegStorage reserved_regs_arr_64q[] = {rs_rX86_SP_64};
-static const RegStorage core_temps_arr_32[] = {rs_rAX, rs_rCX, rs_rDX, rs_rBX};
-static const RegStorage core_temps_arr_64[] = {
+static constexpr RegStorage reserved_regs_arr_32[] = {rs_rX86_SP_32};
+static constexpr RegStorage reserved_regs_arr_64[] = {rs_rX86_SP_64};
+static constexpr RegStorage reserved_regs_arr_64q[] = {rs_rX86_SP_64};
+static constexpr RegStorage core_temps_arr_32[] = {rs_rAX, rs_rCX, rs_rDX, rs_rBX};
+static constexpr RegStorage core_temps_arr_64[] = {
     rs_rAX, rs_rCX, rs_rDX, rs_rSI, rs_rDI,
 #ifdef TARGET_REX_SUPPORT
     rs_r8, rs_r9, rs_r10, rs_r11
 #endif
 };
-static const RegStorage core_temps_arr_64q[] = {
+static constexpr RegStorage core_temps_arr_64q[] = {
     rs_r0q, rs_r1q, rs_r2q, rs_r6q, rs_r7q,
 #ifdef TARGET_REX_SUPPORT
     rs_r8q, rs_r9q, rs_r10q, rs_r11q
 #endif
 };
-static const RegStorage sp_temps_arr_32[] = {
+static constexpr RegStorage sp_temps_arr_32[] = {
     rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7,
 };
-static const RegStorage sp_temps_arr_64[] = {
+static constexpr RegStorage sp_temps_arr_64[] = {
     rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7,
 #ifdef TARGET_REX_SUPPORT
     rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15
 #endif
 };
-static const RegStorage dp_temps_arr_32[] = {
+static constexpr RegStorage dp_temps_arr_32[] = {
     rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7,
 };
-static const RegStorage dp_temps_arr_64[] = {
+static constexpr RegStorage dp_temps_arr_64[] = {
     rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7,
 #ifdef TARGET_REX_SUPPORT
     rs_dr8, rs_dr9, rs_dr10, rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15
 #endif
 };
 
-static const RegStorage xp_temps_arr_32[] = {
+static constexpr RegStorage xp_temps_arr_32[] = {
     rs_xr0, rs_xr1, rs_xr2, rs_xr3, rs_xr4, rs_xr5, rs_xr6, rs_xr7,
 };
-static const RegStorage xp_temps_arr_64[] = {
+static constexpr RegStorage xp_temps_arr_64[] = {
     rs_xr0, rs_xr1, rs_xr2, rs_xr3, rs_xr4, rs_xr5, rs_xr6, rs_xr7,
 #ifdef TARGET_REX_SUPPORT
     rs_xr8, rs_xr9, rs_xr10, rs_xr11, rs_xr12, rs_xr13, rs_xr14, rs_xr15
 #endif
 };
 
-static const std::vector<RegStorage> empty_pool;
-static const std::vector<RegStorage> core_regs_32(core_regs_arr_32,
-    core_regs_arr_32 + sizeof(core_regs_arr_32) / sizeof(core_regs_arr_32[0]));
-static const std::vector<RegStorage> core_regs_64(core_regs_arr_64,
-    core_regs_arr_64 + sizeof(core_regs_arr_64) / sizeof(core_regs_arr_64[0]));
-static const std::vector<RegStorage> core_regs_64q(core_regs_arr_64q,
-    core_regs_arr_64q + sizeof(core_regs_arr_64q) / sizeof(core_regs_arr_64q[0]));
-static const std::vector<RegStorage> sp_regs_32(sp_regs_arr_32,
-    sp_regs_arr_32 + sizeof(sp_regs_arr_32) / sizeof(sp_regs_arr_32[0]));
-static const std::vector<RegStorage> sp_regs_64(sp_regs_arr_64,
-    sp_regs_arr_64 + sizeof(sp_regs_arr_64) / sizeof(sp_regs_arr_64[0]));
-static const std::vector<RegStorage> dp_regs_32(dp_regs_arr_32,
-    dp_regs_arr_32 + sizeof(dp_regs_arr_32) / sizeof(dp_regs_arr_32[0]));
-static const std::vector<RegStorage> dp_regs_64(dp_regs_arr_64,
-    dp_regs_arr_64 + sizeof(dp_regs_arr_64) / sizeof(dp_regs_arr_64[0]));
-static const std::vector<RegStorage> reserved_regs_32(reserved_regs_arr_32,
-    reserved_regs_arr_32 + sizeof(reserved_regs_arr_32) / sizeof(reserved_regs_arr_32[0]));
-static const std::vector<RegStorage> reserved_regs_64(reserved_regs_arr_64,
-    reserved_regs_arr_64 + sizeof(reserved_regs_arr_64) / sizeof(reserved_regs_arr_64[0]));
-static const std::vector<RegStorage> reserved_regs_64q(reserved_regs_arr_64q,
-    reserved_regs_arr_64q + sizeof(reserved_regs_arr_64q) / sizeof(reserved_regs_arr_64q[0]));
-static const std::vector<RegStorage> core_temps_32(core_temps_arr_32,
-    core_temps_arr_32 + sizeof(core_temps_arr_32) / sizeof(core_temps_arr_32[0]));
-static const std::vector<RegStorage> core_temps_64(core_temps_arr_64,
-    core_temps_arr_64 + sizeof(core_temps_arr_64) / sizeof(core_temps_arr_64[0]));
-static const std::vector<RegStorage> core_temps_64q(core_temps_arr_64q,
-    core_temps_arr_64q + sizeof(core_temps_arr_64q) / sizeof(core_temps_arr_64q[0]));
-static const std::vector<RegStorage> sp_temps_32(sp_temps_arr_32,
-    sp_temps_arr_32 + sizeof(sp_temps_arr_32) / sizeof(sp_temps_arr_32[0]));
-static const std::vector<RegStorage> sp_temps_64(sp_temps_arr_64,
-    sp_temps_arr_64 + sizeof(sp_temps_arr_64) / sizeof(sp_temps_arr_64[0]));
-static const std::vector<RegStorage> dp_temps_32(dp_temps_arr_32,
-    dp_temps_arr_32 + sizeof(dp_temps_arr_32) / sizeof(dp_temps_arr_32[0]));
-static const std::vector<RegStorage> dp_temps_64(dp_temps_arr_64,
-    dp_temps_arr_64 + sizeof(dp_temps_arr_64) / sizeof(dp_temps_arr_64[0]));
+static constexpr ArrayRef<const RegStorage> empty_pool;
+static constexpr ArrayRef<const RegStorage> core_regs_32(core_regs_arr_32);
+static constexpr ArrayRef<const RegStorage> core_regs_64(core_regs_arr_64);
+static constexpr ArrayRef<const RegStorage> core_regs_64q(core_regs_arr_64q);
+static constexpr ArrayRef<const RegStorage> sp_regs_32(sp_regs_arr_32);
+static constexpr ArrayRef<const RegStorage> sp_regs_64(sp_regs_arr_64);
+static constexpr ArrayRef<const RegStorage> dp_regs_32(dp_regs_arr_32);
+static constexpr ArrayRef<const RegStorage> dp_regs_64(dp_regs_arr_64);
+static constexpr ArrayRef<const RegStorage> reserved_regs_32(reserved_regs_arr_32);
+static constexpr ArrayRef<const RegStorage> reserved_regs_64(reserved_regs_arr_64);
+static constexpr ArrayRef<const RegStorage> reserved_regs_64q(reserved_regs_arr_64q);
+static constexpr ArrayRef<const RegStorage> core_temps_32(core_temps_arr_32);
+static constexpr ArrayRef<const RegStorage> core_temps_64(core_temps_arr_64);
+static constexpr ArrayRef<const RegStorage> core_temps_64q(core_temps_arr_64q);
+static constexpr ArrayRef<const RegStorage> sp_temps_32(sp_temps_arr_32);
+static constexpr ArrayRef<const RegStorage> sp_temps_64(sp_temps_arr_64);
+static constexpr ArrayRef<const RegStorage> dp_temps_32(dp_temps_arr_32);
+static constexpr ArrayRef<const RegStorage> dp_temps_64(dp_temps_arr_64);
 
-static const std::vector<RegStorage> xp_temps_32(xp_temps_arr_32,
-    xp_temps_arr_32 + sizeof(xp_temps_arr_32) / sizeof(xp_temps_arr_32[0]));
-static const std::vector<RegStorage> xp_temps_64(xp_temps_arr_64,
-    xp_temps_arr_64 + sizeof(xp_temps_arr_64) / sizeof(xp_temps_arr_64[0]));
+static constexpr ArrayRef<const RegStorage> xp_temps_32(xp_temps_arr_32);
+static constexpr ArrayRef<const RegStorage> xp_temps_64(xp_temps_arr_64);
 
 RegStorage rs_rX86_SP;
 
@@ -582,7 +563,7 @@
   // Target-specific adjustments.
 
   // Add in XMM registers.
-  const std::vector<RegStorage> *xp_temps = Gen64Bit() ? &xp_temps_64 : &xp_temps_32;
+  const ArrayRef<const RegStorage> *xp_temps = Gen64Bit() ? &xp_temps_64 : &xp_temps_32;
   for (RegStorage reg : *xp_temps) {
     RegisterInfo* info = new (arena_) RegisterInfo(reg, GetRegMaskCommon(reg));
     reginfo_map_.Put(reg.GetReg(), info);
diff --git a/compiler/utils/array_ref.h b/compiler/utils/array_ref.h
new file mode 100644
index 0000000..5a68874
--- /dev/null
+++ b/compiler/utils/array_ref.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef ART_COMPILER_UTILS_ARRAY_REF_H_
+#define ART_COMPILER_UTILS_ARRAY_REF_H_
+
+#include <type_traits>
+#include <vector>
+
+#include "base/logging.h"
+
+namespace art {
+
+template <typename T, bool ok> struct ArrayRefHelper;
+
+/**
+ * @brief A container that references an array.
+ *
+ * @details The template class ArrayRef provides a container that references
+ * an external array. This external array must remain alive while the ArrayRef
+ * object is in use. The external array may be a std::vector<>-backed storage
+ * or any other contiguous chunk of memory but that memory must remain valid,
+ * i.e. the std::vector<> must not be resized for example.
+ *
+ * Except for copy/assign and insert/erase/capacity functions, the interface
+ * is essentially the same as std::vector<>. Since we don't want to throw
+ * exceptions, at() is also excluded.
+ */
+template <typename T>
+class ArrayRef {
+ public:
+  typedef T value_type;
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef T* pointer;
+  typedef const T* const_pointer;
+  typedef T* iterator;
+  typedef const T* const_iterator;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef ptrdiff_t difference_type;
+  typedef size_t size_type;
+
+  // Constructors.
+
+  constexpr ArrayRef()
+      : array_(nullptr), size_(0u) {
+  }
+
+  template <size_t size>
+  constexpr ArrayRef(T (&array)[size])
+    : array_(array), size_(size) {
+  }
+
+  template <typename U, size_t size>
+  constexpr ArrayRef(U (&array)[size],
+                     typename ArrayRefHelper<T, std::is_same<T, const U>::value>::tag t = tag())
+    : array_(array), size_(size) {
+  }
+
+  constexpr ArrayRef(T* array, size_t size)
+      : array_(array), size_(size) {
+  }
+
+  template <typename U>
+  constexpr ArrayRef(U* array, size_t size,
+                     typename ArrayRefHelper<T, std::is_same<T, const U>::value>::tag t = tag())
+      : array_(array), size_(size) {
+  }
+
+  explicit ArrayRef(std::vector<T>& v)
+      : array_(v.data()), size_(v.size()) {
+  }
+
+  template <typename U>
+  ArrayRef(const std::vector<U>& v,
+           typename ArrayRefHelper<T, std::is_same<T, const U>::value>::tag t = tag())
+      : array_(v.data()), size_(v.size()) {
+  }
+
+  // Assignment operators.
+
+  ArrayRef& operator=(const ArrayRef& other) {
+    array_ = other.array_;
+    size_ = other.size_;
+    return *this;
+  }
+
+  template <typename U>
+  typename ArrayRefHelper<T, std::is_same<T, const U>::value>::type&
+  operator=(const ArrayRef<U>& other) {
+    return *this = ArrayRef(other);
+  }
+
+  // Destructor.
+  ~ArrayRef() = default;
+
+  // Iterators.
+  iterator begin() { return array_; }
+  const_iterator begin() const { return array_; }
+  const_iterator cbegin() const { return array_; }
+  iterator end() { return array_ + size_; }
+  const_iterator end() const { return array_ + size_; }
+  const_iterator cend() const { return array_ + size_; }
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+  const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); }
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+  const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }
+
+  // Size.
+  size_type size() const { return size_; }
+  bool empty() const { return size() == 0u; }
+
+  // Element access. NOTE: Not providing at().
+
+  reference operator[](size_type n) {
+    DCHECK_LT(n, size_);
+    return array_[n];
+  }
+
+  const_reference operator[](size_type n) const {
+    DCHECK_LT(n, size_);
+    return array_[n];
+  }
+
+  reference front() {
+    DCHECK_NE(size_, 0u);
+    return array_[0];
+  }
+
+  const_reference front() const {
+    DCHECK_NE(size_, 0u);
+    return array_[0];
+  }
+
+  reference back() {
+    DCHECK_NE(size_, 0u);
+    return array_[size_ - 1u];
+  }
+
+  const_reference back() const {
+    DCHECK_NE(size_, 0u);
+    return array_[size_ - 1u];
+  }
+
+  value_type* data() { return array_; }
+  const value_type* data() const { return array_; }
+
+ private:
+  struct tag { };
+  friend struct ArrayRefHelper<T, true>;
+
+  T* array_;
+  size_t size_;
+};
+
+template <typename T> struct ArrayRefHelper<T, true> {
+  typedef typename ArrayRef<T>::tag tag;
+  typedef ArrayRef<T> type;
+};
+
+template <typename T> struct ArrayRefHelper<T, false> {
+  // SFINAE: No "tag" or "type" typedef.
+};
+
+}  // namespace art
+
+
+#endif  // ART_COMPILER_UTILS_ARRAY_REF_H_