Home | History | Annotate | Download | only in optimizing
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "optimizing_compiler.h"
     18 
     19 #include <fstream>
     20 #include <memory>
     21 #include <sstream>
     22 
     23 #include <stdint.h>
     24 
     25 #include "android-base/strings.h"
     26 
     27 #ifdef ART_ENABLE_CODEGEN_arm
     28 #include "dex_cache_array_fixups_arm.h"
     29 #endif
     30 
     31 #ifdef ART_ENABLE_CODEGEN_arm64
     32 #include "instruction_simplifier_arm64.h"
     33 #endif
     34 
     35 #ifdef ART_ENABLE_CODEGEN_mips
     36 #include "dex_cache_array_fixups_mips.h"
     37 #include "pc_relative_fixups_mips.h"
     38 #endif
     39 
     40 #ifdef ART_ENABLE_CODEGEN_x86
     41 #include "pc_relative_fixups_x86.h"
     42 #endif
     43 
     44 #if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
     45 #include "x86_memory_gen.h"
     46 #endif
     47 
     48 #include "art_method-inl.h"
     49 #include "base/arena_allocator.h"
     50 #include "base/arena_containers.h"
     51 #include "base/dumpable.h"
     52 #include "base/macros.h"
     53 #include "base/mutex.h"
     54 #include "base/timing_logger.h"
     55 #include "bounds_check_elimination.h"
     56 #include "builder.h"
     57 #include "cha_guard_optimization.h"
     58 #include "code_generator.h"
     59 #include "code_sinking.h"
     60 #include "compiled_method.h"
     61 #include "compiler.h"
     62 #include "constant_folding.h"
     63 #include "dead_code_elimination.h"
     64 #include "debug/elf_debug_writer.h"
     65 #include "debug/method_debug_info.h"
     66 #include "dex/verification_results.h"
     67 #include "dex/verified_method.h"
     68 #include "dex_file_types.h"
     69 #include "driver/compiler_driver-inl.h"
     70 #include "driver/compiler_options.h"
     71 #include "driver/dex_compilation_unit.h"
     72 #include "elf_writer_quick.h"
     73 #include "graph_checker.h"
     74 #include "graph_visualizer.h"
     75 #include "gvn.h"
     76 #include "induction_var_analysis.h"
     77 #include "inliner.h"
     78 #include "instruction_simplifier.h"
     79 #include "instruction_simplifier_arm.h"
     80 #include "intrinsics.h"
     81 #include "jit/debugger_interface.h"
     82 #include "jit/jit.h"
     83 #include "jit/jit_code_cache.h"
     84 #include "jni/quick/jni_compiler.h"
     85 #include "licm.h"
     86 #include "load_store_elimination.h"
     87 #include "loop_optimization.h"
     88 #include "nodes.h"
     89 #include "oat_quick_method_header.h"
     90 #include "prepare_for_register_allocation.h"
     91 #include "reference_type_propagation.h"
     92 #include "register_allocator_linear_scan.h"
     93 #include "select_generator.h"
     94 #include "scheduler.h"
     95 #include "sharpening.h"
     96 #include "side_effects_analysis.h"
     97 #include "ssa_builder.h"
     98 #include "ssa_liveness_analysis.h"
     99 #include "ssa_phi_elimination.h"
    100 #include "utils/assembler.h"
    101 #include "verifier/verifier_compiler_binding.h"
    102 
    103 namespace art {
    104 
    105 static constexpr size_t kArenaAllocatorMemoryReportThreshold = 8 * MB;
    106 
    107 static constexpr const char* kPassNameSeparator = "$";
    108 
    109 /**
    110  * Used by the code generator, to allocate the code in a vector.
    111  */
    112 class CodeVectorAllocator FINAL : public CodeAllocator {
    113  public:
    114   explicit CodeVectorAllocator(ArenaAllocator* arena)
    115       : memory_(arena->Adapter(kArenaAllocCodeBuffer)),
    116         size_(0) {}
    117 
    118   virtual uint8_t* Allocate(size_t size) {
    119     size_ = size;
    120     memory_.resize(size);
    121     return &memory_[0];
    122   }
    123 
    124   size_t GetSize() const { return size_; }
    125   const ArenaVector<uint8_t>& GetMemory() const { return memory_; }
    126   uint8_t* GetData() { return memory_.data(); }
    127 
    128  private:
    129   ArenaVector<uint8_t> memory_;
    130   size_t size_;
    131 
    132   DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator);
    133 };
    134 
    135 /**
    136  * Filter to apply to the visualizer. Methods whose name contain that filter will
    137  * be dumped.
    138  */
    139 static constexpr const char kStringFilter[] = "";
    140 
    141 class PassScope;
    142 
    143 class PassObserver : public ValueObject {
    144  public:
    145   PassObserver(HGraph* graph,
    146                CodeGenerator* codegen,
    147                std::ostream* visualizer_output,
    148                CompilerDriver* compiler_driver,
    149                Mutex& dump_mutex)
    150       : graph_(graph),
    151         cached_method_name_(),
    152         timing_logger_enabled_(compiler_driver->GetDumpPasses()),
    153         timing_logger_(timing_logger_enabled_ ? GetMethodName() : "", true, true),
    154         disasm_info_(graph->GetArena()),
    155         visualizer_oss_(),
    156         visualizer_output_(visualizer_output),
    157         visualizer_enabled_(!compiler_driver->GetCompilerOptions().GetDumpCfgFileName().empty()),
    158         visualizer_(&visualizer_oss_, graph, *codegen),
    159         visualizer_dump_mutex_(dump_mutex),
    160         graph_in_bad_state_(false) {
    161     if (timing_logger_enabled_ || visualizer_enabled_) {
    162       if (!IsVerboseMethod(compiler_driver, GetMethodName())) {
    163         timing_logger_enabled_ = visualizer_enabled_ = false;
    164       }
    165       if (visualizer_enabled_) {
    166         visualizer_.PrintHeader(GetMethodName());
    167         codegen->SetDisassemblyInformation(&disasm_info_);
    168       }
    169     }
    170   }
    171 
    172   ~PassObserver() {
    173     if (timing_logger_enabled_) {
    174       LOG(INFO) << "TIMINGS " << GetMethodName();
    175       LOG(INFO) << Dumpable<TimingLogger>(timing_logger_);
    176     }
    177     DCHECK(visualizer_oss_.str().empty());
    178   }
    179 
    180   void DumpDisassembly() REQUIRES(!visualizer_dump_mutex_) {
    181     if (visualizer_enabled_) {
    182       visualizer_.DumpGraphWithDisassembly();
    183       FlushVisualizer();
    184     }
    185   }
    186 
    187   void SetGraphInBadState() { graph_in_bad_state_ = true; }
    188 
    189   const char* GetMethodName() {
    190     // PrettyMethod() is expensive, so we delay calling it until we actually have to.
    191     if (cached_method_name_.empty()) {
    192       cached_method_name_ = graph_->GetDexFile().PrettyMethod(graph_->GetMethodIdx());
    193     }
    194     return cached_method_name_.c_str();
    195   }
    196 
    197  private:
    198   void StartPass(const char* pass_name) REQUIRES(!visualizer_dump_mutex_) {
    199     VLOG(compiler) << "Starting pass: " << pass_name;
    200     // Dump graph first, then start timer.
    201     if (visualizer_enabled_) {
    202       visualizer_.DumpGraph(pass_name, /* is_after_pass */ false, graph_in_bad_state_);
    203       FlushVisualizer();
    204     }
    205     if (timing_logger_enabled_) {
    206       timing_logger_.StartTiming(pass_name);
    207     }
    208   }
    209 
    210   void FlushVisualizer() REQUIRES(!visualizer_dump_mutex_) {
    211     MutexLock mu(Thread::Current(), visualizer_dump_mutex_);
    212     *visualizer_output_ << visualizer_oss_.str();
    213     visualizer_output_->flush();
    214     visualizer_oss_.str("");
    215     visualizer_oss_.clear();
    216   }
    217 
    218   void EndPass(const char* pass_name) REQUIRES(!visualizer_dump_mutex_) {
    219     // Pause timer first, then dump graph.
    220     if (timing_logger_enabled_) {
    221       timing_logger_.EndTiming();
    222     }
    223     if (visualizer_enabled_) {
    224       visualizer_.DumpGraph(pass_name, /* is_after_pass */ true, graph_in_bad_state_);
    225       FlushVisualizer();
    226     }
    227 
    228     // Validate the HGraph if running in debug mode.
    229     if (kIsDebugBuild) {
    230       if (!graph_in_bad_state_) {
    231         GraphChecker checker(graph_);
    232         checker.Run();
    233         if (!checker.IsValid()) {
    234           LOG(FATAL) << "Error after " << pass_name << ": " << Dumpable<GraphChecker>(checker);
    235         }
    236       }
    237     }
    238   }
    239 
    240   static bool IsVerboseMethod(CompilerDriver* compiler_driver, const char* method_name) {
    241     // Test an exact match to --verbose-methods. If verbose-methods is set, this overrides an
    242     // empty kStringFilter matching all methods.
    243     if (compiler_driver->GetCompilerOptions().HasVerboseMethods()) {
    244       return compiler_driver->GetCompilerOptions().IsVerboseMethod(method_name);
    245     }
    246 
    247     // Test the kStringFilter sub-string. constexpr helper variable to silence unreachable-code
    248     // warning when the string is empty.
    249     constexpr bool kStringFilterEmpty = arraysize(kStringFilter) <= 1;
    250     if (kStringFilterEmpty || strstr(method_name, kStringFilter) != nullptr) {
    251       return true;
    252     }
    253 
    254     return false;
    255   }
    256 
    257   HGraph* const graph_;
    258 
    259   std::string cached_method_name_;
    260 
    261   bool timing_logger_enabled_;
    262   TimingLogger timing_logger_;
    263 
    264   DisassemblyInformation disasm_info_;
    265 
    266   std::ostringstream visualizer_oss_;
    267   std::ostream* visualizer_output_;
    268   bool visualizer_enabled_;
    269   HGraphVisualizer visualizer_;
    270   Mutex& visualizer_dump_mutex_;
    271 
    272   // Flag to be set by the compiler if the pass failed and the graph is not
    273   // expected to validate.
    274   bool graph_in_bad_state_;
    275 
    276   friend PassScope;
    277 
    278   DISALLOW_COPY_AND_ASSIGN(PassObserver);
    279 };
    280 
    281 class PassScope : public ValueObject {
    282  public:
    283   PassScope(const char *pass_name, PassObserver* pass_observer)
    284       : pass_name_(pass_name),
    285         pass_observer_(pass_observer) {
    286     pass_observer_->StartPass(pass_name_);
    287   }
    288 
    289   ~PassScope() {
    290     pass_observer_->EndPass(pass_name_);
    291   }
    292 
    293  private:
    294   const char* const pass_name_;
    295   PassObserver* const pass_observer_;
    296 };
    297 
    298 class OptimizingCompiler FINAL : public Compiler {
    299  public:
    300   explicit OptimizingCompiler(CompilerDriver* driver);
    301   ~OptimizingCompiler() OVERRIDE;
    302 
    303   bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file) const OVERRIDE;
    304 
    305   CompiledMethod* Compile(const DexFile::CodeItem* code_item,
    306                           uint32_t access_flags,
    307                           InvokeType invoke_type,
    308                           uint16_t class_def_idx,
    309                           uint32_t method_idx,
    310                           Handle<mirror::ClassLoader> class_loader,
    311                           const DexFile& dex_file,
    312                           Handle<mirror::DexCache> dex_cache) const OVERRIDE;
    313 
    314   CompiledMethod* JniCompile(uint32_t access_flags,
    315                              uint32_t method_idx,
    316                              const DexFile& dex_file,
    317                              JniOptimizationFlags optimization_flags) const OVERRIDE {
    318     return ArtQuickJniCompileMethod(GetCompilerDriver(),
    319                                     access_flags,
    320                                     method_idx,
    321                                     dex_file,
    322                                     optimization_flags);
    323   }
    324 
    325   uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE
    326       REQUIRES_SHARED(Locks::mutator_lock_) {
    327     return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
    328         InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
    329   }
    330 
    331   void Init() OVERRIDE;
    332 
    333   void UnInit() const OVERRIDE;
    334 
    335   void MaybeRecordStat(MethodCompilationStat compilation_stat) const {
    336     if (compilation_stats_.get() != nullptr) {
    337       compilation_stats_->RecordStat(compilation_stat);
    338     }
    339   }
    340 
    341   bool JitCompile(Thread* self, jit::JitCodeCache* code_cache, ArtMethod* method, bool osr)
    342       OVERRIDE
    343       REQUIRES_SHARED(Locks::mutator_lock_);
    344 
    345  private:
    346   void RunOptimizations(HGraph* graph,
    347                         CodeGenerator* codegen,
    348                         CompilerDriver* driver,
    349                         const DexCompilationUnit& dex_compilation_unit,
    350                         PassObserver* pass_observer,
    351                         VariableSizedHandleScope* handles) const;
    352 
    353   void RunOptimizations(HOptimization* optimizations[],
    354                         size_t length,
    355                         PassObserver* pass_observer) const;
    356 
    357  private:
    358   // Create a 'CompiledMethod' for an optimized graph.
    359   CompiledMethod* Emit(ArenaAllocator* arena,
    360                        CodeVectorAllocator* code_allocator,
    361                        CodeGenerator* codegen,
    362                        CompilerDriver* driver,
    363                        const DexFile::CodeItem* item) const;
    364 
    365   // Try compiling a method and return the code generator used for
    366   // compiling it.
    367   // This method:
    368   // 1) Builds the graph. Returns null if it failed to build it.
    369   // 2) Transforms the graph to SSA. Returns null if it failed.
    370   // 3) Runs optimizations on the graph, including register allocator.
    371   // 4) Generates code with the `code_allocator` provided.
    372   CodeGenerator* TryCompile(ArenaAllocator* arena,
    373                             CodeVectorAllocator* code_allocator,
    374                             const DexFile::CodeItem* code_item,
    375                             uint32_t access_flags,
    376                             InvokeType invoke_type,
    377                             uint16_t class_def_idx,
    378                             uint32_t method_idx,
    379                             Handle<mirror::ClassLoader> class_loader,
    380                             const DexFile& dex_file,
    381                             Handle<mirror::DexCache> dex_cache,
    382                             ArtMethod* method,
    383                             bool osr,
    384                             VariableSizedHandleScope* handles) const;
    385 
    386   void MaybeRunInliner(HGraph* graph,
    387                        CodeGenerator* codegen,
    388                        CompilerDriver* driver,
    389                        const DexCompilationUnit& dex_compilation_unit,
    390                        PassObserver* pass_observer,
    391                        VariableSizedHandleScope* handles) const;
    392 
    393   void RunArchOptimizations(InstructionSet instruction_set,
    394                             HGraph* graph,
    395                             CodeGenerator* codegen,
    396                             PassObserver* pass_observer) const;
    397 
    398   std::unique_ptr<OptimizingCompilerStats> compilation_stats_;
    399 
    400   std::unique_ptr<std::ostream> visualizer_output_;
    401 
    402   mutable Mutex dump_mutex_;  // To synchronize visualizer writing.
    403 
    404   DISALLOW_COPY_AND_ASSIGN(OptimizingCompiler);
    405 };
    406 
    407 static const int kMaximumCompilationTimeBeforeWarning = 100; /* ms */
    408 
    409 OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver)
    410     : Compiler(driver, kMaximumCompilationTimeBeforeWarning),
    411       dump_mutex_("Visualizer dump lock") {}
    412 
    413 void OptimizingCompiler::Init() {
    414   // Enable C1visualizer output. Must be done in Init() because the compiler
    415   // driver is not fully initialized when passed to the compiler's constructor.
    416   CompilerDriver* driver = GetCompilerDriver();
    417   const std::string cfg_file_name = driver->GetCompilerOptions().GetDumpCfgFileName();
    418   if (!cfg_file_name.empty()) {
    419     std::ios_base::openmode cfg_file_mode =
    420         driver->GetCompilerOptions().GetDumpCfgAppend() ? std::ofstream::app : std::ofstream::out;
    421     visualizer_output_.reset(new std::ofstream(cfg_file_name, cfg_file_mode));
    422   }
    423   if (driver->GetDumpStats()) {
    424     compilation_stats_.reset(new OptimizingCompilerStats());
    425   }
    426 }
    427 
    428 void OptimizingCompiler::UnInit() const {
    429 }
    430 
    431 OptimizingCompiler::~OptimizingCompiler() {
    432   if (compilation_stats_.get() != nullptr) {
    433     compilation_stats_->Log();
    434   }
    435 }
    436 
    437 bool OptimizingCompiler::CanCompileMethod(uint32_t method_idx ATTRIBUTE_UNUSED,
    438                                           const DexFile& dex_file ATTRIBUTE_UNUSED) const {
    439   return true;
    440 }
    441 
    442 static bool IsInstructionSetSupported(InstructionSet instruction_set) {
    443   return (instruction_set == kArm && !kArm32QuickCodeUseSoftFloat)
    444       || instruction_set == kArm64
    445       || (instruction_set == kThumb2 && !kArm32QuickCodeUseSoftFloat)
    446       || instruction_set == kMips
    447       || instruction_set == kMips64
    448       || instruction_set == kX86
    449       || instruction_set == kX86_64;
    450 }
    451 
    452 // Strip pass name suffix to get optimization name.
    453 static std::string ConvertPassNameToOptimizationName(const std::string& pass_name) {
    454   size_t pos = pass_name.find(kPassNameSeparator);
    455   return pos == std::string::npos ? pass_name : pass_name.substr(0, pos);
    456 }
    457 
    458 static HOptimization* BuildOptimization(
    459     const std::string& pass_name,
    460     ArenaAllocator* arena,
    461     HGraph* graph,
    462     OptimizingCompilerStats* stats,
    463     CodeGenerator* codegen,
    464     CompilerDriver* driver,
    465     const DexCompilationUnit& dex_compilation_unit,
    466     VariableSizedHandleScope* handles,
    467     SideEffectsAnalysis* most_recent_side_effects,
    468     HInductionVarAnalysis* most_recent_induction) {
    469   std::string opt_name = ConvertPassNameToOptimizationName(pass_name);
    470   if (opt_name == BoundsCheckElimination::kBoundsCheckEliminationPassName) {
    471     CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr);
    472     return new (arena) BoundsCheckElimination(graph,
    473                                               *most_recent_side_effects,
    474                                               most_recent_induction);
    475   } else if (opt_name == GVNOptimization::kGlobalValueNumberingPassName) {
    476     CHECK(most_recent_side_effects != nullptr);
    477     return new (arena) GVNOptimization(graph, *most_recent_side_effects, pass_name.c_str());
    478   } else if (opt_name == HConstantFolding::kConstantFoldingPassName) {
    479     return new (arena) HConstantFolding(graph, pass_name.c_str());
    480   } else if (opt_name == HDeadCodeElimination::kDeadCodeEliminationPassName) {
    481     return new (arena) HDeadCodeElimination(graph, stats, pass_name.c_str());
    482   } else if (opt_name == HInliner::kInlinerPassName) {
    483     size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_;
    484     return new (arena) HInliner(graph,                   // outer_graph
    485                                 graph,                   // outermost_graph
    486                                 codegen,
    487                                 dex_compilation_unit,    // outer_compilation_unit
    488                                 dex_compilation_unit,    // outermost_compilation_unit
    489                                 driver,
    490                                 handles,
    491                                 stats,
    492                                 number_of_dex_registers,
    493                                 /* total_number_of_instructions */ 0,
    494                                 /* parent */ nullptr);
    495   } else if (opt_name == HSharpening::kSharpeningPassName) {
    496     return new (arena) HSharpening(graph, codegen, dex_compilation_unit, driver, handles);
    497   } else if (opt_name == HSelectGenerator::kSelectGeneratorPassName) {
    498     return new (arena) HSelectGenerator(graph, stats);
    499   } else if (opt_name == HInductionVarAnalysis::kInductionPassName) {
    500     return new (arena) HInductionVarAnalysis(graph);
    501   } else if (opt_name == InstructionSimplifier::kInstructionSimplifierPassName) {
    502     return new (arena) InstructionSimplifier(graph, codegen, stats, pass_name.c_str());
    503   } else if (opt_name == IntrinsicsRecognizer::kIntrinsicsRecognizerPassName) {
    504     return new (arena) IntrinsicsRecognizer(graph, stats);
    505   } else if (opt_name == LICM::kLoopInvariantCodeMotionPassName) {
    506     CHECK(most_recent_side_effects != nullptr);
    507     return new (arena) LICM(graph, *most_recent_side_effects, stats);
    508   } else if (opt_name == LoadStoreElimination::kLoadStoreEliminationPassName) {
    509     CHECK(most_recent_side_effects != nullptr);
    510     return new (arena) LoadStoreElimination(graph, *most_recent_side_effects);
    511   } else if (opt_name == SideEffectsAnalysis::kSideEffectsAnalysisPassName) {
    512     return new (arena) SideEffectsAnalysis(graph);
    513   } else if (opt_name == HLoopOptimization::kLoopOptimizationPassName) {
    514     return new (arena) HLoopOptimization(graph, driver, most_recent_induction);
    515   } else if (opt_name == CHAGuardOptimization::kCHAGuardOptimizationPassName) {
    516     return new (arena) CHAGuardOptimization(graph);
    517   } else if (opt_name == CodeSinking::kCodeSinkingPassName) {
    518     return new (arena) CodeSinking(graph, stats);
    519 #ifdef ART_ENABLE_CODEGEN_arm
    520   } else if (opt_name == arm::DexCacheArrayFixups::kDexCacheArrayFixupsArmPassName) {
    521     return new (arena) arm::DexCacheArrayFixups(graph, codegen, stats);
    522   } else if (opt_name == arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName) {
    523     return new (arena) arm::InstructionSimplifierArm(graph, stats);
    524 #endif
    525 #ifdef ART_ENABLE_CODEGEN_arm64
    526   } else if (opt_name == arm64::InstructionSimplifierArm64::kInstructionSimplifierArm64PassName) {
    527     return new (arena) arm64::InstructionSimplifierArm64(graph, stats);
    528 #endif
    529 #ifdef ART_ENABLE_CODEGEN_mips
    530   } else if (opt_name == mips::DexCacheArrayFixups::kDexCacheArrayFixupsMipsPassName) {
    531     return new (arena) mips::DexCacheArrayFixups(graph, codegen, stats);
    532   } else if (opt_name == mips::PcRelativeFixups::kPcRelativeFixupsMipsPassName) {
    533     return new (arena) mips::PcRelativeFixups(graph, codegen, stats);
    534 #endif
    535 #ifdef ART_ENABLE_CODEGEN_x86
    536   } else if (opt_name == x86::PcRelativeFixups::kPcRelativeFixupsX86PassName) {
    537     return new (arena) x86::PcRelativeFixups(graph, codegen, stats);
    538   } else if (opt_name == x86::X86MemoryOperandGeneration::kX86MemoryOperandGenerationPassName) {
    539     return new (arena) x86::X86MemoryOperandGeneration(graph, codegen, stats);
    540 #endif
    541   }
    542   return nullptr;
    543 }
    544 
    545 static ArenaVector<HOptimization*> BuildOptimizations(
    546     const std::vector<std::string>& pass_names,
    547     ArenaAllocator* arena,
    548     HGraph* graph,
    549     OptimizingCompilerStats* stats,
    550     CodeGenerator* codegen,
    551     CompilerDriver* driver,
    552     const DexCompilationUnit& dex_compilation_unit,
    553     VariableSizedHandleScope* handles) {
    554   // Few HOptimizations constructors require SideEffectsAnalysis or HInductionVarAnalysis
    555   // instances. This method assumes that each of them expects the nearest instance preceeding it
    556   // in the pass name list.
    557   SideEffectsAnalysis* most_recent_side_effects = nullptr;
    558   HInductionVarAnalysis* most_recent_induction = nullptr;
    559   ArenaVector<HOptimization*> ret(arena->Adapter());
    560   for (const std::string& pass_name : pass_names) {
    561     HOptimization* opt = BuildOptimization(
    562         pass_name,
    563         arena,
    564         graph,
    565         stats,
    566         codegen,
    567         driver,
    568         dex_compilation_unit,
    569         handles,
    570         most_recent_side_effects,
    571         most_recent_induction);
    572     CHECK(opt != nullptr) << "Couldn't build optimization: \"" << pass_name << "\"";
    573     ret.push_back(opt);
    574 
    575     std::string opt_name = ConvertPassNameToOptimizationName(pass_name);
    576     if (opt_name == SideEffectsAnalysis::kSideEffectsAnalysisPassName) {
    577       most_recent_side_effects = down_cast<SideEffectsAnalysis*>(opt);
    578     } else if (opt_name == HInductionVarAnalysis::kInductionPassName) {
    579       most_recent_induction = down_cast<HInductionVarAnalysis*>(opt);
    580     }
    581   }
    582   return ret;
    583 }
    584 
    585 void OptimizingCompiler::RunOptimizations(HOptimization* optimizations[],
    586                                           size_t length,
    587                                           PassObserver* pass_observer) const {
    588   for (size_t i = 0; i < length; ++i) {
    589     PassScope scope(optimizations[i]->GetPassName(), pass_observer);
    590     optimizations[i]->Run();
    591   }
    592 }
    593 
    594 void OptimizingCompiler::MaybeRunInliner(HGraph* graph,
    595                                          CodeGenerator* codegen,
    596                                          CompilerDriver* driver,
    597                                          const DexCompilationUnit& dex_compilation_unit,
    598                                          PassObserver* pass_observer,
    599                                          VariableSizedHandleScope* handles) const {
    600   OptimizingCompilerStats* stats = compilation_stats_.get();
    601   const CompilerOptions& compiler_options = driver->GetCompilerOptions();
    602   bool should_inline = (compiler_options.GetInlineMaxCodeUnits() > 0);
    603   if (!should_inline) {
    604     return;
    605   }
    606   size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_;
    607   HInliner* inliner = new (graph->GetArena()) HInliner(
    608       graph,                   // outer_graph
    609       graph,                   // outermost_graph
    610       codegen,
    611       dex_compilation_unit,    // outer_compilation_unit
    612       dex_compilation_unit,    // outermost_compilation_unit
    613       driver,
    614       handles,
    615       stats,
    616       number_of_dex_registers,
    617       /* total_number_of_instructions */ 0,
    618       /* parent */ nullptr);
    619   HOptimization* optimizations[] = { inliner };
    620 
    621   RunOptimizations(optimizations, arraysize(optimizations), pass_observer);
    622 }
    623 
    624 void OptimizingCompiler::RunArchOptimizations(InstructionSet instruction_set,
    625                                               HGraph* graph,
    626                                               CodeGenerator* codegen,
    627                                               PassObserver* pass_observer) const {
    628   UNUSED(codegen);  // To avoid compilation error when compiling for svelte
    629   OptimizingCompilerStats* stats = compilation_stats_.get();
    630   ArenaAllocator* arena = graph->GetArena();
    631   switch (instruction_set) {
    632 #if defined(ART_ENABLE_CODEGEN_arm)
    633     case kThumb2:
    634     case kArm: {
    635       arm::DexCacheArrayFixups* fixups =
    636           new (arena) arm::DexCacheArrayFixups(graph, codegen, stats);
    637       arm::InstructionSimplifierArm* simplifier =
    638           new (arena) arm::InstructionSimplifierArm(graph, stats);
    639       SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph);
    640       GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN$after_arch");
    641       HOptimization* arm_optimizations[] = {
    642         simplifier,
    643         side_effects,
    644         gvn,
    645         fixups
    646       };
    647       RunOptimizations(arm_optimizations, arraysize(arm_optimizations), pass_observer);
    648       break;
    649     }
    650 #endif
    651 #ifdef ART_ENABLE_CODEGEN_arm64
    652     case kArm64: {
    653       arm64::InstructionSimplifierArm64* simplifier =
    654           new (arena) arm64::InstructionSimplifierArm64(graph, stats);
    655       SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph);
    656       GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN$after_arch");
    657       HInstructionScheduling* scheduling =
    658           new (arena) HInstructionScheduling(graph, instruction_set);
    659       HOptimization* arm64_optimizations[] = {
    660         simplifier,
    661         side_effects,
    662         gvn,
    663         scheduling,
    664       };
    665       RunOptimizations(arm64_optimizations, arraysize(arm64_optimizations), pass_observer);
    666       break;
    667     }
    668 #endif
    669 #ifdef ART_ENABLE_CODEGEN_mips
    670     case kMips: {
    671       mips::PcRelativeFixups* pc_relative_fixups =
    672           new (arena) mips::PcRelativeFixups(graph, codegen, stats);
    673       mips::DexCacheArrayFixups* dex_cache_array_fixups =
    674           new (arena) mips::DexCacheArrayFixups(graph, codegen, stats);
    675       HOptimization* mips_optimizations[] = {
    676           pc_relative_fixups,
    677           dex_cache_array_fixups
    678       };
    679       RunOptimizations(mips_optimizations, arraysize(mips_optimizations), pass_observer);
    680       break;
    681     }
    682 #endif
    683 #ifdef ART_ENABLE_CODEGEN_x86
    684     case kX86: {
    685       x86::PcRelativeFixups* pc_relative_fixups =
    686           new (arena) x86::PcRelativeFixups(graph, codegen, stats);
    687       x86::X86MemoryOperandGeneration* memory_gen =
    688           new (arena) x86::X86MemoryOperandGeneration(graph, codegen, stats);
    689       HOptimization* x86_optimizations[] = {
    690           pc_relative_fixups,
    691           memory_gen
    692       };
    693       RunOptimizations(x86_optimizations, arraysize(x86_optimizations), pass_observer);
    694       break;
    695     }
    696 #endif
    697 #ifdef ART_ENABLE_CODEGEN_x86_64
    698     case kX86_64: {
    699       x86::X86MemoryOperandGeneration* memory_gen =
    700           new (arena) x86::X86MemoryOperandGeneration(graph, codegen, stats);
    701       HOptimization* x86_64_optimizations[] = {
    702           memory_gen
    703       };
    704       RunOptimizations(x86_64_optimizations, arraysize(x86_64_optimizations), pass_observer);
    705       break;
    706     }
    707 #endif
    708     default:
    709       break;
    710   }
    711 }
    712 
    713 NO_INLINE  // Avoid increasing caller's frame size by large stack-allocated objects.
    714 static void AllocateRegisters(HGraph* graph,
    715                               CodeGenerator* codegen,
    716                               PassObserver* pass_observer,
    717                               RegisterAllocator::Strategy strategy) {
    718   {
    719     PassScope scope(PrepareForRegisterAllocation::kPrepareForRegisterAllocationPassName,
    720                     pass_observer);
    721     PrepareForRegisterAllocation(graph).Run();
    722   }
    723   SsaLivenessAnalysis liveness(graph, codegen);
    724   {
    725     PassScope scope(SsaLivenessAnalysis::kLivenessPassName, pass_observer);
    726     liveness.Analyze();
    727   }
    728   {
    729     PassScope scope(RegisterAllocator::kRegisterAllocatorPassName, pass_observer);
    730     RegisterAllocator::Create(graph->GetArena(), codegen, liveness, strategy)->AllocateRegisters();
    731   }
    732 }
    733 
    734 void OptimizingCompiler::RunOptimizations(HGraph* graph,
    735                                           CodeGenerator* codegen,
    736                                           CompilerDriver* driver,
    737                                           const DexCompilationUnit& dex_compilation_unit,
    738                                           PassObserver* pass_observer,
    739                                           VariableSizedHandleScope* handles) const {
    740   OptimizingCompilerStats* stats = compilation_stats_.get();
    741   ArenaAllocator* arena = graph->GetArena();
    742   if (driver->GetCompilerOptions().GetPassesToRun() != nullptr) {
    743     ArenaVector<HOptimization*> optimizations = BuildOptimizations(
    744         *driver->GetCompilerOptions().GetPassesToRun(),
    745         arena,
    746         graph,
    747         stats,
    748         codegen,
    749         driver,
    750         dex_compilation_unit,
    751         handles);
    752     RunOptimizations(&optimizations[0], optimizations.size(), pass_observer);
    753     return;
    754   }
    755 
    756   HDeadCodeElimination* dce1 = new (arena) HDeadCodeElimination(
    757       graph, stats, "dead_code_elimination$initial");
    758   HDeadCodeElimination* dce2 = new (arena) HDeadCodeElimination(
    759       graph, stats, "dead_code_elimination$after_inlining");
    760   HDeadCodeElimination* dce3 = new (arena) HDeadCodeElimination(
    761       graph, stats, "dead_code_elimination$final");
    762   HConstantFolding* fold1 = new (arena) HConstantFolding(graph, "constant_folding");
    763   InstructionSimplifier* simplify1 = new (arena) InstructionSimplifier(graph, codegen, stats);
    764   HSelectGenerator* select_generator = new (arena) HSelectGenerator(graph, stats);
    765   HConstantFolding* fold2 = new (arena) HConstantFolding(
    766       graph, "constant_folding$after_inlining");
    767   HConstantFolding* fold3 = new (arena) HConstantFolding(graph, "constant_folding$after_bce");
    768   SideEffectsAnalysis* side_effects1 = new (arena) SideEffectsAnalysis(
    769       graph, "side_effects$before_gvn");
    770   SideEffectsAnalysis* side_effects2 = new (arena) SideEffectsAnalysis(
    771       graph, "side_effects$before_lse");
    772   GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects1);
    773   LICM* licm = new (arena) LICM(graph, *side_effects1, stats);
    774   HInductionVarAnalysis* induction = new (arena) HInductionVarAnalysis(graph);
    775   BoundsCheckElimination* bce = new (arena) BoundsCheckElimination(graph, *side_effects1, induction);
    776   HLoopOptimization* loop = new (arena) HLoopOptimization(graph, driver, induction);
    777   LoadStoreElimination* lse = new (arena) LoadStoreElimination(graph, *side_effects2);
    778   HSharpening* sharpening = new (arena) HSharpening(
    779       graph, codegen, dex_compilation_unit, driver, handles);
    780   InstructionSimplifier* simplify2 = new (arena) InstructionSimplifier(
    781       graph, codegen, stats, "instruction_simplifier$after_inlining");
    782   InstructionSimplifier* simplify3 = new (arena) InstructionSimplifier(
    783       graph, codegen, stats, "instruction_simplifier$after_bce");
    784   InstructionSimplifier* simplify4 = new (arena) InstructionSimplifier(
    785       graph, codegen, stats, "instruction_simplifier$before_codegen");
    786   IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, stats);
    787   CHAGuardOptimization* cha_guard = new (arena) CHAGuardOptimization(graph);
    788   CodeSinking* code_sinking = new (arena) CodeSinking(graph, stats);
    789 
    790   HOptimization* optimizations1[] = {
    791     intrinsics,
    792     sharpening,
    793     fold1,
    794     simplify1,
    795     dce1,
    796   };
    797   RunOptimizations(optimizations1, arraysize(optimizations1), pass_observer);
    798 
    799   MaybeRunInliner(graph, codegen, driver, dex_compilation_unit, pass_observer, handles);
    800 
    801   HOptimization* optimizations2[] = {
    802     // SelectGenerator depends on the InstructionSimplifier removing
    803     // redundant suspend checks to recognize empty blocks.
    804     select_generator,
    805     fold2,  // TODO: if we don't inline we can also skip fold2.
    806     simplify2,
    807     dce2,
    808     side_effects1,
    809     gvn,
    810     licm,
    811     induction,
    812     bce,
    813     loop,
    814     fold3,  // evaluates code generated by dynamic bce
    815     simplify3,
    816     side_effects2,
    817     lse,
    818     cha_guard,
    819     dce3,
    820     code_sinking,
    821     // The codegen has a few assumptions that only the instruction simplifier
    822     // can satisfy. For example, the code generator does not expect to see a
    823     // HTypeConversion from a type to the same type.
    824     simplify4,
    825   };
    826   RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer);
    827 
    828   RunArchOptimizations(driver->GetInstructionSet(), graph, codegen, pass_observer);
    829 }
    830 
    831 static ArenaVector<LinkerPatch> EmitAndSortLinkerPatches(CodeGenerator* codegen) {
    832   ArenaVector<LinkerPatch> linker_patches(codegen->GetGraph()->GetArena()->Adapter());
    833   codegen->EmitLinkerPatches(&linker_patches);
    834 
    835   // Sort patches by literal offset. Required for .oat_patches encoding.
    836   std::sort(linker_patches.begin(), linker_patches.end(),
    837             [](const LinkerPatch& lhs, const LinkerPatch& rhs) {
    838     return lhs.LiteralOffset() < rhs.LiteralOffset();
    839   });
    840 
    841   return linker_patches;
    842 }
    843 
    844 CompiledMethod* OptimizingCompiler::Emit(ArenaAllocator* arena,
    845                                          CodeVectorAllocator* code_allocator,
    846                                          CodeGenerator* codegen,
    847                                          CompilerDriver* compiler_driver,
    848                                          const DexFile::CodeItem* code_item) const {
    849   ArenaVector<LinkerPatch> linker_patches = EmitAndSortLinkerPatches(codegen);
    850   ArenaVector<uint8_t> stack_map(arena->Adapter(kArenaAllocStackMaps));
    851   ArenaVector<uint8_t> method_info(arena->Adapter(kArenaAllocStackMaps));
    852   size_t stack_map_size = 0;
    853   size_t method_info_size = 0;
    854   codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size);
    855   stack_map.resize(stack_map_size);
    856   method_info.resize(method_info_size);
    857   codegen->BuildStackMaps(MemoryRegion(stack_map.data(), stack_map.size()),
    858                           MemoryRegion(method_info.data(), method_info.size()),
    859                           *code_item);
    860 
    861   CompiledMethod* compiled_method = CompiledMethod::SwapAllocCompiledMethod(
    862       compiler_driver,
    863       codegen->GetInstructionSet(),
    864       ArrayRef<const uint8_t>(code_allocator->GetMemory()),
    865       // Follow Quick's behavior and set the frame size to zero if it is
    866       // considered "empty" (see the definition of
    867       // art::CodeGenerator::HasEmptyFrame).
    868       codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
    869       codegen->GetCoreSpillMask(),
    870       codegen->GetFpuSpillMask(),
    871       ArrayRef<const uint8_t>(method_info),
    872       ArrayRef<const uint8_t>(stack_map),
    873       ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data()),
    874       ArrayRef<const LinkerPatch>(linker_patches));
    875 
    876   return compiled_method;
    877 }
    878 
    879 CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena,
    880                                               CodeVectorAllocator* code_allocator,
    881                                               const DexFile::CodeItem* code_item,
    882                                               uint32_t access_flags,
    883                                               InvokeType invoke_type,
    884                                               uint16_t class_def_idx,
    885                                               uint32_t method_idx,
    886                                               Handle<mirror::ClassLoader> class_loader,
    887                                               const DexFile& dex_file,
    888                                               Handle<mirror::DexCache> dex_cache,
    889                                               ArtMethod* method,
    890                                               bool osr,
    891                                               VariableSizedHandleScope* handles) const {
    892   MaybeRecordStat(MethodCompilationStat::kAttemptCompilation);
    893   CompilerDriver* compiler_driver = GetCompilerDriver();
    894   InstructionSet instruction_set = compiler_driver->GetInstructionSet();
    895 
    896   // Always use the Thumb-2 assembler: some runtime functionality
    897   // (like implicit stack overflow checks) assume Thumb-2.
    898   DCHECK_NE(instruction_set, kArm);
    899 
    900   // Do not attempt to compile on architectures we do not support.
    901   if (!IsInstructionSetSupported(instruction_set)) {
    902     MaybeRecordStat(MethodCompilationStat::kNotCompiledUnsupportedIsa);
    903     return nullptr;
    904   }
    905 
    906   if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
    907     MaybeRecordStat(MethodCompilationStat::kNotCompiledPathological);
    908     return nullptr;
    909   }
    910 
    911   // Implementation of the space filter: do not compile a code item whose size in
    912   // code units is bigger than 128.
    913   static constexpr size_t kSpaceFilterOptimizingThreshold = 128;
    914   const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions();
    915   if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace)
    916       && (code_item->insns_size_in_code_units_ > kSpaceFilterOptimizingThreshold)) {
    917     MaybeRecordStat(MethodCompilationStat::kNotCompiledSpaceFilter);
    918     return nullptr;
    919   }
    920 
    921   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    922   DexCompilationUnit dex_compilation_unit(
    923       class_loader,
    924       class_linker,
    925       dex_file,
    926       code_item,
    927       class_def_idx,
    928       method_idx,
    929       access_flags,
    930       /* verified_method */ nullptr,
    931       dex_cache);
    932 
    933   HGraph* graph = new (arena) HGraph(
    934       arena,
    935       dex_file,
    936       method_idx,
    937       compiler_driver->GetInstructionSet(),
    938       kInvalidInvokeType,
    939       compiler_driver->GetCompilerOptions().GetDebuggable(),
    940       osr);
    941 
    942   const uint8_t* interpreter_metadata = nullptr;
    943   if (method == nullptr) {
    944     ScopedObjectAccess soa(Thread::Current());
    945     method = compiler_driver->ResolveMethod(
    946         soa, dex_cache, class_loader, &dex_compilation_unit, method_idx, invoke_type);
    947   }
    948   // For AOT compilation, we may not get a method, for example if its class is erroneous.
    949   // JIT should always have a method.
    950   DCHECK(Runtime::Current()->IsAotCompiler() || method != nullptr);
    951   if (method != nullptr) {
    952     graph->SetArtMethod(method);
    953     ScopedObjectAccess soa(Thread::Current());
    954     interpreter_metadata = method->GetQuickenedInfo(class_linker->GetImagePointerSize());
    955   }
    956 
    957   std::unique_ptr<CodeGenerator> codegen(
    958       CodeGenerator::Create(graph,
    959                             instruction_set,
    960                             *compiler_driver->GetInstructionSetFeatures(),
    961                             compiler_driver->GetCompilerOptions(),
    962                             compilation_stats_.get()));
    963   if (codegen.get() == nullptr) {
    964     MaybeRecordStat(MethodCompilationStat::kNotCompiledNoCodegen);
    965     return nullptr;
    966   }
    967   codegen->GetAssembler()->cfi().SetEnabled(
    968       compiler_driver->GetCompilerOptions().GenerateAnyDebugInfo());
    969 
    970   PassObserver pass_observer(graph,
    971                              codegen.get(),
    972                              visualizer_output_.get(),
    973                              compiler_driver,
    974                              dump_mutex_);
    975 
    976   {
    977     VLOG(compiler) << "Building " << pass_observer.GetMethodName();
    978     PassScope scope(HGraphBuilder::kBuilderPassName, &pass_observer);
    979     HGraphBuilder builder(graph,
    980                           &dex_compilation_unit,
    981                           &dex_compilation_unit,
    982                           &dex_file,
    983                           *code_item,
    984                           compiler_driver,
    985                           codegen.get(),
    986                           compilation_stats_.get(),
    987                           interpreter_metadata,
    988                           dex_cache,
    989                           handles);
    990     GraphAnalysisResult result = builder.BuildGraph();
    991     if (result != kAnalysisSuccess) {
    992       switch (result) {
    993         case kAnalysisSkipped:
    994           MaybeRecordStat(MethodCompilationStat::kNotCompiledSkipped);
    995           break;
    996         case kAnalysisInvalidBytecode:
    997           MaybeRecordStat(MethodCompilationStat::kNotCompiledInvalidBytecode);
    998           break;
    999         case kAnalysisFailThrowCatchLoop:
   1000           MaybeRecordStat(MethodCompilationStat::kNotCompiledThrowCatchLoop);
   1001           break;
   1002         case kAnalysisFailAmbiguousArrayOp:
   1003           MaybeRecordStat(MethodCompilationStat::kNotCompiledAmbiguousArrayOp);
   1004           break;
   1005         case kAnalysisSuccess:
   1006           UNREACHABLE();
   1007       }
   1008       pass_observer.SetGraphInBadState();
   1009       return nullptr;
   1010     }
   1011   }
   1012 
   1013   RunOptimizations(graph,
   1014                    codegen.get(),
   1015                    compiler_driver,
   1016                    dex_compilation_unit,
   1017                    &pass_observer,
   1018                    handles);
   1019 
   1020   RegisterAllocator::Strategy regalloc_strategy =
   1021     compiler_options.GetRegisterAllocationStrategy();
   1022   AllocateRegisters(graph, codegen.get(), &pass_observer, regalloc_strategy);
   1023 
   1024   codegen->Compile(code_allocator);
   1025   pass_observer.DumpDisassembly();
   1026 
   1027   return codegen.release();
   1028 }
   1029 
   1030 CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item,
   1031                                             uint32_t access_flags,
   1032                                             InvokeType invoke_type,
   1033                                             uint16_t class_def_idx,
   1034                                             uint32_t method_idx,
   1035                                             Handle<mirror::ClassLoader> jclass_loader,
   1036                                             const DexFile& dex_file,
   1037                                             Handle<mirror::DexCache> dex_cache) const {
   1038   CompilerDriver* compiler_driver = GetCompilerDriver();
   1039   CompiledMethod* method = nullptr;
   1040   DCHECK(Runtime::Current()->IsAotCompiler());
   1041   const VerifiedMethod* verified_method = compiler_driver->GetVerifiedMethod(&dex_file, method_idx);
   1042   DCHECK(!verified_method->HasRuntimeThrow());
   1043   if (compiler_driver->IsMethodVerifiedWithoutFailures(method_idx, class_def_idx, dex_file)
   1044       || verifier::CanCompilerHandleVerificationFailure(
   1045             verified_method->GetEncounteredVerificationFailures())) {
   1046     ArenaAllocator arena(Runtime::Current()->GetArenaPool());
   1047     CodeVectorAllocator code_allocator(&arena);
   1048     std::unique_ptr<CodeGenerator> codegen;
   1049     {
   1050       ScopedObjectAccess soa(Thread::Current());
   1051       VariableSizedHandleScope handles(soa.Self());
   1052       // Go to native so that we don't block GC during compilation.
   1053       ScopedThreadSuspension sts(soa.Self(), kNative);
   1054       codegen.reset(
   1055           TryCompile(&arena,
   1056                      &code_allocator,
   1057                      code_item,
   1058                      access_flags,
   1059                      invoke_type,
   1060                      class_def_idx,
   1061                      method_idx,
   1062                      jclass_loader,
   1063                      dex_file,
   1064                      dex_cache,
   1065                      nullptr,
   1066                      /* osr */ false,
   1067                      &handles));
   1068     }
   1069     if (codegen.get() != nullptr) {
   1070       MaybeRecordStat(MethodCompilationStat::kCompiled);
   1071       method = Emit(&arena, &code_allocator, codegen.get(), compiler_driver, code_item);
   1072 
   1073       if (kArenaAllocatorCountAllocations) {
   1074         if (arena.BytesAllocated() > kArenaAllocatorMemoryReportThreshold) {
   1075           MemStats mem_stats(arena.GetMemStats());
   1076           LOG(INFO) << dex_file.PrettyMethod(method_idx) << " " << Dumpable<MemStats>(mem_stats);
   1077         }
   1078       }
   1079     }
   1080   } else {
   1081     if (compiler_driver->GetCompilerOptions().VerifyAtRuntime()) {
   1082       MaybeRecordStat(MethodCompilationStat::kNotCompiledVerifyAtRuntime);
   1083     } else {
   1084       MaybeRecordStat(MethodCompilationStat::kNotCompiledVerificationError);
   1085     }
   1086   }
   1087 
   1088   if (kIsDebugBuild &&
   1089       IsCompilingWithCoreImage() &&
   1090       IsInstructionSetSupported(compiler_driver->GetInstructionSet())) {
   1091     // For testing purposes, we put a special marker on method names
   1092     // that should be compiled with this compiler (when the
   1093     // instruction set is supported). This makes sure we're not
   1094     // regressing.
   1095     std::string method_name = dex_file.PrettyMethod(method_idx);
   1096     bool shouldCompile = method_name.find("$opt$") != std::string::npos;
   1097     DCHECK((method != nullptr) || !shouldCompile) << "Didn't compile " << method_name;
   1098   }
   1099 
   1100   return method;
   1101 }
   1102 
   1103 Compiler* CreateOptimizingCompiler(CompilerDriver* driver) {
   1104   return new OptimizingCompiler(driver);
   1105 }
   1106 
   1107 bool IsCompilingWithCoreImage() {
   1108   const std::string& image = Runtime::Current()->GetImageLocation();
   1109   // TODO: This is under-approximating...
   1110   if (android::base::EndsWith(image, "core.art") ||
   1111       android::base::EndsWith(image, "core-optimizing.art")) {
   1112     return true;
   1113   }
   1114   return false;
   1115 }
   1116 
   1117 bool EncodeArtMethodInInlineInfo(ArtMethod* method ATTRIBUTE_UNUSED) {
   1118   // Note: the runtime is null only for unit testing.
   1119   return Runtime::Current() == nullptr || !Runtime::Current()->IsAotCompiler();
   1120 }
   1121 
   1122 bool CanEncodeInlinedMethodInStackMap(const DexFile& caller_dex_file, ArtMethod* callee) {
   1123   if (!Runtime::Current()->IsAotCompiler()) {
   1124     // JIT can always encode methods in stack maps.
   1125     return true;
   1126   }
   1127   if (IsSameDexFile(caller_dex_file, *callee->GetDexFile())) {
   1128     return true;
   1129   }
   1130   // TODO(ngeoffray): Support more AOT cases for inlining:
   1131   // - methods in multidex
   1132   // - methods in boot image for on-device non-PIC compilation.
   1133   return false;
   1134 }
   1135 
   1136 bool OptimizingCompiler::JitCompile(Thread* self,
   1137                                     jit::JitCodeCache* code_cache,
   1138                                     ArtMethod* method,
   1139                                     bool osr) {
   1140   StackHandleScope<3> hs(self);
   1141   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
   1142       method->GetDeclaringClass()->GetClassLoader()));
   1143   Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
   1144   DCHECK(method->IsCompilable());
   1145 
   1146   const DexFile* dex_file = method->GetDexFile();
   1147   const uint16_t class_def_idx = method->GetClassDefIndex();
   1148   const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
   1149   const uint32_t method_idx = method->GetDexMethodIndex();
   1150   const uint32_t access_flags = method->GetAccessFlags();
   1151   const InvokeType invoke_type = method->GetInvokeType();
   1152 
   1153   ArenaAllocator arena(Runtime::Current()->GetJitArenaPool());
   1154   CodeVectorAllocator code_allocator(&arena);
   1155   VariableSizedHandleScope handles(self);
   1156 
   1157   std::unique_ptr<CodeGenerator> codegen;
   1158   {
   1159     // Go to native so that we don't block GC during compilation.
   1160     ScopedThreadSuspension sts(self, kNative);
   1161     codegen.reset(
   1162         TryCompile(&arena,
   1163                    &code_allocator,
   1164                    code_item,
   1165                    access_flags,
   1166                    invoke_type,
   1167                    class_def_idx,
   1168                    method_idx,
   1169                    class_loader,
   1170                    *dex_file,
   1171                    dex_cache,
   1172                    method,
   1173                    osr,
   1174                    &handles));
   1175     if (codegen.get() == nullptr) {
   1176       return false;
   1177     }
   1178 
   1179     if (kArenaAllocatorCountAllocations) {
   1180       if (arena.BytesAllocated() > kArenaAllocatorMemoryReportThreshold) {
   1181         MemStats mem_stats(arena.GetMemStats());
   1182         LOG(INFO) << dex_file->PrettyMethod(method_idx) << " " << Dumpable<MemStats>(mem_stats);
   1183       }
   1184     }
   1185   }
   1186 
   1187   size_t stack_map_size = 0;
   1188   size_t method_info_size = 0;
   1189   codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size);
   1190   size_t number_of_roots = codegen->GetNumberOfJitRoots();
   1191   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   1192   // We allocate an object array to ensure the JIT roots that we will collect in EmitJitRoots
   1193   // will be visible by the GC between EmitLiterals and CommitCode. Once CommitCode is
   1194   // executed, this array is not needed.
   1195   Handle<mirror::ObjectArray<mirror::Object>> roots(
   1196       hs.NewHandle(mirror::ObjectArray<mirror::Object>::Alloc(
   1197           self, class_linker->GetClassRoot(ClassLinker::kObjectArrayClass), number_of_roots)));
   1198   if (roots == nullptr) {
   1199     // Out of memory, just clear the exception to avoid any Java exception uncaught problems.
   1200     DCHECK(self->IsExceptionPending());
   1201     self->ClearException();
   1202     return false;
   1203   }
   1204   uint8_t* stack_map_data = nullptr;
   1205   uint8_t* method_info_data = nullptr;
   1206   uint8_t* roots_data = nullptr;
   1207   uint32_t data_size = code_cache->ReserveData(self,
   1208                                                stack_map_size,
   1209                                                method_info_size,
   1210                                                number_of_roots,
   1211                                                method,
   1212                                                &stack_map_data,
   1213                                                &method_info_data,
   1214                                                &roots_data);
   1215   if (stack_map_data == nullptr || roots_data == nullptr) {
   1216     return false;
   1217   }
   1218   MaybeRecordStat(MethodCompilationStat::kCompiled);
   1219   codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size),
   1220                           MemoryRegion(method_info_data, method_info_size),
   1221                           *code_item);
   1222   codegen->EmitJitRoots(code_allocator.GetData(), roots, roots_data);
   1223 
   1224   const void* code = code_cache->CommitCode(
   1225       self,
   1226       method,
   1227       stack_map_data,
   1228       method_info_data,
   1229       roots_data,
   1230       codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
   1231       codegen->GetCoreSpillMask(),
   1232       codegen->GetFpuSpillMask(),
   1233       code_allocator.GetMemory().data(),
   1234       code_allocator.GetSize(),
   1235       data_size,
   1236       osr,
   1237       roots,
   1238       codegen->GetGraph()->HasShouldDeoptimizeFlag(),
   1239       codegen->GetGraph()->GetCHASingleImplementationList());
   1240 
   1241   if (code == nullptr) {
   1242     code_cache->ClearData(self, stack_map_data, roots_data);
   1243     return false;
   1244   }
   1245 
   1246   const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
   1247   if (compiler_options.GetGenerateDebugInfo()) {
   1248     const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
   1249     const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
   1250     debug::MethodDebugInfo info = debug::MethodDebugInfo();
   1251     info.trampoline_name = nullptr;
   1252     info.dex_file = dex_file;
   1253     info.class_def_index = class_def_idx;
   1254     info.dex_method_index = method_idx;
   1255     info.access_flags = access_flags;
   1256     info.code_item = code_item;
   1257     info.isa = codegen->GetInstructionSet();
   1258     info.deduped = false;
   1259     info.is_native_debuggable = compiler_options.GetNativeDebuggable();
   1260     info.is_optimized = true;
   1261     info.is_code_address_text_relative = false;
   1262     info.code_address = code_address;
   1263     info.code_size = code_allocator.GetSize();
   1264     info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
   1265     info.code_info = stack_map_size == 0 ? nullptr : stack_map_data;
   1266     info.cfi = ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data());
   1267     std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForMethods(
   1268         GetCompilerDriver()->GetInstructionSet(),
   1269         GetCompilerDriver()->GetInstructionSetFeatures(),
   1270         ArrayRef<const debug::MethodDebugInfo>(&info, 1));
   1271     CreateJITCodeEntryForAddress(code_address, std::move(elf_file));
   1272   }
   1273 
   1274   Runtime::Current()->GetJit()->AddMemoryUsage(method, arena.BytesUsed());
   1275 
   1276   return true;
   1277 }
   1278 
   1279 }  // namespace art
   1280