Optimizing: Tag arena allocations in HGraph.

Replace GrowableArray with ArenaVector in HGraph and related
classes HEnvironment, HLoopInformation, HInvoke and HPhi,
and tag allocations with new arena allocation types.

Change-Id: I3d79897af405b9a1a5b98bfc372e70fe0b3bc40d
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 0d95390..62f5b9a 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -284,8 +284,7 @@
   }
 
   static bool DominatesAllBackEdges(HBasicBlock* block, HLoopInformation* loop_info) {
-    for (size_t i = 0, e = loop_info->GetBackEdges().Size(); i < e; ++i) {
-      HBasicBlock* back_edge = loop_info->GetBackEdges().Get(i);
+    for (HBasicBlock* back_edge : loop_info->GetBackEdges()) {
       if (!block->Dominates(back_edge)) {
         return false;
       }
@@ -1109,9 +1108,9 @@
 
   BCEVisitor(HGraph* graph, HInductionVarAnalysis* induction_analysis)
       : HGraphVisitor(graph),
-        maps_(graph->GetBlocks().Size()),
+        maps_(graph->GetBlocks().size()),
         need_to_revisit_block_(false),
-        initial_block_size_(graph->GetBlocks().Size()),
+        initial_block_size_(graph->GetBlocks().size()),
         induction_range_(induction_analysis) {}
 
   void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
@@ -1852,7 +1851,7 @@
   bool need_to_revisit_block_;
 
   // Initial number of blocks.
-  int32_t initial_block_size_;
+  uint32_t initial_block_size_;
 
   // Range analysis based on induction variables.
   InductionVarRange induction_range_;
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 0a3f083..97545ed 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -339,11 +339,10 @@
 
   // Bit vector stores information on which blocks contain throwing instructions.
   // Must be expandable because catch blocks may be split into two.
-  ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().Size(), /* expandable */ true);
+  ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().size(), /* expandable */ true);
 
   // Scan blocks and mark those which contain throwing instructions.
-  for (size_t block_id = 0, e = graph_->GetBlocks().Size(); block_id < e; ++block_id) {
-    HBasicBlock* block = graph_->GetBlocks().Get(block_id);
+  for (HBasicBlock* block : graph_->GetBlocks()) {
     bool can_throw = false;
     for (HInstructionIterator insn(block->GetInstructions()); !insn.Done(); insn.Advance()) {
       if (insn.Current()->CanThrow()) {
@@ -381,9 +380,7 @@
   //   (c) link the new blocks to corresponding exception handlers.
   // We cannot iterate only over blocks in `branch_targets_` because switch-case
   // blocks share the same dex_pc.
-  for (size_t block_id = 0, e = graph_->GetBlocks().Size(); block_id < e; ++block_id) {
-    HBasicBlock* try_block = graph_->GetBlocks().Get(block_id);
-
+  for (HBasicBlock* try_block : graph_->GetBlocks()) {
     // TryBoundary blocks are added at the end of the list and not iterated over.
     DCHECK(!try_block->IsSingleTryBoundary());
 
@@ -465,7 +462,7 @@
 }
 
 bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
-  DCHECK(graph_->GetBlocks().IsEmpty());
+  DCHECK(graph_->GetBlocks().empty());
 
   const uint16_t* code_ptr = code_item.insns_;
   const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 3bbff6a..aadf525 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -155,13 +155,14 @@
 }
 
 bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const {
-  DCHECK_EQ(block_order_->Get(current_block_index_), current);
+  DCHECK_LT(current_block_index_, block_order_->size());
+  DCHECK_EQ((*block_order_)[current_block_index_], current);
   return GetNextBlockToEmit() == FirstNonEmptyBlock(next);
 }
 
 HBasicBlock* CodeGenerator::GetNextBlockToEmit() const {
-  for (size_t i = current_block_index_ + 1; i < block_order_->Size(); ++i) {
-    HBasicBlock* block = block_order_->Get(i);
+  for (size_t i = current_block_index_ + 1; i < block_order_->size(); ++i) {
+    HBasicBlock* block = (*block_order_)[i];
     if (!block->IsSingleJump()) {
       return block;
     }
@@ -225,8 +226,8 @@
     disasm_info_->SetFrameEntryInterval(frame_start, GetAssembler()->CodeSize());
   }
 
-  for (size_t e = block_order_->Size(); current_block_index_ < e; ++current_block_index_) {
-    HBasicBlock* block = block_order_->Get(current_block_index_);
+  for (size_t e = block_order_->size(); current_block_index_ < e; ++current_block_index_) {
+    HBasicBlock* block = (*block_order_)[current_block_index_];
     // Don't generate code for an empty block. Its predecessors will branch to its successor
     // directly. Also, the label of that block will not be emitted, so this helps catch
     // errors where we reference that label.
@@ -305,9 +306,10 @@
                                              size_t maximum_number_of_live_core_registers,
                                              size_t maximum_number_of_live_fp_registers,
                                              size_t number_of_out_slots,
-                                             const GrowableArray<HBasicBlock*>& block_order) {
+                                             const ArenaVector<HBasicBlock*>& block_order) {
   block_order_ = &block_order;
-  DCHECK(block_order_->Get(0) == GetGraph()->GetEntryBlock());
+  DCHECK(!block_order.empty());
+  DCHECK(block_order[0] == GetGraph()->GetEntryBlock());
   ComputeSpillMask();
   first_register_slot_in_slow_path_ = (number_of_out_slots + number_of_spill_slots) * kVRegSize;
 
@@ -632,8 +634,7 @@
   }
 
   // Walk over the blocks and find which ones correspond to catch block entries.
-  for (size_t i = 0; i < graph_->GetBlocks().Size(); ++i) {
-    HBasicBlock* block = graph_->GetBlocks().Get(i);
+  for (HBasicBlock* block : graph_->GetBlocks()) {
     if (block->IsCatchBlock()) {
       intptr_t native_pc = GetAddressOf(block);
       ++dex2pc_entries;
@@ -671,8 +672,7 @@
     pc2dex_dalvik_offset = stack_map_entry.dex_pc;
   }
 
-  for (size_t i = 0; i < graph_->GetBlocks().Size(); ++i) {
-    HBasicBlock* block = graph_->GetBlocks().Get(i);
+  for (HBasicBlock* block : graph_->GetBlocks()) {
     if (block->IsCatchBlock()) {
       intptr_t native_pc = GetAddressOf(block);
       write_pos2 = EncodeUnsignedLeb128(write_pos2, native_pc - dex2pc_offset);
@@ -699,8 +699,7 @@
       CHECK_EQ(stack_map_entry.dex_pc, it.DexPc());
       ++it;
     }
-    for (size_t i = 0; i < graph_->GetBlocks().Size(); ++i) {
-      HBasicBlock* block = graph_->GetBlocks().Get(i);
+    for (HBasicBlock* block : graph_->GetBlocks()) {
       if (block->IsCatchBlock()) {
         CHECK_EQ(GetAddressOf(block), it2.NativePcOffset());
         CHECK_EQ(block->GetDexPc(), it2.DexPc());
@@ -814,8 +813,7 @@
 void CodeGenerator::RecordCatchBlockInfo() {
   ArenaAllocator* arena = graph_->GetArena();
 
-  for (size_t i = 0, e = block_order_->Size(); i < e; ++i) {
-    HBasicBlock* block = block_order_->Get(i);
+  for (HBasicBlock* block : *block_order_) {
     if (!block->IsCatchBlock()) {
       continue;
     }
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index a93d07a..11daf3f 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -176,7 +176,7 @@
                                 size_t maximum_number_of_live_core_registers,
                                 size_t maximum_number_of_live_fp_registers,
                                 size_t number_of_out_slots,
-                                const GrowableArray<HBasicBlock*>& block_order);
+                                const ArenaVector<HBasicBlock*>& block_order);
   int32_t GetStackSlot(HLocal* local) const;
   Location GetTemporaryLocation(HTemporary* temp) const;
 
@@ -488,7 +488,7 @@
   StackMapStream stack_map_stream_;
 
   // The order to use for code generation.
-  const GrowableArray<HBasicBlock*>* block_order_;
+  const ArenaVector<HBasicBlock*>* block_order_;
 
   // Whether we are using baseline.
   bool is_baseline_;
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index b3e38f0..eefcf7a 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -436,8 +436,7 @@
     stack_map_stream_.SetStackMapNativePcOffset(i, new_position);
   }
   // Adjust native pc offsets of block labels.
-  for (size_t block_idx = 0u, end = block_order_->Size(); block_idx != end; ++block_idx) {
-    HBasicBlock* block = block_order_->Get(block_idx);
+  for (HBasicBlock* block : *block_order_) {
     // Get the label directly from block_labels_ rather than through GetLabelOf() to avoid
     // FirstNonEmptyBlock() which could lead to adjusting a label more than once.
     DCHECK_LT(static_cast<size_t>(block->GetBlockId()), block_labels_.Size());
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 4a0df4e..2baac61 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -309,7 +309,7 @@
   }
 
   void Initialize() OVERRIDE {
-    block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+    block_labels_.SetSize(GetGraph()->GetBlocks().size());
   }
 
   void Finalize(CodeAllocator* allocator) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index 12ead7e..7ebe884 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -326,7 +326,7 @@
 
   void Initialize() OVERRIDE {
     HGraph* graph = GetGraph();
-    int length = graph->GetBlocks().Size();
+    int length = graph->GetBlocks().size();
     block_labels_ = graph->GetArena()->AllocArray<vixl::Label>(length);
     for (int i = 0; i < length; ++i) {
       new(block_labels_ + i) vixl::Label();
diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h
index ae7c568..5433b75 100644
--- a/compiler/optimizing/code_generator_mips64.h
+++ b/compiler/optimizing/code_generator_mips64.h
@@ -273,7 +273,7 @@
   }
 
   void Initialize() OVERRIDE {
-    block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+    block_labels_.SetSize(GetGraph()->GetBlocks().size());
   }
 
   void Finalize(CodeAllocator* allocator) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index bd7cb12..5e4952f 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -312,7 +312,7 @@
   }
 
   void Initialize() OVERRIDE {
-    block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+    block_labels_.SetSize(GetGraph()->GetBlocks().size());
   }
 
   bool NeedsTwoRegisters(Primitive::Type type) const OVERRIDE {
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index f9d8e04..cc1c524 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -297,7 +297,7 @@
   }
 
   void Initialize() OVERRIDE {
-    block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+    block_labels_.SetSize(GetGraph()->GetBlocks().size());
   }
 
   bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc
index 72c67f5..5fc305c 100644
--- a/compiler/optimizing/codegen_test.cc
+++ b/compiler/optimizing/codegen_test.cc
@@ -193,7 +193,7 @@
                              bool has_result,
                              Expected expected) {
   // Tests may have already computed it.
-  if (graph->GetReversePostOrder().IsEmpty()) {
+  if (graph->GetReversePostOrder().empty()) {
     graph->BuildDominatorTree();
   }
   SsaLivenessAnalysis liveness(graph, codegen);
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index 509478c..7d509a2 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -64,8 +64,8 @@
 void HDeadCodeElimination::RemoveDeadBlocks() {
   // Classify blocks as reachable/unreachable.
   ArenaAllocator* allocator = graph_->GetArena();
-  ArenaBitVector live_blocks(allocator, graph_->GetBlocks().Size(), false);
-  ArenaBitVector affected_loops(allocator, graph_->GetBlocks().Size(), false);
+  ArenaBitVector live_blocks(allocator, graph_->GetBlocks().size(), false);
+  ArenaBitVector affected_loops(allocator, graph_->GetBlocks().size(), false);
 
   MarkReachableBlocks(graph_->GetEntryBlock(), &live_blocks);
   bool removed_one_or_more_blocks = false;
diff --git a/compiler/optimizing/dominator_test.cc b/compiler/optimizing/dominator_test.cc
index 78ae1dd..6b18650 100644
--- a/compiler/optimizing/dominator_test.cc
+++ b/compiler/optimizing/dominator_test.cc
@@ -24,7 +24,7 @@
 
 namespace art {
 
-static void TestCode(const uint16_t* data, const int* blocks, size_t blocks_length) {
+static void TestCode(const uint16_t* data, const uint32_t* blocks, size_t blocks_length) {
   ArenaPool pool;
   ArenaAllocator allocator(&pool);
   HGraph* graph = CreateGraph(&allocator);
@@ -33,19 +33,19 @@
   bool graph_built = builder.BuildGraph(*item);
   ASSERT_TRUE(graph_built);
   graph->BuildDominatorTree();
-  ASSERT_EQ(graph->GetBlocks().Size(), blocks_length);
+  ASSERT_EQ(graph->GetBlocks().size(), blocks_length);
   for (size_t i = 0, e = blocks_length; i < e; ++i) {
-    if (blocks[i] == -1) {
-      if (graph->GetBlocks().Get(i) == nullptr) {
+    if (blocks[i] == kInvalidBlockId) {
+      if (graph->GetBlock(i) == nullptr) {
         // Dead block.
       } else {
         // Only the entry block has no dominator.
-        ASSERT_EQ(nullptr, graph->GetBlocks().Get(i)->GetDominator());
-        ASSERT_TRUE(graph->GetBlocks().Get(i)->IsEntryBlock());
+        ASSERT_EQ(nullptr, graph->GetBlock(i)->GetDominator());
+        ASSERT_TRUE(graph->GetBlock(i)->IsEntryBlock());
       }
     } else {
-      ASSERT_NE(nullptr, graph->GetBlocks().Get(i)->GetDominator());
-      ASSERT_EQ(blocks[i], graph->GetBlocks().Get(i)->GetDominator()->GetBlockId());
+      ASSERT_NE(nullptr, graph->GetBlock(i)->GetDominator());
+      ASSERT_EQ(blocks[i], graph->GetBlock(i)->GetDominator()->GetBlockId());
     }
   }
 }
@@ -54,10 +54,10 @@
   const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
       Instruction::RETURN_VOID);  // Block number 1
 
-  const int dominators[] = {
-    -1,
-    0,
-    1
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -68,11 +68,11 @@
     Instruction::GOTO | 0x100,  // Block number 1
     Instruction::RETURN_VOID);  // Block number 2
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    2
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      2
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -84,12 +84,12 @@
     Instruction::GOTO | 0x100,  // Block number 2
     Instruction::RETURN_VOID);  // Block number 3
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    2,
-    3
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      2,
+      3
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -101,12 +101,12 @@
     Instruction::RETURN_VOID,     // Block number 2
     Instruction::GOTO | 0xFF00);  // Block number 3
 
-  const int dominators[] = {
-    -1,
-    0,
-    3,
-    1,
-    2
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      3,
+      1,
+      2
   };
 
   TestCode(data1, dominators, sizeof(dominators) / sizeof(int));
@@ -131,10 +131,10 @@
     Instruction::NOP,
     Instruction::GOTO | 0xFF00);
 
-  const int dominators[] = {
-    -1,
-    0,
-    -1
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      kInvalidBlockId
   };
 
   TestCode(data1, dominators, sizeof(dominators) / sizeof(int));
@@ -152,11 +152,11 @@
     Instruction::GOTO | 0xFE00);  // Block number 2
 
 
-  const int dominators[] = {
-    -1,
-    0,
-    -1,
-    1
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      kInvalidBlockId,
+      1
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -169,13 +169,13 @@
     Instruction::GOTO | 0x100,
     Instruction::RETURN_VOID);
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    1,
-    3,
-    1,  // Synthesized block to avoid critical edge.
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      1,
+      3,
+      1,  // Synthesized block to avoid critical edge.
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -188,14 +188,14 @@
     Instruction::GOTO | 0x100,    // Block number 2
     Instruction::GOTO | 0xFF00);  // Block number 3
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    1,
-    -1,  // exit block is not dominated by any block due to the spin loop.
-    1,   // block to avoid critical edge.
-    1    // block to avoid critical edge.
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      1,
+      kInvalidBlockId,  // exit block is not dominated by any block due to the spin loop.
+      1,   // block to avoid critical edge.
+      1    // block to avoid critical edge.
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -209,14 +209,14 @@
     Instruction::GOTO | 0x100,    // Block number 3
     Instruction::GOTO | 0xFF00);  // Block number 4
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    1,
-    1,
-    -1,  // exit block is not dominated by any block due to the spin loop.
-    1    // block to avoid critical edge.
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      1,
+      1,
+      kInvalidBlockId,  // exit block is not dominated by any block due to the spin loop.
+      1    // block to avoid critical edge.
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -230,14 +230,14 @@
     Instruction::GOTO | 0x100,    // Block number 3
     Instruction::GOTO | 0xFE00);  // Block number 4
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    1,
-    1,
-    -1,  // exit block is not dominated by any block due to the spin loop.
-    1    // block to avoid critical edge.
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      1,
+      1,
+      kInvalidBlockId,  // exit block is not dominated by any block due to the spin loop.
+      1    // block to avoid critical edge.
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
@@ -252,16 +252,16 @@
     Instruction::GOTO | 0x100,  // Block number 4
     Instruction::RETURN_VOID);  // Block number 5
 
-  const int dominators[] = {
-    -1,
-    0,
-    1,
-    2,
-    2,
-    1,
-    5,    // Block number 5 dominates exit block
-    1,    // block to avoid critical edge.
-    2     // block to avoid critical edge.
+  const uint32_t dominators[] = {
+      kInvalidBlockId,
+      0,
+      1,
+      2,
+      2,
+      1,
+      5,    // Block number 5 dominates exit block
+      1,    // block to avoid critical edge.
+      2     // block to avoid critical edge.
   };
 
   TestCode(data, dominators, sizeof(dominators) / sizeof(int));
diff --git a/compiler/optimizing/find_loops_test.cc b/compiler/optimizing/find_loops_test.cc
index 29aa97a..9e0d352 100644
--- a/compiler/optimizing/find_loops_test.cc
+++ b/compiler/optimizing/find_loops_test.cc
@@ -46,8 +46,8 @@
   ArenaPool arena;
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    ASSERT_EQ(block->GetLoopInformation(), nullptr);
   }
 }
 
@@ -59,8 +59,8 @@
   ArenaPool arena;
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    ASSERT_EQ(block->GetLoopInformation(), nullptr);
   }
 }
 
@@ -75,8 +75,8 @@
   ArenaPool arena;
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    ASSERT_EQ(block->GetLoopInformation(), nullptr);
   }
 }
 
@@ -92,8 +92,8 @@
   ArenaPool arena;
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    ASSERT_EQ(block->GetLoopInformation(), nullptr);
   }
 }
 
@@ -107,20 +107,20 @@
   ArenaPool arena;
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    ASSERT_EQ(block->GetLoopInformation(), nullptr);
   }
 }
 
 static void TestBlock(HGraph* graph,
-                      int block_id,
+                      uint32_t block_id,
                       bool is_loop_header,
-                      int parent_loop_header_id,
+                      uint32_t parent_loop_header_id,
                       const int* blocks_in_loop = nullptr,
                       size_t number_of_blocks = 0) {
-  HBasicBlock* block = graph->GetBlocks().Get(block_id);
+  HBasicBlock* block = graph->GetBlock(block_id);
   ASSERT_EQ(block->IsLoopHeader(), is_loop_header);
-  if (parent_loop_header_id == -1) {
+  if (parent_loop_header_id == kInvalidBlockId) {
     ASSERT_EQ(block->GetLoopInformation(), nullptr);
   } else {
     ASSERT_EQ(block->GetLoopInformation()->GetHeader()->GetBlockId(), parent_loop_header_id);
@@ -154,13 +154,13 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // pre header
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // pre header
   const int blocks2[] = {2, 3};
-  TestBlock(graph, 2, true, 2, blocks2, 2);  // loop header
-  TestBlock(graph, 3, false, 2);             // block in loop
-  TestBlock(graph, 4, false, -1);            // return block
-  TestBlock(graph, 5, false, -1);            // exit block
+  TestBlock(graph, 2, true, 2, blocks2, 2);     // loop header
+  TestBlock(graph, 3, false, 2);                // block in loop
+  TestBlock(graph, 4, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 5, false, kInvalidBlockId);  // exit block
 }
 
 TEST(FindLoopsTest, Loop2) {
@@ -182,14 +182,14 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // goto block
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // goto block
   const int blocks2[] = {2, 3};
-  TestBlock(graph, 2, true, 2, blocks2, 2);  // loop header
-  TestBlock(graph, 3, false, 2);             // block in loop
-  TestBlock(graph, 4, false, -1);            // pre header
-  TestBlock(graph, 5, false, -1);            // return block
-  TestBlock(graph, 6, false, -1);            // exit block
+  TestBlock(graph, 2, true, 2, blocks2, 2);     // loop header
+  TestBlock(graph, 3, false, 2);                // block in loop
+  TestBlock(graph, 4, false, kInvalidBlockId);  // pre header
+  TestBlock(graph, 5, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 6, false, kInvalidBlockId);  // exit block
 }
 
 TEST(FindLoopsTest, Loop3) {
@@ -207,16 +207,16 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // goto block
-  TestBlock(graph, 2, false, -1);
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // goto block
+  TestBlock(graph, 2, false, kInvalidBlockId);
   const int blocks2[] = {3, 4};
-  TestBlock(graph, 3, true, 3, blocks2, 2);  // loop header
-  TestBlock(graph, 4, false, 3);             // block in loop
-  TestBlock(graph, 5, false, -1);            // pre header
-  TestBlock(graph, 6, false, -1);            // return block
-  TestBlock(graph, 7, false, -1);            // exit block
-  TestBlock(graph, 8, false, -1);            // synthesized pre header
+  TestBlock(graph, 3, true, 3, blocks2, 2);     // loop header
+  TestBlock(graph, 4, false, 3);                // block in loop
+  TestBlock(graph, 5, false, kInvalidBlockId);  // pre header
+  TestBlock(graph, 6, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 7, false, kInvalidBlockId);  // exit block
+  TestBlock(graph, 8, false, kInvalidBlockId);  // synthesized pre header
 }
 
 TEST(FindLoopsTest, Loop4) {
@@ -233,15 +233,15 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // pre header
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // pre header
   const int blocks2[] = {2, 3, 4, 5};
   TestBlock(graph, 2, true, 2, blocks2, arraysize(blocks2));  // loop header
-  TestBlock(graph, 3, false, 2);             // block in loop
-  TestBlock(graph, 4, false, 2);             // back edge
-  TestBlock(graph, 5, false, 2);             // back edge
-  TestBlock(graph, 6, false, -1);            // return block
-  TestBlock(graph, 7, false, -1);            // exit block
+  TestBlock(graph, 3, false, 2);                // block in loop
+  TestBlock(graph, 4, false, 2);                // back edge
+  TestBlock(graph, 5, false, 2);                // back edge
+  TestBlock(graph, 6, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 7, false, kInvalidBlockId);  // exit block
 }
 
 
@@ -259,16 +259,16 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // pre header
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // pre header
   const int blocks2[] = {2, 3, 5};
-  TestBlock(graph, 2, true, 2, blocks2, 3);  // loop header
-  TestBlock(graph, 3, false, 2);             // block in loop
-  TestBlock(graph, 4, false, -1);            // loop exit
-  TestBlock(graph, 5, false, 2);             // back edge
-  TestBlock(graph, 6, false, -1);            // return block
-  TestBlock(graph, 7, false, -1);            // exit block
-  TestBlock(graph, 8, false, -1);            // synthesized block at the loop exit
+  TestBlock(graph, 2, true, 2, blocks2, 3);     // loop header
+  TestBlock(graph, 3, false, 2);                // block in loop
+  TestBlock(graph, 4, false, kInvalidBlockId);  // loop exit
+  TestBlock(graph, 5, false, 2);                // back edge
+  TestBlock(graph, 6, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 7, false, kInvalidBlockId);  // exit block
+  TestBlock(graph, 8, false, kInvalidBlockId);  // synthesized block at the loop exit
 }
 
 TEST(FindLoopsTest, InnerLoop) {
@@ -284,22 +284,22 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // pre header of outer loop
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // pre header of outer loop
   const int blocks2[] = {2, 3, 4, 5, 8};
-  TestBlock(graph, 2, true, 2, blocks2, 5);  // outer loop header
+  TestBlock(graph, 2, true, 2, blocks2, 5);     // outer loop header
   const int blocks3[] = {3, 4};
-  TestBlock(graph, 3, true, 3, blocks3, 2);  // inner loop header
-  TestBlock(graph, 4, false, 3);             // back edge on inner loop
-  TestBlock(graph, 5, false, 2);             // back edge on outer loop
-  TestBlock(graph, 6, false, -1);            // return block
-  TestBlock(graph, 7, false, -1);            // exit block
-  TestBlock(graph, 8, false, 2);             // synthesized block as pre header of inner loop
+  TestBlock(graph, 3, true, 3, blocks3, 2);     // inner loop header
+  TestBlock(graph, 4, false, 3);                // back edge on inner loop
+  TestBlock(graph, 5, false, 2);                // back edge on outer loop
+  TestBlock(graph, 6, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 7, false, kInvalidBlockId);  // exit block
+  TestBlock(graph, 8, false, 2);                // synthesized block as pre header of inner loop
 
-  ASSERT_TRUE(graph->GetBlocks().Get(3)->GetLoopInformation()->IsIn(
-                    *graph->GetBlocks().Get(2)->GetLoopInformation()));
-  ASSERT_FALSE(graph->GetBlocks().Get(2)->GetLoopInformation()->IsIn(
-                    *graph->GetBlocks().Get(3)->GetLoopInformation()));
+  ASSERT_TRUE(graph->GetBlock(3)->GetLoopInformation()->IsIn(
+                    *graph->GetBlock(2)->GetLoopInformation()));
+  ASSERT_FALSE(graph->GetBlock(2)->GetLoopInformation()->IsIn(
+                    *graph->GetBlock(3)->GetLoopInformation()));
 }
 
 TEST(FindLoopsTest, TwoLoops) {
@@ -315,21 +315,21 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // pre header of first loop
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // pre header of first loop
   const int blocks2[] = {2, 3};
-  TestBlock(graph, 2, true, 2, blocks2, 2);  // first loop header
-  TestBlock(graph, 3, false, 2);             // back edge of first loop
+  TestBlock(graph, 2, true, 2, blocks2, 2);     // first loop header
+  TestBlock(graph, 3, false, 2);                // back edge of first loop
   const int blocks4[] = {4, 5};
-  TestBlock(graph, 4, true, 4, blocks4, 2);  // second loop header
-  TestBlock(graph, 5, false, 4);             // back edge of second loop
-  TestBlock(graph, 6, false, -1);            // return block
-  TestBlock(graph, 7, false, -1);            // exit block
+  TestBlock(graph, 4, true, 4, blocks4, 2);     // second loop header
+  TestBlock(graph, 5, false, 4);                // back edge of second loop
+  TestBlock(graph, 6, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 7, false, kInvalidBlockId);  // exit block
 
-  ASSERT_FALSE(graph->GetBlocks().Get(4)->GetLoopInformation()->IsIn(
-                    *graph->GetBlocks().Get(2)->GetLoopInformation()));
-  ASSERT_FALSE(graph->GetBlocks().Get(2)->GetLoopInformation()->IsIn(
-                    *graph->GetBlocks().Get(4)->GetLoopInformation()));
+  ASSERT_FALSE(graph->GetBlock(4)->GetLoopInformation()->IsIn(
+                    *graph->GetBlock(2)->GetLoopInformation()));
+  ASSERT_FALSE(graph->GetBlock(2)->GetLoopInformation()->IsIn(
+                    *graph->GetBlock(4)->GetLoopInformation()));
 }
 
 TEST(FindLoopsTest, NonNaturalLoop) {
@@ -344,9 +344,10 @@
   ArenaPool arena;
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
-  ASSERT_TRUE(graph->GetBlocks().Get(3)->IsLoopHeader());
-  HLoopInformation* info = graph->GetBlocks().Get(3)->GetLoopInformation();
-  ASSERT_FALSE(info->GetHeader()->Dominates(info->GetBackEdges().Get(0)));
+  ASSERT_TRUE(graph->GetBlock(3)->IsLoopHeader());
+  HLoopInformation* info = graph->GetBlock(3)->GetLoopInformation();
+  ASSERT_EQ(1u, info->NumberOfBackEdges());
+  ASSERT_FALSE(info->GetHeader()->Dominates(info->GetBackEdges()[0]));
 }
 
 TEST(FindLoopsTest, DoWhileLoop) {
@@ -360,14 +361,14 @@
   ArenaAllocator allocator(&arena);
   HGraph* graph = TestCode(data, &allocator);
 
-  TestBlock(graph, 0, false, -1);            // entry block
-  TestBlock(graph, 1, false, -1);            // pre header of first loop
+  TestBlock(graph, 0, false, kInvalidBlockId);  // entry block
+  TestBlock(graph, 1, false, kInvalidBlockId);  // pre header of first loop
   const int blocks2[] = {2, 3, 6};
-  TestBlock(graph, 2, true, 2, blocks2, 3);  // loop header
-  TestBlock(graph, 3, false, 2);             // back edge of first loop
-  TestBlock(graph, 4, false, -1);            // return block
-  TestBlock(graph, 5, false, -1);            // exit block
-  TestBlock(graph, 6, false, 2);             // synthesized block to avoid a critical edge
+  TestBlock(graph, 2, true, 2, blocks2, 3);     // loop header
+  TestBlock(graph, 3, false, 2);                // back edge of first loop
+  TestBlock(graph, 4, false, kInvalidBlockId);  // return block
+  TestBlock(graph, 5, false, kInvalidBlockId);  // exit block
+  TestBlock(graph, 6, false, 2);                // synthesized block to avoid a critical edge
 }
 
 }  // namespace art
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 074ed71..af8aa23 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -475,14 +475,13 @@
   const ArenaBitVector& loop_blocks = loop_information->GetBlocks();
 
   // Ensure back edges belong to the loop.
-  size_t num_back_edges = loop_information->GetBackEdges().Size();
-  if (num_back_edges == 0) {
+  if (loop_information->NumberOfBackEdges() == 0) {
     AddError(StringPrintf(
         "Loop defined by header %d has no back edge.",
         id));
   } else {
-    for (size_t i = 0; i < num_back_edges; ++i) {
-      int back_edge_id = loop_information->GetBackEdges().Get(i)->GetBlockId();
+    for (HBasicBlock* back_edge : loop_information->GetBackEdges()) {
+      int back_edge_id = back_edge->GetBlockId();
       if (!loop_blocks.IsBitSet(back_edge_id)) {
         AddError(StringPrintf(
             "Loop defined by header %d has an invalid back edge %d.",
@@ -494,7 +493,7 @@
 
   // Ensure all blocks in the loop are live and dominated by the loop header.
   for (uint32_t i : loop_blocks.Indexes()) {
-    HBasicBlock* loop_block = GetGraph()->GetBlocks().Get(i);
+    HBasicBlock* loop_block = GetGraph()->GetBlock(i);
     if (loop_block == nullptr) {
       AddError(StringPrintf("Loop defined by header %d contains a previously removed block %d.",
                             id,
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 5b8e386..60a5955 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -679,7 +679,7 @@
                                  bool is_after_pass,
                                  bool graph_in_bad_state) const {
   DCHECK(output_ != nullptr);
-  if (!graph_->GetBlocks().IsEmpty()) {
+  if (!graph_->GetBlocks().empty()) {
     HGraphVisualizerPrinter printer(graph_,
                                     *output_,
                                     pass_name,
@@ -692,7 +692,7 @@
 
 void HGraphVisualizer::DumpGraphWithDisassembly() const {
   DCHECK(output_ != nullptr);
-  if (!graph_->GetBlocks().IsEmpty()) {
+  if (!graph_->GetBlocks().empty()) {
     HGraphVisualizerPrinter printer(graph_,
                                     *output_,
                                     "disassembly",
diff --git a/compiler/optimizing/gvn.cc b/compiler/optimizing/gvn.cc
index 5bb4e8e..1ee8648 100644
--- a/compiler/optimizing/gvn.cc
+++ b/compiler/optimizing/gvn.cc
@@ -306,7 +306,7 @@
       : graph_(graph),
         allocator_(allocator),
         side_effects_(side_effects),
-        sets_(allocator, graph->GetBlocks().Size(), nullptr) {}
+        sets_(allocator, graph->GetBlocks().size(), nullptr) {}
 
   void Run();
 
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index efd4fcf..12fd1c3 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -48,16 +48,17 @@
     // doing some logic in the runtime to discover if a method could have been inlined.
     return;
   }
-  const GrowableArray<HBasicBlock*>& blocks = graph_->GetReversePostOrder();
-  HBasicBlock* next_block = blocks.Get(0);
-  for (size_t i = 0; i < blocks.Size(); ++i) {
+  const ArenaVector<HBasicBlock*>& blocks = graph_->GetReversePostOrder();
+  DCHECK(!blocks.empty());
+  HBasicBlock* next_block = blocks[0];
+  for (size_t i = 0; i < blocks.size(); ++i) {
     // Because we are changing the graph when inlining, we need to remember the next block.
     // This avoids doing the inlining work again on the inlined blocks.
-    if (blocks.Get(i) != next_block) {
+    if (blocks[i] != next_block) {
       continue;
     }
     HBasicBlock* block = next_block;
-    next_block = (i == blocks.Size() - 1) ? nullptr : blocks.Get(i + 1);
+    next_block = (i == blocks.size() - 1) ? nullptr : blocks[i + 1];
     for (HInstruction* instruction = block->GetFirstInstruction(); instruction != nullptr;) {
       HInstruction* next = instruction->GetNext();
       HInvoke* call = instruction->AsInvoke();
diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc
index 5b89b4e..c38bbe3 100644
--- a/compiler/optimizing/licm.cc
+++ b/compiler/optimizing/licm.cc
@@ -80,7 +80,7 @@
 void LICM::Run() {
   DCHECK(side_effects_.HasRun());
   // Only used during debug.
-  ArenaBitVector visited(graph_->GetArena(), graph_->GetBlocks().Size(), false);
+  ArenaBitVector visited(graph_->GetArena(), graph_->GetBlocks().size(), false);
 
   // Post order visit to visit inner loops before outer loops.
   for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc
index 4f259b5..a059766 100644
--- a/compiler/optimizing/linearize_test.cc
+++ b/compiler/optimizing/linearize_test.cc
@@ -36,7 +36,8 @@
 
 namespace art {
 
-static void TestCode(const uint16_t* data, const int* expected_order, size_t number_of_blocks) {
+template <size_t number_of_blocks>
+static void TestCode(const uint16_t* data, const uint32_t (&expected_order)[number_of_blocks]) {
   ArenaPool pool;
   ArenaAllocator allocator(&pool);
   HGraph* graph = CreateGraph(&allocator);
@@ -53,9 +54,9 @@
   SsaLivenessAnalysis liveness(graph, &codegen);
   liveness.Analyze();
 
-  ASSERT_EQ(graph->GetLinearOrder().Size(), number_of_blocks);
+  ASSERT_EQ(graph->GetLinearOrder().size(), number_of_blocks);
   for (size_t i = 0; i < number_of_blocks; ++i) {
-    ASSERT_EQ(graph->GetLinearOrder().Get(i)->GetBlockId(), expected_order[i]);
+    ASSERT_EQ(graph->GetLinearOrder()[i]->GetBlockId(), expected_order[i]);
   }
 }
 
@@ -80,8 +81,8 @@
     Instruction::GOTO | 0xFE00,
     Instruction::RETURN_VOID);
 
-  const int blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
-  TestCode(data, blocks, 9);
+  const uint32_t blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
+  TestCode(data, blocks);
 }
 
 TEST(LinearizeTest, CFG2) {
@@ -105,8 +106,8 @@
     Instruction::IF_EQ, 0xFFFD,
     Instruction::GOTO | 0xFE00);
 
-  const int blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
-  TestCode(data, blocks, 9);
+  const uint32_t blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
+  TestCode(data, blocks);
 }
 
 TEST(LinearizeTest, CFG3) {
@@ -132,8 +133,8 @@
     Instruction::IF_EQ, 0xFFFC,
     Instruction::GOTO | 0xFD00);
 
-  const int blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
-  TestCode(data, blocks, 10);
+  const uint32_t blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
+  TestCode(data, blocks);
 }
 
 TEST(LinearizeTest, CFG4) {
@@ -162,8 +163,8 @@
     Instruction::GOTO | 0xFE00,
     Instruction::RETURN_VOID);
 
-  const int blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
-  TestCode(data, blocks, 12);
+  const uint32_t blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
+  TestCode(data, blocks);
 }
 
 TEST(LinearizeTest, CFG5) {
@@ -192,8 +193,8 @@
     Instruction::IF_EQ, 0xFFFE,
     Instruction::GOTO | 0xFE00);
 
-  const int blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
-  TestCode(data, blocks, 12);
+  const uint32_t blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
+  TestCode(data, blocks);
 }
 
 TEST(LinearizeTest, CFG6) {
@@ -218,8 +219,8 @@
     Instruction::RETURN_VOID,
     Instruction::GOTO | 0xFA00);
 
-  const int blocks[] = {0, 1, 2, 3, 4, 6, 9, 8, 5, 7};
-  TestCode(data, blocks, arraysize(blocks));
+  const uint32_t blocks[] = {0, 1, 2, 3, 4, 6, 9, 8, 5, 7};
+  TestCode(data, blocks);
 }
 
 TEST(LinearizeTest, CFG7) {
@@ -246,8 +247,8 @@
     Instruction::RETURN_VOID,
     Instruction::GOTO | 0xFA00);
 
-  const int blocks[] = {0, 1, 2, 3, 4, 9, 8, 6, 5, 7};
-  TestCode(data, blocks, arraysize(blocks));
+  const uint32_t blocks[] = {0, 1, 2, 3, 4, 9, 8, 6, 5, 7};
+  TestCode(data, blocks);
 }
 
 }  // namespace art
diff --git a/compiler/optimizing/live_ranges_test.cc b/compiler/optimizing/live_ranges_test.cc
index 7cb00a1..b9ab290 100644
--- a/compiler/optimizing/live_ranges_test.cc
+++ b/compiler/optimizing/live_ranges_test.cc
@@ -77,7 +77,7 @@
   ASSERT_EQ(2u, range->GetStart());
   // Last use is the return instruction.
   ASSERT_EQ(8u, range->GetEnd());
-  HBasicBlock* block = graph->GetBlocks().Get(1);
+  HBasicBlock* block = graph->GetBlock(1);
   ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
   ASSERT_EQ(8u, block->GetLastInstruction()->GetLifetimePosition());
   ASSERT_TRUE(range->GetNext() == nullptr);
@@ -125,7 +125,7 @@
   ASSERT_EQ(2u, range->GetStart());
   // Last use is the return instruction.
   ASSERT_EQ(22u, range->GetEnd());
-  HBasicBlock* block = graph->GetBlocks().Get(3);
+  HBasicBlock* block = graph->GetBlock(3);
   ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
   ASSERT_EQ(22u, block->GetLastInstruction()->GetLifetimePosition());
   ASSERT_TRUE(range->GetNext() == nullptr);
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h
index 4b25046..cc3b35b 100644
--- a/compiler/optimizing/locations.h
+++ b/compiler/optimizing/locations.h
@@ -35,7 +35,7 @@
  * A Location is an abstraction over the potential location
  * of an instruction. It could be in register or stack.
  */
-class Location : public ValueObject {
+class Location {
  public:
   enum OutputOverlap {
     kOutputOverlap,
@@ -84,7 +84,7 @@
     DCHECK(!IsValid());
   }
 
-  Location(const Location& other) : ValueObject(), value_(other.value_) {}
+  Location(const Location& other) : value_(other.value_) {}
 
   Location& operator=(const Location& other) {
     value_ = other.value_;
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index cc12a10..570ce2e 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -27,12 +27,12 @@
 namespace art {
 
 void HGraph::AddBlock(HBasicBlock* block) {
-  block->SetBlockId(blocks_.Size());
-  blocks_.Add(block);
+  block->SetBlockId(blocks_.size());
+  blocks_.push_back(block);
 }
 
 void HGraph::FindBackEdges(ArenaBitVector* visited) {
-  ArenaBitVector visiting(arena_, blocks_.Size(), false);
+  ArenaBitVector visiting(arena_, blocks_.size(), false);
   VisitBlockForBackEdges(entry_block_, visited, &visiting);
 }
 
@@ -53,9 +53,9 @@
 }
 
 void HGraph::RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visited) const {
-  for (size_t i = 0; i < blocks_.Size(); ++i) {
+  for (size_t i = 0; i < blocks_.size(); ++i) {
     if (!visited.IsBitSet(i)) {
-      HBasicBlock* block = blocks_.Get(i);
+      HBasicBlock* block = GetBlock(i);
       DCHECK(block->GetPhis().IsEmpty()) << "Phis are not inserted at this stage";
       for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
         RemoveAsUser(it.Current());
@@ -65,16 +65,16 @@
 }
 
 void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) {
-  for (size_t i = 0; i < blocks_.Size(); ++i) {
+  for (size_t i = 0; i < blocks_.size(); ++i) {
     if (!visited.IsBitSet(i)) {
-      HBasicBlock* block = blocks_.Get(i);
+      HBasicBlock* block = GetBlock(i);
       // We only need to update the successor, which might be live.
       for (HBasicBlock* successor : block->GetSuccessors()) {
         successor->RemovePredecessor(block);
       }
       // Remove the block from the list of blocks, so that further analyses
       // never see it.
-      blocks_.Put(i, nullptr);
+      blocks_[i] = nullptr;
     }
   }
 }
@@ -103,7 +103,7 @@
   //     collect both normal- and exceptional-flow values at the same time.
   SimplifyCatchBlocks();
 
-  ArenaBitVector visited(arena_, blocks_.Size(), false);
+  ArenaBitVector visited(arena_, blocks_.size(), false);
 
   // (2) Find the back edges in the graph doing a DFS traversal.
   FindBackEdges(&visited);
@@ -130,7 +130,7 @@
   for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) {
     it.Current()->ClearDominanceInformation();
   }
-  reverse_post_order_.Reset();
+  reverse_post_order_.clear();
 }
 
 void HBasicBlock::ClearDominanceInformation() {
@@ -139,17 +139,17 @@
 }
 
 void HGraph::ComputeDominanceInformation() {
-  DCHECK(reverse_post_order_.IsEmpty());
-  GrowableArray<size_t> visits(arena_, blocks_.Size());
-  visits.SetSize(blocks_.Size());
-  reverse_post_order_.Add(entry_block_);
+  DCHECK(reverse_post_order_.empty());
+  reverse_post_order_.reserve(blocks_.size());
+  ArenaVector<size_t> visits(blocks_.size(), 0u, arena_->Adapter());
+  reverse_post_order_.push_back(entry_block_);
   for (HBasicBlock* successor : entry_block_->GetSuccessors()) {
     VisitBlockForDominatorTree(successor, entry_block_, &visits);
   }
 }
 
 HBasicBlock* HGraph::FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const {
-  ArenaBitVector visited(arena_, blocks_.Size(), false);
+  ArenaBitVector visited(arena_, blocks_.size(), false);
   // Walk the dominator tree of the first block and mark the visited blocks.
   while (first != nullptr) {
     visited.SetBit(first->GetBlockId());
@@ -168,20 +168,20 @@
 
 void HGraph::VisitBlockForDominatorTree(HBasicBlock* block,
                                         HBasicBlock* predecessor,
-                                        GrowableArray<size_t>* visits) {
+                                        ArenaVector<size_t>* visits) {
   if (block->GetDominator() == nullptr) {
     block->SetDominator(predecessor);
   } else {
     block->SetDominator(FindCommonDominator(block->GetDominator(), predecessor));
   }
 
-  visits->Increment(block->GetBlockId());
   // Once all the forward edges have been visited, we know the immediate
   // dominator of the block. We can then start visiting its successors.
-  if (visits->Get(block->GetBlockId()) ==
+  DCHECK_LT(block->GetBlockId(), visits->size());
+  if (++(*visits)[block->GetBlockId()] ==
       block->GetPredecessors().size() - block->NumberOfBackEdges()) {
     block->GetDominator()->AddDominatedBlock(block);
-    reverse_post_order_.Add(block);
+    reverse_post_order_.push_back(block);
     for (HBasicBlock* successor : block->GetSuccessors()) {
       VisitBlockForDominatorTree(successor, block, visits);
     }
@@ -189,7 +189,7 @@
 }
 
 void HGraph::TransformToSsa() {
-  DCHECK(!reverse_post_order_.IsEmpty());
+  DCHECK(!reverse_post_order_.empty());
   SsaBuilder ssa_builder(this);
   ssa_builder.BuildSsa();
 }
@@ -289,8 +289,7 @@
 }
 
 void HGraph::SimplifyCatchBlocks() {
-  for (size_t i = 0; i < blocks_.Size(); ++i) {
-    HBasicBlock* catch_block = blocks_.Get(i);
+  for (HBasicBlock* catch_block : blocks_) {
     if (!catch_block->IsCatchBlock()) {
       continue;
     }
@@ -350,8 +349,7 @@
   // Simplify the CFG for future analysis, and code generation:
   // (1): Split critical edges.
   // (2): Simplify loops by having only one back edge, and one preheader.
-  for (size_t i = 0; i < blocks_.Size(); ++i) {
-    HBasicBlock* block = blocks_.Get(i);
+  for (HBasicBlock* block : blocks_) {
     if (block == nullptr) continue;
     if (block->NumberOfNormalSuccessors() > 1) {
       for (size_t j = 0; j < block->GetSuccessors().size(); ++j) {
@@ -483,8 +481,7 @@
 
 bool HLoopInformation::Populate() {
   DCHECK_EQ(blocks_.NumSetBits(), 0u) << "Loop information has already been populated";
-  for (size_t i = 0, e = GetBackEdges().Size(); i < e; ++i) {
-    HBasicBlock* back_edge = GetBackEdges().Get(i);
+  for (HBasicBlock* back_edge : GetBackEdges()) {
     DCHECK(back_edge->GetDominator() != nullptr);
     if (!header_->Dominates(back_edge)) {
       // This loop is not natural. Do not bother going further.
@@ -505,7 +502,7 @@
 void HLoopInformation::Update() {
   HGraph* graph = header_->GetGraph();
   for (uint32_t id : blocks_.Indexes()) {
-    HBasicBlock* block = graph->GetBlocks().Get(id);
+    HBasicBlock* block = graph->GetBlock(id);
     // Reset loop information of non-header blocks inside the loop, except
     // members of inner nested loops because those should already have been
     // updated by their own LoopInformation.
@@ -515,7 +512,7 @@
   }
   blocks_.ClearAllBits();
 
-  if (back_edges_.IsEmpty()) {
+  if (back_edges_.empty()) {
     // The loop has been dismantled, delete its suspend check and remove info
     // from the header.
     DCHECK(HasSuspendCheck());
@@ -525,8 +522,8 @@
     suspend_check_ = nullptr;
   } else {
     if (kIsDebugBuild) {
-      for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
-        DCHECK(header_->Dominates(back_edges_.Get(i)));
+      for (HBasicBlock* back_edge : back_edges_) {
+        DCHECK(header_->Dominates(back_edge));
       }
     }
     // This loop still has reachable back edges. Repopulate the list of blocks.
@@ -549,8 +546,8 @@
 
 size_t HLoopInformation::GetLifetimeEnd() const {
   size_t last_position = 0;
-  for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
-    last_position = std::max(back_edges_.Get(i)->GetLifetimeEnd(), last_position);
+  for (HBasicBlock* back_edge : GetBackEdges()) {
+    last_position = std::max(back_edge->GetLifetimeEnd(), last_position);
   }
   return last_position;
 }
@@ -714,7 +711,8 @@
 }
 
 void HEnvironment::RemoveAsUserOfInput(size_t index) const {
-  const HUserRecord<HEnvironment*> user_record = vregs_.Get(index);
+  DCHECK_LT(index, Size());
+  const HUserRecord<HEnvironment*>& user_record = vregs_[index];
   user_record.GetInstruction()->RemoveEnvironmentUser(user_record.GetUseNode());
 }
 
@@ -883,14 +881,15 @@
 
 void HPhi::AddInput(HInstruction* input) {
   DCHECK(input->GetBlock() != nullptr);
-  inputs_.Add(HUserRecord<HInstruction*>(input));
-  input->AddUseAt(this, inputs_.Size() - 1);
+  inputs_.push_back(HUserRecord<HInstruction*>(input));
+  input->AddUseAt(this, inputs_.size() - 1);
 }
 
 void HPhi::RemoveInputAt(size_t index) {
   RemoveAsUserOfInput(index);
-  inputs_.DeleteAt(index);
+  inputs_.erase(inputs_.begin() + index);
   for (size_t i = index, e = InputCount(); i < e; ++i) {
+    DCHECK_EQ(InputRecordAt(i).GetUseNode()->GetIndex(), i + 1u);
     InputRecordAt(i).GetUseNode()->SetIndex(i);
   }
 }
@@ -905,9 +904,8 @@
 #undef DEFINE_ACCEPT
 
 void HGraphVisitor::VisitInsertionOrder() {
-  const GrowableArray<HBasicBlock*>& blocks = graph_->GetBlocks();
-  for (size_t i = 0 ; i < blocks.Size(); i++) {
-    HBasicBlock* block = blocks.Get(i);
+  const ArenaVector<HBasicBlock*>& blocks = graph_->GetBlocks();
+  for (HBasicBlock* block : blocks) {
     if (block != nullptr) {
       VisitBasicBlock(block);
     }
@@ -1441,15 +1439,14 @@
 
 // Create space in `blocks` for adding `number_of_new_blocks` entries
 // starting at location `at`. Blocks after `at` are moved accordingly.
-static void MakeRoomFor(GrowableArray<HBasicBlock*>* blocks,
+static void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks,
                         size_t number_of_new_blocks,
-                        size_t at) {
-  size_t old_size = blocks->Size();
+                        size_t after) {
+  DCHECK_LT(after, blocks->size());
+  size_t old_size = blocks->size();
   size_t new_size = old_size + number_of_new_blocks;
-  blocks->SetSize(new_size);
-  for (size_t i = old_size - 1, j = new_size - 1; i > at; --i, --j) {
-    blocks->Put(j, blocks->Get(i));
-  }
+  blocks->resize(new_size);
+  std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end());
 }
 
 void HGraph::DeleteDeadBlock(HBasicBlock* block) {
@@ -1470,8 +1467,8 @@
     exit_block_ = nullptr;
   }
 
-  reverse_post_order_.Delete(block);
-  blocks_.Put(block->GetBlockId(), nullptr);
+  RemoveElement(reverse_post_order_, block);
+  blocks_[block->GetBlockId()] = nullptr;
 }
 
 HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
@@ -1500,12 +1497,12 @@
   }
 
   HInstruction* return_value = nullptr;
-  if (GetBlocks().Size() == 3) {
+  if (GetBlocks().size() == 3) {
     // Simple case of an entry block, a body block, and an exit block.
     // Put the body block's instruction into `invoke`'s block.
-    HBasicBlock* body = GetBlocks().Get(1);
-    DCHECK(GetBlocks().Get(0)->IsEntryBlock());
-    DCHECK(GetBlocks().Get(2)->IsExitBlock());
+    HBasicBlock* body = GetBlock(1);
+    DCHECK(GetBlock(0)->IsEntryBlock());
+    DCHECK(GetBlock(2)->IsExitBlock());
     DCHECK(!body->IsExitBlock());
     HInstruction* last = body->GetLastInstruction();
 
@@ -1578,15 +1575,12 @@
 
     // We add the `to` block.
     static constexpr int kNumberOfNewBlocksInCaller = 1;
-    size_t blocks_added = (reverse_post_order_.Size() - kNumberOfSkippedBlocksInCallee)
+    size_t blocks_added = (reverse_post_order_.size() - kNumberOfSkippedBlocksInCallee)
         + kNumberOfNewBlocksInCaller;
 
     // Find the location of `at` in the outer graph's reverse post order. The new
     // blocks will be added after it.
-    size_t index_of_at = 0;
-    while (outer_graph->reverse_post_order_.Get(index_of_at) != at) {
-      index_of_at++;
-    }
+    size_t index_of_at = IndexOfElement(outer_graph->reverse_post_order_, at);
     MakeRoomFor(&outer_graph->reverse_post_order_, blocks_added, index_of_at);
 
     // Do a reverse post order of the blocks in the callee and do (1), (2),
@@ -1599,7 +1593,7 @@
         DCHECK(current->GetGraph() == this);
         current->SetGraph(outer_graph);
         outer_graph->AddBlock(current);
-        outer_graph->reverse_post_order_.Put(++index_of_at, current);
+        outer_graph->reverse_post_order_[++index_of_at] = current;
         if (info != nullptr) {
           current->SetLoopInformation(info);
           for (HLoopInformationOutwardIterator loop_it(*at); !loop_it.Done(); loop_it.Advance()) {
@@ -1612,7 +1606,7 @@
     // Do (1), (2), and (3) to `to`.
     to->SetGraph(outer_graph);
     outer_graph->AddBlock(to);
-    outer_graph->reverse_post_order_.Put(++index_of_at, to);
+    outer_graph->reverse_post_order_[++index_of_at] = to;
     if (info != nullptr) {
       to->SetLoopInformation(info);
       for (HLoopInformationOutwardIterator loop_it(*at); !loop_it.Done(); loop_it.Advance()) {
@@ -1725,15 +1719,12 @@
   new_pre_header->dominated_blocks_.push_back(header);
   header->SetDominator(new_pre_header);
 
-  size_t index_of_header = 0;
-  while (reverse_post_order_.Get(index_of_header) != header) {
-    index_of_header++;
-  }
+  size_t index_of_header = IndexOfElement(reverse_post_order_, header);
   MakeRoomFor(&reverse_post_order_, 4, index_of_header - 1);
-  reverse_post_order_.Put(index_of_header++, if_block);
-  reverse_post_order_.Put(index_of_header++, dummy_block);
-  reverse_post_order_.Put(index_of_header++, deopt_block);
-  reverse_post_order_.Put(index_of_header++, new_pre_header);
+  reverse_post_order_[index_of_header++] = if_block;
+  reverse_post_order_[index_of_header++] = dummy_block;
+  reverse_post_order_[index_of_header++] = deopt_block;
+  reverse_post_order_[index_of_header++] = new_pre_header;
 
   HLoopInformation* info = pre_header->GetLoopInformation();
   if (info != nullptr) {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index d52a4f7..993cc37 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -147,9 +147,9 @@
          bool debuggable = false,
          int start_instruction_id = 0)
       : arena_(arena),
-        blocks_(arena, kDefaultNumberOfBlocks),
-        reverse_post_order_(arena, kDefaultNumberOfBlocks),
-        linear_order_(arena, kDefaultNumberOfBlocks),
+        blocks_(arena->Adapter(kArenaAllocBlockList)),
+        reverse_post_order_(arena->Adapter(kArenaAllocReversePostOrder)),
+        linear_order_(arena->Adapter(kArenaAllocLinearOrder)),
         entry_block_(nullptr),
         exit_block_(nullptr),
         maximum_number_of_out_vregs_(0),
@@ -167,15 +167,21 @@
         should_generate_constructor_barrier_(should_generate_constructor_barrier),
         instruction_set_(instruction_set),
         cached_null_constant_(nullptr),
-        cached_int_constants_(std::less<int32_t>(), arena->Adapter()),
-        cached_float_constants_(std::less<int32_t>(), arena->Adapter()),
-        cached_long_constants_(std::less<int64_t>(), arena->Adapter()),
-        cached_double_constants_(std::less<int64_t>(), arena->Adapter()),
-        cached_current_method_(nullptr) {}
+        cached_int_constants_(std::less<int32_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+        cached_float_constants_(std::less<int32_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+        cached_long_constants_(std::less<int64_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+        cached_double_constants_(std::less<int64_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+        cached_current_method_(nullptr) {
+    blocks_.reserve(kDefaultNumberOfBlocks);
+  }
 
   ArenaAllocator* GetArena() const { return arena_; }
-  const GrowableArray<HBasicBlock*>& GetBlocks() const { return blocks_; }
-  HBasicBlock* GetBlock(size_t id) const { return blocks_.Get(id); }
+  const ArenaVector<HBasicBlock*>& GetBlocks() const { return blocks_; }
+
+  HBasicBlock* GetBlock(size_t id) const {
+    DCHECK_LT(id, blocks_.size());
+    return blocks_[id];
+  }
 
   bool IsInSsaForm() const { return in_ssa_form_; }
 
@@ -295,11 +301,11 @@
     return number_of_vregs_ - number_of_in_vregs_;
   }
 
-  const GrowableArray<HBasicBlock*>& GetReversePostOrder() const {
+  const ArenaVector<HBasicBlock*>& GetReversePostOrder() const {
     return reverse_post_order_;
   }
 
-  const GrowableArray<HBasicBlock*>& GetLinearOrder() const {
+  const ArenaVector<HBasicBlock*>& GetLinearOrder() const {
     return linear_order_;
   }
 
@@ -366,7 +372,7 @@
  private:
   void VisitBlockForDominatorTree(HBasicBlock* block,
                                   HBasicBlock* predecessor,
-                                  GrowableArray<size_t>* visits);
+                                  ArenaVector<size_t>* visits);
   void FindBackEdges(ArenaBitVector* visited);
   void VisitBlockForBackEdges(HBasicBlock* block,
                               ArenaBitVector* visited,
@@ -407,13 +413,13 @@
   ArenaAllocator* const arena_;
 
   // List of blocks in insertion order.
-  GrowableArray<HBasicBlock*> blocks_;
+  ArenaVector<HBasicBlock*> blocks_;
 
   // List of blocks to perform a reverse post order tree traversal.
-  GrowableArray<HBasicBlock*> reverse_post_order_;
+  ArenaVector<HBasicBlock*> reverse_post_order_;
 
   // List of blocks to perform a linear order tree traversal.
-  GrowableArray<HBasicBlock*> linear_order_;
+  ArenaVector<HBasicBlock*> linear_order_;
 
   HBasicBlock* entry_block_;
   HBasicBlock* exit_block_;
@@ -483,9 +489,11 @@
   HLoopInformation(HBasicBlock* header, HGraph* graph)
       : header_(header),
         suspend_check_(nullptr),
-        back_edges_(graph->GetArena(), kDefaultNumberOfBackEdges),
+        back_edges_(graph->GetArena()->Adapter(kArenaAllocLoopInfoBackEdges)),
         // Make bit vector growable, as the number of blocks may change.
-        blocks_(graph->GetArena(), graph->GetBlocks().Size(), true) {}
+        blocks_(graph->GetArena(), graph->GetBlocks().size(), true) {
+    back_edges_.reserve(kDefaultNumberOfBackEdges);
+  }
 
   HBasicBlock* GetHeader() const {
     return header_;
@@ -500,27 +508,24 @@
   bool HasSuspendCheck() const { return suspend_check_ != nullptr; }
 
   void AddBackEdge(HBasicBlock* back_edge) {
-    back_edges_.Add(back_edge);
+    back_edges_.push_back(back_edge);
   }
 
   void RemoveBackEdge(HBasicBlock* back_edge) {
-    back_edges_.Delete(back_edge);
+    RemoveElement(back_edges_, back_edge);
   }
 
   bool IsBackEdge(const HBasicBlock& block) const {
-    for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
-      if (back_edges_.Get(i) == &block) return true;
-    }
-    return false;
+    return ContainsElement(back_edges_, &block);
   }
 
   size_t NumberOfBackEdges() const {
-    return back_edges_.Size();
+    return back_edges_.size();
   }
 
   HBasicBlock* GetPreHeader() const;
 
-  const GrowableArray<HBasicBlock*>& GetBackEdges() const {
+  const ArenaVector<HBasicBlock*>& GetBackEdges() const {
     return back_edges_;
   }
 
@@ -529,13 +534,7 @@
   size_t GetLifetimeEnd() const;
 
   void ReplaceBackEdge(HBasicBlock* existing, HBasicBlock* new_back_edge) {
-    for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
-      if (back_edges_.Get(i) == existing) {
-        back_edges_.Put(i, new_back_edge);
-        return;
-      }
-    }
-    UNREACHABLE();
+    ReplaceElement(back_edges_, existing, new_back_edge);
   }
 
   // Finds blocks that are part of this loop. Returns whether the loop is a natural loop,
@@ -567,7 +566,7 @@
 
   HBasicBlock* header_;
   HSuspendCheck* suspend_check_;
-  GrowableArray<HBasicBlock*> back_edges_;
+  ArenaVector<HBasicBlock*> back_edges_;
   ArenaBitVector blocks_;
 
   DISALLOW_COPY_AND_ASSIGN(HLoopInformation);
@@ -627,6 +626,7 @@
 };
 
 static constexpr size_t kNoLifetime = -1;
+static constexpr uint32_t kInvalidBlockId = static_cast<uint32_t>(-1);
 
 // A block in a method. Contains the list of instructions represented
 // as a double linked list. Each block knows its predecessors and
@@ -641,7 +641,7 @@
         loop_information_(nullptr),
         dominator_(nullptr),
         dominated_blocks_(graph->GetArena()->Adapter(kArenaAllocDominated)),
-        block_id_(-1),
+        block_id_(kInvalidBlockId),
         dex_pc_(dex_pc),
         lifetime_start_(kNoLifetime),
         lifetime_end_(kNoLifetime),
@@ -707,7 +707,7 @@
   HGraph* GetGraph() const { return graph_; }
   void SetGraph(HGraph* graph) { graph_ = graph; }
 
-  int GetBlockId() const { return block_id_; }
+  uint32_t GetBlockId() const { return block_id_; }
   void SetBlockId(int id) { block_id_ = id; }
   uint32_t GetDexPc() const { return dex_pc_; }
 
@@ -964,7 +964,7 @@
   HLoopInformation* loop_information_;
   HBasicBlock* dominator_;
   ArenaVector<HBasicBlock*> dominated_blocks_;
-  int block_id_;
+  uint32_t block_id_;
   // The dex program counter of the first instruction of this block.
   const uint32_t dex_pc_;
   size_t lifetime_start_;
@@ -1242,7 +1242,7 @@
 // instructions they use and pointers to the corresponding HUseListNodes kept
 // by the used instructions.
 template <typename T>
-class HUserRecord : public ValueObject {
+class HUserRecord {
  public:
   HUserRecord() : instruction_(nullptr), use_node_(nullptr) {}
   explicit HUserRecord(HInstruction* instruction) : instruction_(instruction), use_node_(nullptr) {}
@@ -1513,23 +1513,14 @@
                uint32_t dex_pc,
                InvokeType invoke_type,
                HInstruction* holder)
-     : vregs_(arena, number_of_vregs),
-       locations_(arena, number_of_vregs),
+     : vregs_(number_of_vregs, arena->Adapter(kArenaAllocEnvironmentVRegs)),
+       locations_(number_of_vregs, arena->Adapter(kArenaAllocEnvironmentLocations)),
        parent_(nullptr),
        dex_file_(dex_file),
        method_idx_(method_idx),
        dex_pc_(dex_pc),
        invoke_type_(invoke_type),
        holder_(holder) {
-    vregs_.SetSize(number_of_vregs);
-    for (size_t i = 0; i < number_of_vregs; i++) {
-      vregs_.Put(i, HUserRecord<HEnvironment*>());
-    }
-
-    locations_.SetSize(number_of_vregs);
-    for (size_t i = 0; i < number_of_vregs; ++i) {
-      locations_.Put(i, Location());
-    }
   }
 
   HEnvironment(ArenaAllocator* arena, const HEnvironment& to_copy, HInstruction* holder)
@@ -1562,25 +1553,29 @@
   void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header);
 
   void SetRawEnvAt(size_t index, HInstruction* instruction) {
-    vregs_.Put(index, HUserRecord<HEnvironment*>(instruction));
+    DCHECK_LT(index, Size());
+    vregs_[index] = HUserRecord<HEnvironment*>(instruction);
   }
 
   HInstruction* GetInstructionAt(size_t index) const {
-    return vregs_.Get(index).GetInstruction();
+    DCHECK_LT(index, Size());
+    return vregs_[index].GetInstruction();
   }
 
   void RemoveAsUserOfInput(size_t index) const;
 
-  size_t Size() const { return vregs_.Size(); }
+  size_t Size() const { return vregs_.size(); }
 
   HEnvironment* GetParent() const { return parent_; }
 
   void SetLocationAt(size_t index, Location location) {
-    locations_.Put(index, location);
+    DCHECK_LT(index, Size());
+    locations_[index] = location;
   }
 
   Location GetLocationAt(size_t index) const {
-    return locations_.Get(index);
+    DCHECK_LT(index, Size());
+    return locations_[index];
   }
 
   uint32_t GetDexPc() const {
@@ -1609,11 +1604,12 @@
   void RecordEnvUse(HUseListNode<HEnvironment*>* env_use) {
     DCHECK(env_use->GetUser() == this);
     size_t index = env_use->GetIndex();
-    vregs_.Put(index, HUserRecord<HEnvironment*>(vregs_.Get(index), env_use));
+    DCHECK_LT(index, Size());
+    vregs_[index] = HUserRecord<HEnvironment*>(vregs_[index], env_use);
   }
 
-  GrowableArray<HUserRecord<HEnvironment*> > vregs_;
-  GrowableArray<Location> locations_;
+  ArenaVector<HUserRecord<HEnvironment*>> vregs_;
+  ArenaVector<Location> locations_;
   HEnvironment* parent_;
   const DexFile& dex_file_;
   const uint32_t method_idx_;
@@ -2977,7 +2973,7 @@
 
 class HInvoke : public HInstruction {
  public:
-  size_t InputCount() const OVERRIDE { return inputs_.Size(); }
+  size_t InputCount() const OVERRIDE { return inputs_.size(); }
 
   // Runtime needs to walk the stack, so Dex -> Dex calls need to
   // know their environment.
@@ -3031,23 +3027,26 @@
     : HInstruction(
           SideEffects::AllExceptGCDependency(), dex_pc),  // Assume write/read on all fields/arrays.
       number_of_arguments_(number_of_arguments),
-      inputs_(arena, number_of_arguments),
+      inputs_(number_of_arguments + number_of_other_inputs, arena->Adapter(kArenaAllocInvokeInputs)),
       return_type_(return_type),
       dex_method_index_(dex_method_index),
       original_invoke_type_(original_invoke_type),
       intrinsic_(Intrinsics::kNone),
       needs_environment_or_cache_(kNeedsEnvironmentOrCache) {
-    uint32_t number_of_inputs = number_of_arguments + number_of_other_inputs;
-    inputs_.SetSize(number_of_inputs);
   }
 
-  const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_.Get(i); }
+  const HUserRecord<HInstruction*> InputRecordAt(size_t index) const OVERRIDE {
+    DCHECK_LT(index, InputCount());
+    return inputs_[index];
+  }
+
   void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE {
-    inputs_.Put(index, input);
+    DCHECK_LT(index, InputCount());
+    inputs_[index] = input;
   }
 
   uint32_t number_of_arguments_;
-  GrowableArray<HUserRecord<HInstruction*> > inputs_;
+  ArenaVector<HUserRecord<HInstruction*>> inputs_;
   const Primitive::Type return_type_;
   const uint32_t dex_method_index_;
   const InvokeType original_invoke_type_;
@@ -3226,7 +3225,7 @@
     DCHECK(last_input != nullptr);
     DCHECK(last_input->IsLoadClass()) << last_input->DebugName();
     RemoveAsUserOfInput(last_input_index);
-    inputs_.DeleteAt(last_input_index);
+    inputs_.pop_back();
     clinit_check_requirement_ = ClinitCheckRequirement::kImplicit;
     DCHECK(IsStaticWithImplicitClinitCheck());
   }
@@ -3245,7 +3244,7 @@
     DCHECK(last_input != nullptr);
     DCHECK(last_input->IsFakeString()) << last_input->DebugName();
     RemoveAsUserOfInput(last_input_index);
-    inputs_.DeleteAt(last_input_index);
+    inputs_.pop_back();
   }
 
   // Is this a call to a static method whose declaring class has an
@@ -3978,12 +3977,11 @@
        Primitive::Type type,
        uint32_t dex_pc = kNoDexPc)
       : HInstruction(SideEffects::None(), dex_pc),
-        inputs_(arena, number_of_inputs),
+        inputs_(number_of_inputs, arena->Adapter(kArenaAllocPhiInputs)),
         reg_number_(reg_number),
         type_(type),
         is_live_(false),
         can_be_null_(true) {
-    inputs_.SetSize(number_of_inputs);
   }
 
   // Returns a type equivalent to the given `type`, but that a `HPhi` can hold.
@@ -4001,7 +3999,7 @@
 
   bool IsCatchPhi() const { return GetBlock()->IsCatchBlock(); }
 
-  size_t InputCount() const OVERRIDE { return inputs_.Size(); }
+  size_t InputCount() const OVERRIDE { return inputs_.size(); }
 
   void AddInput(HInstruction* input);
   void RemoveInputAt(size_t index);
@@ -4043,14 +4041,18 @@
   DECLARE_INSTRUCTION(Phi);
 
  protected:
-  const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_.Get(i); }
+  const HUserRecord<HInstruction*> InputRecordAt(size_t index) const OVERRIDE {
+    DCHECK_LE(index, InputCount());
+    return inputs_[index];
+  }
 
   void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE {
-    inputs_.Put(index, input);
+    DCHECK_LE(index, InputCount());
+    inputs_[index] = input;
   }
 
  private:
-  GrowableArray<HUserRecord<HInstruction*> > inputs_;
+  ArenaVector<HUserRecord<HInstruction*> > inputs_;
   const uint32_t reg_number_;
   Primitive::Type type_;
   bool is_live_;
@@ -5084,8 +5086,8 @@
  public:
   explicit HInsertionOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {}
 
-  bool Done() const { return index_ == graph_.GetBlocks().Size(); }
-  HBasicBlock* Current() const { return graph_.GetBlocks().Get(index_); }
+  bool Done() const { return index_ == graph_.GetBlocks().size(); }
+  HBasicBlock* Current() const { return graph_.GetBlock(index_); }
   void Advance() { ++index_; }
 
  private:
@@ -5099,11 +5101,11 @@
  public:
   explicit HReversePostOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {
     // Check that reverse post order of the graph has been built.
-    DCHECK(!graph.GetReversePostOrder().IsEmpty());
+    DCHECK(!graph.GetReversePostOrder().empty());
   }
 
-  bool Done() const { return index_ == graph_.GetReversePostOrder().Size(); }
-  HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_); }
+  bool Done() const { return index_ == graph_.GetReversePostOrder().size(); }
+  HBasicBlock* Current() const { return graph_.GetReversePostOrder()[index_]; }
   void Advance() { ++index_; }
 
  private:
@@ -5116,13 +5118,13 @@
 class HPostOrderIterator : public ValueObject {
  public:
   explicit HPostOrderIterator(const HGraph& graph)
-      : graph_(graph), index_(graph_.GetReversePostOrder().Size()) {
+      : graph_(graph), index_(graph_.GetReversePostOrder().size()) {
     // Check that reverse post order of the graph has been built.
-    DCHECK(!graph.GetReversePostOrder().IsEmpty());
+    DCHECK(!graph.GetReversePostOrder().empty());
   }
 
   bool Done() const { return index_ == 0; }
-  HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_ - 1); }
+  HBasicBlock* Current() const { return graph_.GetReversePostOrder()[index_ - 1u]; }
   void Advance() { --index_; }
 
  private:
@@ -5135,11 +5137,11 @@
 class HLinearPostOrderIterator : public ValueObject {
  public:
   explicit HLinearPostOrderIterator(const HGraph& graph)
-      : order_(graph.GetLinearOrder()), index_(graph.GetLinearOrder().Size()) {}
+      : order_(graph.GetLinearOrder()), index_(graph.GetLinearOrder().size()) {}
 
   bool Done() const { return index_ == 0; }
 
-  HBasicBlock* Current() const { return order_.Get(index_ -1); }
+  HBasicBlock* Current() const { return order_[index_ - 1u]; }
 
   void Advance() {
     --index_;
@@ -5147,7 +5149,7 @@
   }
 
  private:
-  const GrowableArray<HBasicBlock*>& order_;
+  const ArenaVector<HBasicBlock*>& order_;
   size_t index_;
 
   DISALLOW_COPY_AND_ASSIGN(HLinearPostOrderIterator);
@@ -5158,12 +5160,12 @@
   explicit HLinearOrderIterator(const HGraph& graph)
       : order_(graph.GetLinearOrder()), index_(0) {}
 
-  bool Done() const { return index_ == order_.Size(); }
-  HBasicBlock* Current() const { return order_.Get(index_); }
+  bool Done() const { return index_ == order_.size(); }
+  HBasicBlock* Current() const { return order_[index_]; }
   void Advance() { ++index_; }
 
  private:
-  const GrowableArray<HBasicBlock*>& order_;
+  const ArenaVector<HBasicBlock*>& order_;
   size_t index_;
 
   DISALLOW_COPY_AND_ASSIGN(HLinearOrderIterator);
@@ -5183,11 +5185,11 @@
     }
   }
 
-  bool Done() const { return index_ == blocks_.Size(); }
-  HBasicBlock* Current() const { return blocks_.Get(index_); }
+  bool Done() const { return index_ == blocks_.size(); }
+  HBasicBlock* Current() const { return blocks_[index_]; }
   void Advance() {
     ++index_;
-    for (size_t e = blocks_.Size(); index_ < e; ++index_) {
+    for (size_t e = blocks_.size(); index_ < e; ++index_) {
       if (blocks_in_loop_.IsBitSet(index_)) {
         break;
       }
@@ -5196,7 +5198,7 @@
 
  private:
   const BitVector& blocks_in_loop_;
-  const GrowableArray<HBasicBlock*>& blocks_;
+  const ArenaVector<HBasicBlock*>& blocks_;
   size_t index_;
 
   DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator);
@@ -5211,17 +5213,18 @@
       : blocks_in_loop_(info.GetBlocks()),
         blocks_(info.GetHeader()->GetGraph()->GetReversePostOrder()),
         index_(0) {
-    if (!blocks_in_loop_.IsBitSet(blocks_.Get(index_)->GetBlockId())) {
+    DCHECK(!blocks_.empty());
+    if (!blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) {
       Advance();
     }
   }
 
-  bool Done() const { return index_ == blocks_.Size(); }
-  HBasicBlock* Current() const { return blocks_.Get(index_); }
+  bool Done() const { return index_ == blocks_.size(); }
+  HBasicBlock* Current() const { return blocks_[index_]; }
   void Advance() {
     ++index_;
-    for (size_t e = blocks_.Size(); index_ < e; ++index_) {
-      if (blocks_in_loop_.IsBitSet(blocks_.Get(index_)->GetBlockId())) {
+    for (size_t e = blocks_.size(); index_ < e; ++index_) {
+      if (blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) {
         break;
       }
     }
@@ -5229,7 +5232,7 @@
 
  private:
   const BitVector& blocks_in_loop_;
-  const GrowableArray<HBasicBlock*>& blocks_;
+  const ArenaVector<HBasicBlock*>& blocks_;
   size_t index_;
 
   DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopReversePostOrderIterator);
diff --git a/compiler/optimizing/optimizing_cfi_test.cc b/compiler/optimizing/optimizing_cfi_test.cc
index f455571..05c6b2c 100644
--- a/compiler/optimizing/optimizing_cfi_test.cc
+++ b/compiler/optimizing/optimizing_cfi_test.cc
@@ -71,7 +71,7 @@
         }
       }
     }
-    GrowableArray<HBasicBlock*> blocks(&allocator, 0);
+    ArenaVector<HBasicBlock*> blocks(allocator.Adapter());
     code_gen->block_order_ = &blocks;
     code_gen->ComputeSpillMask();
     code_gen->SetFrameSize(frame_size);
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index 86c22ed..350f0b1 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -60,10 +60,8 @@
 }
 
 void RemoveSuspendChecks(HGraph* graph) {
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    for (HInstructionIterator it(graph->GetBlocks().Get(i)->GetInstructions());
-         !it.Done();
-         it.Advance()) {
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
       HInstruction* current = it.Current();
       if (current->IsSuspendCheck()) {
         current->GetBlock()->RemoveInstruction(current);
diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc
index 965a8df..b72df86 100644
--- a/compiler/optimizing/register_allocator_test.cc
+++ b/compiler/optimizing/register_allocator_test.cc
@@ -312,7 +312,7 @@
   register_allocator.AllocateRegisters();
   ASSERT_TRUE(register_allocator.Validate(false));
 
-  HBasicBlock* loop_header = graph->GetBlocks().Get(2);
+  HBasicBlock* loop_header = graph->GetBlock(2);
   HPhi* phi = loop_header->GetFirstPhi()->AsPhi();
 
   LiveInterval* phi_interval = phi->GetLiveInterval();
@@ -321,7 +321,7 @@
   ASSERT_TRUE(loop_update->HasRegister());
   ASSERT_NE(phi_interval->GetRegister(), loop_update->GetRegister());
 
-  HBasicBlock* return_block = graph->GetBlocks().Get(3);
+  HBasicBlock* return_block = graph->GetBlock(3);
   HReturn* ret = return_block->GetLastInstruction()->AsReturn();
   ASSERT_EQ(phi_interval->GetRegister(), ret->InputAt(0)->GetLiveInterval()->GetRegister());
 }
@@ -343,8 +343,8 @@
   SsaLivenessAnalysis liveness(graph, &codegen);
   liveness.Analyze();
 
-  HXor* first_xor = graph->GetBlocks().Get(1)->GetFirstInstruction()->AsXor();
-  HXor* last_xor = graph->GetBlocks().Get(1)->GetLastInstruction()->GetPrevious()->AsXor();
+  HXor* first_xor = graph->GetBlock(1)->GetFirstInstruction()->AsXor();
+  HXor* last_xor = graph->GetBlock(1)->GetLastInstruction()->GetPrevious()->AsXor();
   ASSERT_EQ(last_xor->InputAt(0), first_xor);
   LiveInterval* interval = first_xor->GetLiveInterval();
   ASSERT_EQ(interval->GetEnd(), last_xor->GetLifetimePosition());
diff --git a/compiler/optimizing/side_effects_analysis.cc b/compiler/optimizing/side_effects_analysis.cc
index 1c3e255..1956781 100644
--- a/compiler/optimizing/side_effects_analysis.cc
+++ b/compiler/optimizing/side_effects_analysis.cc
@@ -21,8 +21,8 @@
 void SideEffectsAnalysis::Run() {
   // Inlining might have created more blocks, so we need to increase the size
   // if needed.
-  block_effects_.SetSize(graph_->GetBlocks().Size());
-  loop_effects_.SetSize(graph_->GetBlocks().Size());
+  block_effects_.SetSize(graph_->GetBlocks().size());
+  loop_effects_.SetSize(graph_->GetBlocks().size());
 
   // In DEBUG mode, ensure side effects are properly initialized to empty.
   if (kIsDebugBuild) {
diff --git a/compiler/optimizing/side_effects_analysis.h b/compiler/optimizing/side_effects_analysis.h
index 7d300ad..9888140 100644
--- a/compiler/optimizing/side_effects_analysis.h
+++ b/compiler/optimizing/side_effects_analysis.h
@@ -27,8 +27,8 @@
   explicit SideEffectsAnalysis(HGraph* graph)
       : HOptimization(graph, kSideEffectsAnalysisPassName),
         graph_(graph),
-        block_effects_(graph->GetArena(), graph->GetBlocks().Size(), SideEffects::None()),
-        loop_effects_(graph->GetArena(), graph->GetBlocks().Size(), SideEffects::None()) {}
+        block_effects_(graph->GetArena(), graph->GetBlocks().size(), SideEffects::None()),
+        loop_effects_(graph->GetArena(), graph->GetBlocks().size(), SideEffects::None()) {}
 
   SideEffects GetLoopEffects(HBasicBlock* block) const;
   SideEffects GetBlockEffects(HBasicBlock* block) const;
diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h
index 64600db..dc76177 100644
--- a/compiler/optimizing/ssa_builder.h
+++ b/compiler/optimizing/ssa_builder.h
@@ -52,8 +52,8 @@
       : HGraphVisitor(graph),
         current_locals_(nullptr),
         loop_headers_(graph->GetArena(), kDefaultNumberOfLoops),
-        locals_for_(graph->GetArena(), graph->GetBlocks().Size()) {
-    locals_for_.SetSize(graph->GetBlocks().Size());
+        locals_for_(graph->GetArena(), graph->GetBlocks().size()) {
+    locals_for_.SetSize(graph->GetBlocks().size());
   }
 
   void BuildSsa();
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc
index 63635f3..1e9a813 100644
--- a/compiler/optimizing/ssa_liveness_analysis.cc
+++ b/compiler/optimizing/ssa_liveness_analysis.cc
@@ -69,8 +69,8 @@
   //      current reverse post order in the graph, but it would require making
   //      order queries to a GrowableArray, which is not the best data structure
   //      for it.
-  GrowableArray<uint32_t> forward_predecessors(graph_->GetArena(), graph_->GetBlocks().Size());
-  forward_predecessors.SetSize(graph_->GetBlocks().Size());
+  GrowableArray<uint32_t> forward_predecessors(graph_->GetArena(), graph_->GetBlocks().size());
+  forward_predecessors.SetSize(graph_->GetBlocks().size());
   for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
     HBasicBlock* block = it.Current();
     size_t number_of_forward_predecessors = block->GetPredecessors().size();
@@ -84,11 +84,12 @@
   //      iterate over the successors. When all non-back edge predecessors of a
   //      successor block are visited, the successor block is added in the worklist
   //      following an order that satisfies the requirements to build our linear graph.
+  graph_->linear_order_.reserve(graph_->GetReversePostOrder().size());
   GrowableArray<HBasicBlock*> worklist(graph_->GetArena(), 1);
   worklist.Add(graph_->GetEntryBlock());
   do {
     HBasicBlock* current = worklist.Pop();
-    graph_->linear_order_.Add(current);
+    graph_->linear_order_.push_back(current);
     for (HBasicBlock* successor : current->GetSuccessors()) {
       int block_id = successor->GetBlockId();
       size_t number_of_remaining_predecessors = forward_predecessors.Get(block_id);
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index ef396cb..3aedaa5 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -1106,11 +1106,11 @@
   SsaLivenessAnalysis(HGraph* graph, CodeGenerator* codegen)
       : graph_(graph),
         codegen_(codegen),
-        block_infos_(graph->GetArena(), graph->GetBlocks().Size()),
+        block_infos_(graph->GetArena(), graph->GetBlocks().size()),
         instructions_from_ssa_index_(graph->GetArena(), 0),
         instructions_from_lifetime_position_(graph->GetArena(), 0),
         number_of_ssa_values_(0) {
-    block_infos_.SetSize(graph->GetBlocks().Size());
+    block_infos_.SetSize(graph->GetBlocks().size());
   }
 
   void Analyze();
diff --git a/compiler/optimizing/ssa_test.cc b/compiler/optimizing/ssa_test.cc
index 0e8c058..024278f 100644
--- a/compiler/optimizing/ssa_test.cc
+++ b/compiler/optimizing/ssa_test.cc
@@ -64,8 +64,7 @@
 
 static void ReNumberInstructions(HGraph* graph) {
   int id = 0;
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    HBasicBlock* block = graph->GetBlocks().Get(i);
+  for (HBasicBlock* block : graph->GetBlocks()) {
     for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
       it.Current()->SetId(id++);
     }
@@ -92,8 +91,8 @@
   ReNumberInstructions(graph);
 
   // Test that phis had their type set.
-  for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
-    for (HInstructionIterator it(graph->GetBlocks().Get(i)->GetPhis()); !it.Done(); it.Advance()) {
+  for (HBasicBlock* block : graph->GetBlocks()) {
+    for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
       ASSERT_NE(it.Current()->GetType(), Primitive::kPrimVoid);
     }
   }
diff --git a/runtime/base/arena_allocator.cc b/runtime/base/arena_allocator.cc
index a36b0fb..337df38 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -57,14 +57,23 @@
   "STL          ",
   "Graph        ",
   "BasicBlock   ",
+  "BlockList    ",
+  "RevPostOrder ",
+  "LinearOrder  ",
+  "ConstantsMap ",
   "Predecessors ",
   "Successors   ",
   "Dominated    ",
   "Instruction  ",
+  "InvokeInputs ",
+  "PhiInputs    ",
   "LoopInfo     ",
+  "LIBackEdges  ",
   "TryCatchInf  ",
   "UseListNode  ",
   "Environment  ",
+  "EnvVRegs     ",
+  "EnvLocations ",
   "MoveOperands ",
   "CodeBuffer   ",
   "StackMaps    ",
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index 47defb4..8104978 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -67,14 +67,23 @@
   kArenaAllocSTL,
   kArenaAllocGraph,
   kArenaAllocBasicBlock,
+  kArenaAllocBlockList,
+  kArenaAllocReversePostOrder,
+  kArenaAllocLinearOrder,
+  kArenaAllocConstantsMap,
   kArenaAllocPredecessors,
   kArenaAllocSuccessors,
   kArenaAllocDominated,
   kArenaAllocInstruction,
+  kArenaAllocInvokeInputs,
+  kArenaAllocPhiInputs,
   kArenaAllocLoopInfo,
+  kArenaAllocLoopInfoBackEdges,
   kArenaAllocTryCatchInfo,
   kArenaAllocUseListNode,
   kArenaAllocEnvironment,
+  kArenaAllocEnvironmentVRegs,
+  kArenaAllocEnvironmentLocations,
   kArenaAllocMoveOperands,
   kArenaAllocCodeBuffer,
   kArenaAllocStackMaps,