Make CodeItem fields private

Make code item fields private and use accessors. Added a hand full of
friend classes to reduce the size of the change.

Changed default to be nullable and removed CreateNullable.
CreateNullable was a bad API since it defaulted to the unsafe, may
add a CreateNonNullable if it's important for performance.

Motivation:
Have a different layout for code items in cdex.

Bug: 63756964
Test: test-art-host-gtest
Test: test/testrunner/testrunner.py --host
Test: art/tools/run-jdwp-tests.sh '--mode=host' '--variant=X32' --debug

Change-Id: I42bc7435e20358682075cb6de52713b595f95bf9
diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc
index 58f591b..c505efa 100644
--- a/compiler/optimizing/block_builder.cc
+++ b/compiler/optimizing/block_builder.cc
@@ -18,10 +18,31 @@
 
 #include "base/logging.h"  // FOR VLOG.
 #include "bytecode_utils.h"
+#include "code_item_accessors-inl.h"
 #include "quicken_info.h"
 
 namespace art {
 
+HBasicBlockBuilder::HBasicBlockBuilder(HGraph* graph,
+                                       const DexFile* const dex_file,
+                                       const CodeItemDebugInfoAccessor& accessor,
+                                       ScopedArenaAllocator* local_allocator)
+    : allocator_(graph->GetAllocator()),
+      graph_(graph),
+      dex_file_(dex_file),
+      code_item_accessor_(accessor),
+      local_allocator_(local_allocator),
+      branch_targets_(code_item_accessor_.HasCodeItem()
+                          ? code_item_accessor_.InsnsSizeInCodeUnits()
+                          : /* fake dex_pc=0 for intrinsic graph */ 1u,
+                      nullptr,
+                      local_allocator->Adapter(kArenaAllocGraphBuilder)),
+      throwing_blocks_(kDefaultNumberOfThrowingBlocks,
+                       local_allocator->Adapter(kArenaAllocGraphBuilder)),
+      number_of_branches_(0u),
+      quicken_index_for_dex_pc_(std::less<uint32_t>(),
+                                local_allocator->Adapter(kArenaAllocGraphBuilder)) {}
+
 HBasicBlock* HBasicBlockBuilder::MaybeCreateBlockAt(uint32_t dex_pc) {
   return MaybeCreateBlockAt(dex_pc, dex_pc);
 }
@@ -41,20 +62,19 @@
   // Create the first block for the dex instructions, single successor of the entry block.
   MaybeCreateBlockAt(0u);
 
-  if (code_item_->tries_size_ != 0) {
+  if (code_item_accessor_.TriesSize() != 0) {
     // Create branch targets at the start/end of the TryItem range. These are
     // places where the program might fall through into/out of the a block and
     // where TryBoundary instructions will be inserted later. Other edges which
     // enter/exit the try blocks are a result of branches/switches.
-    for (size_t idx = 0; idx < code_item_->tries_size_; ++idx) {
-      const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item_, idx);
-      uint32_t dex_pc_start = try_item->start_addr_;
-      uint32_t dex_pc_end = dex_pc_start + try_item->insn_count_;
+    for (const DexFile::TryItem& try_item : code_item_accessor_.TryItems()) {
+      uint32_t dex_pc_start = try_item.start_addr_;
+      uint32_t dex_pc_end = dex_pc_start + try_item.insn_count_;
       MaybeCreateBlockAt(dex_pc_start);
-      if (dex_pc_end < code_item_->insns_size_in_code_units_) {
+      if (dex_pc_end < code_item_accessor_.InsnsSizeInCodeUnits()) {
         // TODO: Do not create block if the last instruction cannot fall through.
         MaybeCreateBlockAt(dex_pc_end);
-      } else if (dex_pc_end == code_item_->insns_size_in_code_units_) {
+      } else if (dex_pc_end == code_item_accessor_.InsnsSizeInCodeUnits()) {
         // The TryItem spans until the very end of the CodeItem and therefore
         // cannot have any code afterwards.
       } else {
@@ -65,7 +85,7 @@
     }
 
     // Create branch targets for exception handlers.
-    const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
+    const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
     uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
     for (uint32_t idx = 0; idx < handlers_size; ++idx) {
       CatchHandlerIterator iterator(handlers_ptr);
@@ -78,8 +98,7 @@
 
   // Iterate over all instructions and find branching instructions. Create blocks for
   // the locations these instructions branch to.
-  IterationRange<DexInstructionIterator> instructions = code_item_->Instructions();
-  for (const DexInstructionPcPair& pair : instructions) {
+  for (const DexInstructionPcPair& pair : code_item_accessor_) {
     const uint32_t dex_pc = pair.DexPc();
     const Instruction& instruction = pair.Inst();
 
@@ -109,7 +128,7 @@
 
     if (instruction.CanFlowThrough()) {
       DexInstructionIterator next(std::next(DexInstructionIterator(pair)));
-      if (next == instructions.end()) {
+      if (next == code_item_accessor_.end()) {
         // In the normal case we should never hit this but someone can artificially forge a dex
         // file to fall-through out the method code. In this case we bail out compilation.
         VLOG(compiler) << "Not compiled: Fall-through beyond the CodeItem";
@@ -130,7 +149,7 @@
   bool is_throwing_block = false;
   // Calculate the qucikening index here instead of CreateBranchTargets since it's easier to
   // calculate in dex_pc order.
-  for (const DexInstructionPcPair& pair : code_item_->Instructions()) {
+  for (const DexInstructionPcPair& pair : code_item_accessor_) {
     const uint32_t dex_pc = pair.DexPc();
     const Instruction& instruction = pair.Inst();
 
@@ -213,10 +232,12 @@
 // successors matches the order in which runtime exception delivery searches
 // for a handler.
 static void LinkToCatchBlocks(HTryBoundary* try_boundary,
-                              const DexFile::CodeItem& code_item,
+                              const CodeItemDataAccessor& accessor,
                               const DexFile::TryItem* try_item,
                               const ScopedArenaSafeMap<uint32_t, HBasicBlock*>& catch_blocks) {
-  for (CatchHandlerIterator it(code_item, *try_item); it.HasNext(); it.Next()) {
+  for (CatchHandlerIterator it(accessor.GetCatchHandlerData(try_item->handler_off_));
+      it.HasNext();
+      it.Next()) {
     try_boundary->AddExceptionHandler(catch_blocks.Get(it.GetHandlerAddress()));
   }
 }
@@ -232,7 +253,7 @@
     }
   }
 
-  const Instruction& first = code_item_->InstructionAt(catch_block->GetDexPc());
+  const Instruction& first = code_item_accessor_.InstructionAt(catch_block->GetDexPc());
   if (first.Opcode() == Instruction::MOVE_EXCEPTION) {
     // Verifier guarantees that if a catch block begins with MOVE_EXCEPTION then
     // it has no live normal predecessors.
@@ -250,7 +271,7 @@
 }
 
 void HBasicBlockBuilder::InsertTryBoundaryBlocks() {
-  if (code_item_->tries_size_ == 0) {
+  if (code_item_accessor_.TriesSize() == 0) {
     return;
   }
 
@@ -272,12 +293,10 @@
     // loop for synchronized blocks.
     if (ContainsElement(throwing_blocks_, block)) {
       // Try to find a TryItem covering the block.
-      const int32_t try_item_idx = DexFile::FindTryItem(DexFile::GetTryItems(*code_item_, 0u),
-                                                        code_item_->tries_size_,
-                                                        block->GetDexPc());
-      if (try_item_idx != -1) {
+      const DexFile::TryItem* try_item = code_item_accessor_.FindTryItem(block->GetDexPc());
+      if (try_item != nullptr) {
         // Block throwing and in a TryItem. Store the try block information.
-        try_block_info.Put(block->GetBlockId(), DexFile::GetTryItems(*code_item_, try_item_idx));
+        try_block_info.Put(block->GetBlockId(), try_item);
       }
     }
   }
@@ -288,7 +307,7 @@
 
   // Iterate over catch blocks, create artifical landing pads if necessary to
   // simplify the CFG, and set metadata.
-  const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
+  const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
   uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
   for (uint32_t idx = 0; idx < handlers_size; ++idx) {
     CatchHandlerIterator iterator(handlers_ptr);
@@ -336,7 +355,7 @@
         HTryBoundary* try_entry = new (allocator_) HTryBoundary(
             HTryBoundary::BoundaryKind::kEntry, try_block->GetDexPc());
         try_block->CreateImmediateDominator()->AddInstruction(try_entry);
-        LinkToCatchBlocks(try_entry, *code_item_, try_item, catch_blocks);
+        LinkToCatchBlocks(try_entry, code_item_accessor_, try_item, catch_blocks);
         break;
       }
     }
@@ -364,13 +383,13 @@
       HTryBoundary* try_exit =
           new (allocator_) HTryBoundary(HTryBoundary::BoundaryKind::kExit, successor->GetDexPc());
       graph_->SplitEdge(try_block, successor)->AddInstruction(try_exit);
-      LinkToCatchBlocks(try_exit, *code_item_, try_item, catch_blocks);
+      LinkToCatchBlocks(try_exit, code_item_accessor_, try_item, catch_blocks);
     }
   }
 }
 
 bool HBasicBlockBuilder::Build() {
-  DCHECK(code_item_ != nullptr);
+  DCHECK(code_item_accessor_.HasCodeItem());
   DCHECK(graph_->GetBlocks().empty());
 
   graph_->SetEntryBlock(new (allocator_) HBasicBlock(graph_, kNoDexPc));
@@ -388,7 +407,7 @@
 }
 
 void HBasicBlockBuilder::BuildIntrinsic() {
-  DCHECK(code_item_ == nullptr);
+  DCHECK(!code_item_accessor_.HasCodeItem());
   DCHECK(graph_->GetBlocks().empty());
 
   // Create blocks.