ART: Same skip-compilation heuristic in both backends

When deciding if a method should be compiled, Optimizing counts the
DEX instructions while Quick approximates this figure as the size of
the CodeItem. This patch modifies Optimizing to use the same logic
so that the two backends reject the same set of methods.

Change-Id: Icb12bf2977f948198df08d59f243532ec8c61783
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 2cdd5af..62bd86a 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -230,8 +230,7 @@
   }
 }
 
-bool HGraphBuilder::SkipCompilation(size_t number_of_dex_instructions,
-                                    size_t number_of_blocks ATTRIBUTE_UNUSED,
+bool HGraphBuilder::SkipCompilation(const DexFile::CodeItem& code_item,
                                     size_t number_of_branches) {
   const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
   CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
@@ -239,19 +238,20 @@
     return false;
   }
 
-  if (compiler_options.IsHugeMethod(number_of_dex_instructions)) {
+  if (compiler_options.IsHugeMethod(code_item.insns_size_in_code_units_)) {
     VLOG(compiler) << "Skip compilation of huge method "
                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
-                   << ": " << number_of_dex_instructions << " dex instructions";
+                   << ": " << code_item.insns_size_in_code_units_ << " code units";
     MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod);
     return true;
   }
 
   // If it's large and contains no branches, it's likely to be machine generated initialization.
-  if (compiler_options.IsLargeMethod(number_of_dex_instructions) && (number_of_branches == 0)) {
+  if (compiler_options.IsLargeMethod(code_item.insns_size_in_code_units_)
+      && (number_of_branches == 0)) {
     VLOG(compiler) << "Skip compilation of large method with no branch "
                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
-                   << ": " << number_of_dex_instructions << " dex instructions";
+                   << ": " << code_item.insns_size_in_code_units_ << " code units";
     MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
     return true;
   }
@@ -278,18 +278,14 @@
 
   // Compute the number of dex instructions, blocks, and branches. We will
   // check these values against limits given to the compiler.
-  size_t number_of_dex_instructions = 0;
-  size_t number_of_blocks = 0;
   size_t number_of_branches = 0;
 
   // To avoid splitting blocks, we compute ahead of time the instructions that
   // start a new block, and create these blocks.
-  ComputeBranchTargets(
-      code_ptr, code_end, &number_of_dex_instructions, &number_of_blocks, &number_of_branches);
+  ComputeBranchTargets(code_ptr, code_end, &number_of_branches);
 
   // Note that the compiler driver is null when unit testing.
-  if ((compiler_driver_ != nullptr)
-      && SkipCompilation(number_of_dex_instructions, number_of_blocks, number_of_branches)) {
+  if ((compiler_driver_ != nullptr) && SkipCompilation(code_item, number_of_branches)) {
     return false;
   }
 
@@ -355,8 +351,6 @@
 
 void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
                                          const uint16_t* code_end,
-                                         size_t* number_of_dex_instructions,
-                                         size_t* number_of_blocks,
                                          size_t* number_of_branches) {
   branch_targets_.SetSize(code_end - code_ptr);
 
@@ -369,7 +363,6 @@
   // the locations these instructions branch to.
   uint32_t dex_pc = 0;
   while (code_ptr < code_end) {
-    (*number_of_dex_instructions)++;
     const Instruction& instruction = *Instruction::At(code_ptr);
     if (instruction.IsBranch()) {
       (*number_of_branches)++;
@@ -378,14 +371,12 @@
       if (FindBlockStartingAt(target) == nullptr) {
         block = new (arena_) HBasicBlock(graph_, target);
         branch_targets_.Put(target, block);
-        (*number_of_blocks)++;
       }
       dex_pc += instruction.SizeInCodeUnits();
       code_ptr += instruction.SizeInCodeUnits();
       if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) {
         block = new (arena_) HBasicBlock(graph_, dex_pc);
         branch_targets_.Put(dex_pc, block);
-        (*number_of_blocks)++;
       }
     } else if (instruction.IsSwitch()) {
       SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH);
@@ -403,14 +394,12 @@
         if (FindBlockStartingAt(target) == nullptr) {
           block = new (arena_) HBasicBlock(graph_, target);
           branch_targets_.Put(target, block);
-          (*number_of_blocks)++;
         }
 
         // The next case gets its own block.
         if (i < num_entries) {
           block = new (arena_) HBasicBlock(graph_, target);
           branch_targets_.Put(table.GetDexPcForIndex(i), block);
-          (*number_of_blocks)++;
         }
       }
 
@@ -420,7 +409,6 @@
       if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) {
         block = new (arena_) HBasicBlock(graph_, dex_pc);
         branch_targets_.Put(dex_pc, block);
-        (*number_of_blocks)++;
       }
     } else {
       code_ptr += instruction.SizeInCodeUnits();
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 6a0738a..dc6d97e 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -90,8 +90,6 @@
   // branches.
   void ComputeBranchTargets(const uint16_t* start,
                             const uint16_t* end,
-                            size_t* number_of_dex_instructions,
-                            size_t* number_of_block,
                             size_t* number_of_branches);
   void MaybeUpdateCurrentBlock(size_t index);
   HBasicBlock* FindBlockStartingAt(int32_t index) const;
@@ -217,9 +215,7 @@
                              HInstruction* value, int32_t case_value_int,
                              int32_t target_offset, uint32_t dex_pc);
 
-  bool SkipCompilation(size_t number_of_dex_instructions,
-                       size_t number_of_blocks,
-                       size_t number_of_branches);
+  bool SkipCompilation(const DexFile::CodeItem& code_item, size_t number_of_branches);
 
   void MaybeRecordStat(MethodCompilationStat compilation_stat);