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 <stdint.h>
     22 
     23 #ifdef ART_ENABLE_CODEGEN_arm
     24 #include "dex_cache_array_fixups_arm.h"
     25 #endif
     26 
     27 #ifdef ART_ENABLE_CODEGEN_arm64
     28 #include "instruction_simplifier_arm64.h"
     29 #endif
     30 
     31 #ifdef ART_ENABLE_CODEGEN_x86
     32 #include "pc_relative_fixups_x86.h"
     33 #endif
     34 
     35 #include "art_method-inl.h"
     36 #include "base/arena_allocator.h"
     37 #include "base/arena_containers.h"
     38 #include "base/dumpable.h"
     39 #include "base/macros.h"
     40 #include "base/timing_logger.h"
     41 #include "bounds_check_elimination.h"
     42 #include "builder.h"
     43 #include "code_generator.h"
     44 #include "compiled_method.h"
     45 #include "compiler.h"
     46 #include "constant_folding.h"
     47 #include "dead_code_elimination.h"
     48 #include "debug/elf_debug_writer.h"
     49 #include "debug/method_debug_info.h"
     50 #include "dex/quick/dex_file_to_method_inliner_map.h"
     51 #include "dex/verification_results.h"
     52 #include "dex/verified_method.h"
     53 #include "driver/compiler_driver-inl.h"
     54 #include "driver/compiler_options.h"
     55 #include "driver/dex_compilation_unit.h"
     56 #include "elf_writer_quick.h"
     57 #include "graph_checker.h"
     58 #include "graph_visualizer.h"
     59 #include "gvn.h"
     60 #include "induction_var_analysis.h"
     61 #include "inliner.h"
     62 #include "instruction_simplifier.h"
     63 #include "instruction_simplifier_arm.h"
     64 #include "intrinsics.h"
     65 #include "jit/debugger_interface.h"
     66 #include "jit/jit.h"
     67 #include "jit/jit_code_cache.h"
     68 #include "jni/quick/jni_compiler.h"
     69 #include "licm.h"
     70 #include "load_store_elimination.h"
     71 #include "nodes.h"
     72 #include "oat_quick_method_header.h"
     73 #include "prepare_for_register_allocation.h"
     74 #include "reference_type_propagation.h"
     75 #include "register_allocator.h"
     76 #include "select_generator.h"
     77 #include "sharpening.h"
     78 #include "side_effects_analysis.h"
     79 #include "ssa_builder.h"
     80 #include "ssa_liveness_analysis.h"
     81 #include "ssa_phi_elimination.h"
     82 #include "utils/assembler.h"
     83 #include "verifier/method_verifier.h"
     84 
     85 namespace art {
     86 
     87 static constexpr size_t kArenaAllocatorMemoryReportThreshold = 8 * MB;
     88 
     89 /**
     90  * Used by the code generator, to allocate the code in a vector.
     91  */
     92 class CodeVectorAllocator FINAL : public CodeAllocator {
     93  public:
     94   explicit CodeVectorAllocator(ArenaAllocator* arena)
     95       : memory_(arena->Adapter(kArenaAllocCodeBuffer)),
     96         size_(0) {}
     97 
     98   virtual uint8_t* Allocate(size_t size) {
     99     size_ = size;
    100     memory_.resize(size);
    101     return &memory_[0];
    102   }
    103 
    104   size_t GetSize() const { return size_; }
    105   const ArenaVector<uint8_t>& GetMemory() const { return memory_; }
    106 
    107  private:
    108   ArenaVector<uint8_t> memory_;
    109   size_t size_;
    110 
    111   DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator);
    112 };
    113 
    114 /**
    115  * Filter to apply to the visualizer. Methods whose name contain that filter will
    116  * be dumped.
    117  */
    118 static constexpr const char kStringFilter[] = "";
    119 
    120 class PassScope;
    121 
    122 class PassObserver : public ValueObject {
    123  public:
    124   PassObserver(HGraph* graph,
    125                CodeGenerator* codegen,
    126                std::ostream* visualizer_output,
    127                CompilerDriver* compiler_driver)
    128       : graph_(graph),
    129         cached_method_name_(),
    130         timing_logger_enabled_(compiler_driver->GetDumpPasses()),
    131         timing_logger_(timing_logger_enabled_ ? GetMethodName() : "", true, true),
    132         disasm_info_(graph->GetArena()),
    133         visualizer_enabled_(!compiler_driver->GetCompilerOptions().GetDumpCfgFileName().empty()),
    134         visualizer_(visualizer_output, graph, *codegen),
    135         graph_in_bad_state_(false) {
    136     if (timing_logger_enabled_ || visualizer_enabled_) {
    137       if (!IsVerboseMethod(compiler_driver, GetMethodName())) {
    138         timing_logger_enabled_ = visualizer_enabled_ = false;
    139       }
    140       if (visualizer_enabled_) {
    141         visualizer_.PrintHeader(GetMethodName());
    142         codegen->SetDisassemblyInformation(&disasm_info_);
    143       }
    144     }
    145   }
    146 
    147   ~PassObserver() {
    148     if (timing_logger_enabled_) {
    149       LOG(INFO) << "TIMINGS " << GetMethodName();
    150       LOG(INFO) << Dumpable<TimingLogger>(timing_logger_);
    151     }
    152   }
    153 
    154   void DumpDisassembly() const {
    155     if (visualizer_enabled_) {
    156       visualizer_.DumpGraphWithDisassembly();
    157     }
    158   }
    159 
    160   void SetGraphInBadState() { graph_in_bad_state_ = true; }
    161 
    162   const char* GetMethodName() {
    163     // PrettyMethod() is expensive, so we delay calling it until we actually have to.
    164     if (cached_method_name_.empty()) {
    165       cached_method_name_ = PrettyMethod(graph_->GetMethodIdx(), graph_->GetDexFile());
    166     }
    167     return cached_method_name_.c_str();
    168   }
    169 
    170  private:
    171   void StartPass(const char* pass_name) {
    172     // Dump graph first, then start timer.
    173     if (visualizer_enabled_) {
    174       visualizer_.DumpGraph(pass_name, /* is_after_pass */ false, graph_in_bad_state_);
    175     }
    176     if (timing_logger_enabled_) {
    177       timing_logger_.StartTiming(pass_name);
    178     }
    179   }
    180 
    181   void EndPass(const char* pass_name) {
    182     // Pause timer first, then dump graph.
    183     if (timing_logger_enabled_) {
    184       timing_logger_.EndTiming();
    185     }
    186     if (visualizer_enabled_) {
    187       visualizer_.DumpGraph(pass_name, /* is_after_pass */ true, graph_in_bad_state_);
    188     }
    189 
    190     // Validate the HGraph if running in debug mode.
    191     if (kIsDebugBuild) {
    192       if (!graph_in_bad_state_) {
    193         GraphChecker checker(graph_);
    194         checker.Run();
    195         if (!checker.IsValid()) {
    196           LOG(FATAL) << "Error after " << pass_name << ": " << Dumpable<GraphChecker>(checker);
    197         }
    198       }
    199     }
    200   }
    201 
    202   static bool IsVerboseMethod(CompilerDriver* compiler_driver, const char* method_name) {
    203     // Test an exact match to --verbose-methods. If verbose-methods is set, this overrides an
    204     // empty kStringFilter matching all methods.
    205     if (compiler_driver->GetCompilerOptions().HasVerboseMethods()) {
    206       return compiler_driver->GetCompilerOptions().IsVerboseMethod(method_name);
    207     }
    208 
    209     // Test the kStringFilter sub-string. constexpr helper variable to silence unreachable-code
    210     // warning when the string is empty.
    211     constexpr bool kStringFilterEmpty = arraysize(kStringFilter) <= 1;
    212     if (kStringFilterEmpty || strstr(method_name, kStringFilter) != nullptr) {
    213       return true;
    214     }
    215 
    216     return false;
    217   }
    218 
    219   HGraph* const graph_;
    220 
    221   std::string cached_method_name_;
    222 
    223   bool timing_logger_enabled_;
    224   TimingLogger timing_logger_;
    225 
    226   DisassemblyInformation disasm_info_;
    227 
    228   bool visualizer_enabled_;
    229   HGraphVisualizer visualizer_;
    230 
    231   // Flag to be set by the compiler if the pass failed and the graph is not
    232   // expected to validate.
    233   bool graph_in_bad_state_;
    234 
    235   friend PassScope;
    236 
    237   DISALLOW_COPY_AND_ASSIGN(PassObserver);
    238 };
    239 
    240 class PassScope : public ValueObject {
    241  public:
    242   PassScope(const char *pass_name, PassObserver* pass_observer)
    243       : pass_name_(pass_name),
    244         pass_observer_(pass_observer) {
    245     pass_observer_->StartPass(pass_name_);
    246   }
    247 
    248   ~PassScope() {
    249     pass_observer_->EndPass(pass_name_);
    250   }
    251 
    252  private:
    253   const char* const pass_name_;
    254   PassObserver* const pass_observer_;
    255 };
    256 
    257 class OptimizingCompiler FINAL : public Compiler {
    258  public:
    259   explicit OptimizingCompiler(CompilerDriver* driver);
    260   ~OptimizingCompiler();
    261 
    262   bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file) const OVERRIDE;
    263 
    264   CompiledMethod* Compile(const DexFile::CodeItem* code_item,
    265                           uint32_t access_flags,
    266                           InvokeType invoke_type,
    267                           uint16_t class_def_idx,
    268                           uint32_t method_idx,
    269                           jobject class_loader,
    270                           const DexFile& dex_file,
    271                           Handle<mirror::DexCache> dex_cache) const OVERRIDE;
    272 
    273   CompiledMethod* JniCompile(uint32_t access_flags,
    274                              uint32_t method_idx,
    275                              const DexFile& dex_file) const OVERRIDE {
    276     return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
    277   }
    278 
    279   uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE
    280       SHARED_REQUIRES(Locks::mutator_lock_) {
    281     return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
    282         InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
    283   }
    284 
    285   void Init() OVERRIDE;
    286 
    287   void UnInit() const OVERRIDE;
    288 
    289   void MaybeRecordStat(MethodCompilationStat compilation_stat) const {
    290     if (compilation_stats_.get() != nullptr) {
    291       compilation_stats_->RecordStat(compilation_stat);
    292     }
    293   }
    294 
    295   bool JitCompile(Thread* self, jit::JitCodeCache* code_cache, ArtMethod* method, bool osr)
    296       OVERRIDE
    297       SHARED_REQUIRES(Locks::mutator_lock_);
    298 
    299  private:
    300   // Create a 'CompiledMethod' for an optimized graph.
    301   CompiledMethod* Emit(ArenaAllocator* arena,
    302                        CodeVectorAllocator* code_allocator,
    303                        CodeGenerator* codegen,
    304                        CompilerDriver* driver,
    305                        const DexFile::CodeItem* item) const;
    306 
    307   // Try compiling a method and return the code generator used for
    308   // compiling it.
    309   // This method:
    310   // 1) Builds the graph. Returns null if it failed to build it.
    311   // 2) Transforms the graph to SSA. Returns null if it failed.
    312   // 3) Runs optimizations on the graph, including register allocator.
    313   // 4) Generates code with the `code_allocator` provided.
    314   CodeGenerator* TryCompile(ArenaAllocator* arena,
    315                             CodeVectorAllocator* code_allocator,
    316                             const DexFile::CodeItem* code_item,
    317                             uint32_t access_flags,
    318                             InvokeType invoke_type,
    319                             uint16_t class_def_idx,
    320                             uint32_t method_idx,
    321                             jobject class_loader,
    322                             const DexFile& dex_file,
    323                             Handle<mirror::DexCache> dex_cache,
    324                             ArtMethod* method,
    325                             bool osr) const;
    326 
    327   std::unique_ptr<OptimizingCompilerStats> compilation_stats_;
    328 
    329   std::unique_ptr<std::ostream> visualizer_output_;
    330 
    331   DISALLOW_COPY_AND_ASSIGN(OptimizingCompiler);
    332 };
    333 
    334 static const int kMaximumCompilationTimeBeforeWarning = 100; /* ms */
    335 
    336 OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver)
    337     : Compiler(driver, kMaximumCompilationTimeBeforeWarning) {}
    338 
    339 void OptimizingCompiler::Init() {
    340   // Enable C1visualizer output. Must be done in Init() because the compiler
    341   // driver is not fully initialized when passed to the compiler's constructor.
    342   CompilerDriver* driver = GetCompilerDriver();
    343   const std::string cfg_file_name = driver->GetCompilerOptions().GetDumpCfgFileName();
    344   if (!cfg_file_name.empty()) {
    345     CHECK_EQ(driver->GetThreadCount(), 1U)
    346       << "Graph visualizer requires the compiler to run single-threaded. "
    347       << "Invoke the compiler with '-j1'.";
    348     std::ios_base::openmode cfg_file_mode =
    349         driver->GetCompilerOptions().GetDumpCfgAppend() ? std::ofstream::app : std::ofstream::out;
    350     visualizer_output_.reset(new std::ofstream(cfg_file_name, cfg_file_mode));
    351   }
    352   if (driver->GetDumpStats()) {
    353     compilation_stats_.reset(new OptimizingCompilerStats());
    354   }
    355 }
    356 
    357 void OptimizingCompiler::UnInit() const {
    358 }
    359 
    360 OptimizingCompiler::~OptimizingCompiler() {
    361   if (compilation_stats_.get() != nullptr) {
    362     compilation_stats_->Log();
    363   }
    364 }
    365 
    366 bool OptimizingCompiler::CanCompileMethod(uint32_t method_idx ATTRIBUTE_UNUSED,
    367                                           const DexFile& dex_file ATTRIBUTE_UNUSED) const {
    368   return true;
    369 }
    370 
    371 static bool IsInstructionSetSupported(InstructionSet instruction_set) {
    372   return (instruction_set == kArm && !kArm32QuickCodeUseSoftFloat)
    373       || instruction_set == kArm64
    374       || (instruction_set == kThumb2 && !kArm32QuickCodeUseSoftFloat)
    375       || instruction_set == kMips
    376       || instruction_set == kMips64
    377       || instruction_set == kX86
    378       || instruction_set == kX86_64;
    379 }
    380 
    381 // Read barrier are supported on ARM, ARM64, x86 and x86-64 at the moment.
    382 // TODO: Add support for other architectures and remove this function
    383 static bool InstructionSetSupportsReadBarrier(InstructionSet instruction_set) {
    384   return instruction_set == kArm64
    385       || instruction_set == kThumb2
    386       || instruction_set == kX86
    387       || instruction_set == kX86_64;
    388 }
    389 
    390 static void RunOptimizations(HOptimization* optimizations[],
    391                              size_t length,
    392                              PassObserver* pass_observer) {
    393   for (size_t i = 0; i < length; ++i) {
    394     PassScope scope(optimizations[i]->GetPassName(), pass_observer);
    395     optimizations[i]->Run();
    396   }
    397 }
    398 
    399 static void MaybeRunInliner(HGraph* graph,
    400                             CodeGenerator* codegen,
    401                             CompilerDriver* driver,
    402                             OptimizingCompilerStats* stats,
    403                             const DexCompilationUnit& dex_compilation_unit,
    404                             PassObserver* pass_observer,
    405                             StackHandleScopeCollection* handles) {
    406   const CompilerOptions& compiler_options = driver->GetCompilerOptions();
    407   bool should_inline = (compiler_options.GetInlineDepthLimit() > 0)
    408       && (compiler_options.GetInlineMaxCodeUnits() > 0);
    409   if (!should_inline) {
    410     return;
    411   }
    412   size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_;
    413   HInliner* inliner = new (graph->GetArena()) HInliner(
    414       graph,
    415       graph,
    416       codegen,
    417       dex_compilation_unit,
    418       dex_compilation_unit,
    419       driver,
    420       handles,
    421       stats,
    422       number_of_dex_registers,
    423       /* depth */ 0);
    424   HOptimization* optimizations[] = { inliner };
    425 
    426   RunOptimizations(optimizations, arraysize(optimizations), pass_observer);
    427 }
    428 
    429 static void RunArchOptimizations(InstructionSet instruction_set,
    430                                  HGraph* graph,
    431                                  CodeGenerator* codegen,
    432                                  OptimizingCompilerStats* stats,
    433                                  PassObserver* pass_observer) {
    434   ArenaAllocator* arena = graph->GetArena();
    435   switch (instruction_set) {
    436 #ifdef ART_ENABLE_CODEGEN_arm
    437     case kThumb2:
    438     case kArm: {
    439       arm::DexCacheArrayFixups* fixups = new (arena) arm::DexCacheArrayFixups(graph, stats);
    440       arm::InstructionSimplifierArm* simplifier =
    441           new (arena) arm::InstructionSimplifierArm(graph, stats);
    442       HOptimization* arm_optimizations[] = {
    443         simplifier,
    444         fixups
    445       };
    446       RunOptimizations(arm_optimizations, arraysize(arm_optimizations), pass_observer);
    447       break;
    448     }
    449 #endif
    450 #ifdef ART_ENABLE_CODEGEN_arm64
    451     case kArm64: {
    452       arm64::InstructionSimplifierArm64* simplifier =
    453           new (arena) arm64::InstructionSimplifierArm64(graph, stats);
    454       SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph);
    455       GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN_after_arch");
    456       HOptimization* arm64_optimizations[] = {
    457         simplifier,
    458         side_effects,
    459         gvn
    460       };
    461       RunOptimizations(arm64_optimizations, arraysize(arm64_optimizations), pass_observer);
    462       break;
    463     }
    464 #endif
    465 #ifdef ART_ENABLE_CODEGEN_x86
    466     case kX86: {
    467       x86::PcRelativeFixups* pc_relative_fixups =
    468           new (arena) x86::PcRelativeFixups(graph, codegen, stats);
    469       HOptimization* x86_optimizations[] = {
    470           pc_relative_fixups
    471       };
    472       RunOptimizations(x86_optimizations, arraysize(x86_optimizations), pass_observer);
    473       break;
    474     }
    475 #endif
    476     default:
    477       break;
    478   }
    479 }
    480 
    481 NO_INLINE  // Avoid increasing caller's frame size by large stack-allocated objects.
    482 static void AllocateRegisters(HGraph* graph,
    483                               CodeGenerator* codegen,
    484                               PassObserver* pass_observer) {
    485   {
    486     PassScope scope(PrepareForRegisterAllocation::kPrepareForRegisterAllocationPassName,
    487                     pass_observer);
    488     PrepareForRegisterAllocation(graph).Run();
    489   }
    490   SsaLivenessAnalysis liveness(graph, codegen);
    491   {
    492     PassScope scope(SsaLivenessAnalysis::kLivenessPassName, pass_observer);
    493     liveness.Analyze();
    494   }
    495   {
    496     PassScope scope(RegisterAllocator::kRegisterAllocatorPassName, pass_observer);
    497     RegisterAllocator(graph->GetArena(), codegen, liveness).AllocateRegisters();
    498   }
    499 }
    500 
    501 static void RunOptimizations(HGraph* graph,
    502                              CodeGenerator* codegen,
    503                              CompilerDriver* driver,
    504                              OptimizingCompilerStats* stats,
    505                              const DexCompilationUnit& dex_compilation_unit,
    506                              PassObserver* pass_observer,
    507                              StackHandleScopeCollection* handles) {
    508   ArenaAllocator* arena = graph->GetArena();
    509   HDeadCodeElimination* dce1 = new (arena) HDeadCodeElimination(
    510       graph, stats, HDeadCodeElimination::kInitialDeadCodeEliminationPassName);
    511   HDeadCodeElimination* dce2 = new (arena) HDeadCodeElimination(
    512       graph, stats, HDeadCodeElimination::kFinalDeadCodeEliminationPassName);
    513   HConstantFolding* fold1 = new (arena) HConstantFolding(graph);
    514   InstructionSimplifier* simplify1 = new (arena) InstructionSimplifier(graph, stats);
    515   HSelectGenerator* select_generator = new (arena) HSelectGenerator(graph, stats);
    516   HConstantFolding* fold2 = new (arena) HConstantFolding(graph, "constant_folding_after_inlining");
    517   HConstantFolding* fold3 = new (arena) HConstantFolding(graph, "constant_folding_after_bce");
    518   SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph);
    519   GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects);
    520   LICM* licm = new (arena) LICM(graph, *side_effects, stats);
    521   LoadStoreElimination* lse = new (arena) LoadStoreElimination(graph, *side_effects);
    522   HInductionVarAnalysis* induction = new (arena) HInductionVarAnalysis(graph);
    523   BoundsCheckElimination* bce = new (arena) BoundsCheckElimination(graph, *side_effects, induction);
    524   HSharpening* sharpening = new (arena) HSharpening(graph, codegen, dex_compilation_unit, driver);
    525   InstructionSimplifier* simplify2 = new (arena) InstructionSimplifier(
    526       graph, stats, "instruction_simplifier_after_bce");
    527   InstructionSimplifier* simplify3 = new (arena) InstructionSimplifier(
    528       graph, stats, "instruction_simplifier_before_codegen");
    529   IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, driver, stats);
    530 
    531   HOptimization* optimizations1[] = {
    532     intrinsics,
    533     sharpening,
    534     fold1,
    535     simplify1,
    536     dce1,
    537   };
    538   RunOptimizations(optimizations1, arraysize(optimizations1), pass_observer);
    539 
    540   MaybeRunInliner(graph, codegen, driver, stats, dex_compilation_unit, pass_observer, handles);
    541 
    542   HOptimization* optimizations2[] = {
    543     // SelectGenerator depends on the InstructionSimplifier removing
    544     // redundant suspend checks to recognize empty blocks.
    545     select_generator,
    546     fold2,  // TODO: if we don't inline we can also skip fold2.
    547     side_effects,
    548     gvn,
    549     licm,
    550     induction,
    551     bce,
    552     fold3,  // evaluates code generated by dynamic bce
    553     simplify2,
    554     lse,
    555     dce2,
    556     // The codegen has a few assumptions that only the instruction simplifier
    557     // can satisfy. For example, the code generator does not expect to see a
    558     // HTypeConversion from a type to the same type.
    559     simplify3,
    560   };
    561   RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer);
    562 
    563   RunArchOptimizations(driver->GetInstructionSet(), graph, codegen, stats, pass_observer);
    564   AllocateRegisters(graph, codegen, pass_observer);
    565 }
    566 
    567 static ArenaVector<LinkerPatch> EmitAndSortLinkerPatches(CodeGenerator* codegen) {
    568   ArenaVector<LinkerPatch> linker_patches(codegen->GetGraph()->GetArena()->Adapter());
    569   codegen->EmitLinkerPatches(&linker_patches);
    570 
    571   // Sort patches by literal offset. Required for .oat_patches encoding.
    572   std::sort(linker_patches.begin(), linker_patches.end(),
    573             [](const LinkerPatch& lhs, const LinkerPatch& rhs) {
    574     return lhs.LiteralOffset() < rhs.LiteralOffset();
    575   });
    576 
    577   return linker_patches;
    578 }
    579 
    580 CompiledMethod* OptimizingCompiler::Emit(ArenaAllocator* arena,
    581                                          CodeVectorAllocator* code_allocator,
    582                                          CodeGenerator* codegen,
    583                                          CompilerDriver* compiler_driver,
    584                                          const DexFile::CodeItem* code_item) const {
    585   ArenaVector<LinkerPatch> linker_patches = EmitAndSortLinkerPatches(codegen);
    586   ArenaVector<uint8_t> stack_map(arena->Adapter(kArenaAllocStackMaps));
    587   stack_map.resize(codegen->ComputeStackMapsSize());
    588   codegen->BuildStackMaps(MemoryRegion(stack_map.data(), stack_map.size()), *code_item);
    589 
    590   CompiledMethod* compiled_method = CompiledMethod::SwapAllocCompiledMethod(
    591       compiler_driver,
    592       codegen->GetInstructionSet(),
    593       ArrayRef<const uint8_t>(code_allocator->GetMemory()),
    594       // Follow Quick's behavior and set the frame size to zero if it is
    595       // considered "empty" (see the definition of
    596       // art::CodeGenerator::HasEmptyFrame).
    597       codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
    598       codegen->GetCoreSpillMask(),
    599       codegen->GetFpuSpillMask(),
    600       ArrayRef<const SrcMapElem>(),
    601       ArrayRef<const uint8_t>(stack_map),
    602       ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data()),
    603       ArrayRef<const LinkerPatch>(linker_patches));
    604 
    605   return compiled_method;
    606 }
    607 
    608 CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena,
    609                                               CodeVectorAllocator* code_allocator,
    610                                               const DexFile::CodeItem* code_item,
    611                                               uint32_t access_flags,
    612                                               InvokeType invoke_type,
    613                                               uint16_t class_def_idx,
    614                                               uint32_t method_idx,
    615                                               jobject class_loader,
    616                                               const DexFile& dex_file,
    617                                               Handle<mirror::DexCache> dex_cache,
    618                                               ArtMethod* method,
    619                                               bool osr) const {
    620   MaybeRecordStat(MethodCompilationStat::kAttemptCompilation);
    621   CompilerDriver* compiler_driver = GetCompilerDriver();
    622   InstructionSet instruction_set = compiler_driver->GetInstructionSet();
    623 
    624   // Always use the Thumb-2 assembler: some runtime functionality
    625   // (like implicit stack overflow checks) assume Thumb-2.
    626   if (instruction_set == kArm) {
    627     instruction_set = kThumb2;
    628   }
    629 
    630   // Do not attempt to compile on architectures we do not support.
    631   if (!IsInstructionSetSupported(instruction_set)) {
    632     MaybeRecordStat(MethodCompilationStat::kNotCompiledUnsupportedIsa);
    633     return nullptr;
    634   }
    635 
    636   // When read barriers are enabled, do not attempt to compile for
    637   // instruction sets that have no read barrier support.
    638   if (kEmitCompilerReadBarrier && !InstructionSetSupportsReadBarrier(instruction_set)) {
    639     return nullptr;
    640   }
    641 
    642   if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
    643     MaybeRecordStat(MethodCompilationStat::kNotCompiledPathological);
    644     return nullptr;
    645   }
    646 
    647   // Implementation of the space filter: do not compile a code item whose size in
    648   // code units is bigger than 128.
    649   static constexpr size_t kSpaceFilterOptimizingThreshold = 128;
    650   const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions();
    651   if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace)
    652       && (code_item->insns_size_in_code_units_ > kSpaceFilterOptimizingThreshold)) {
    653     MaybeRecordStat(MethodCompilationStat::kNotCompiledSpaceFilter);
    654     return nullptr;
    655   }
    656 
    657   DexCompilationUnit dex_compilation_unit(
    658       class_loader,
    659       Runtime::Current()->GetClassLinker(),
    660       dex_file,
    661       code_item,
    662       class_def_idx,
    663       method_idx,
    664       access_flags,
    665       /* verified_method */ nullptr,
    666       dex_cache);
    667 
    668   bool requires_barrier = dex_compilation_unit.IsConstructor()
    669       && compiler_driver->RequiresConstructorBarrier(Thread::Current(),
    670                                                      dex_compilation_unit.GetDexFile(),
    671                                                      dex_compilation_unit.GetClassDefIndex());
    672 
    673   HGraph* graph = new (arena) HGraph(
    674       arena,
    675       dex_file,
    676       method_idx,
    677       requires_barrier,
    678       compiler_driver->GetInstructionSet(),
    679       kInvalidInvokeType,
    680       compiler_driver->GetCompilerOptions().GetDebuggable(),
    681       osr);
    682 
    683   const uint8_t* interpreter_metadata = nullptr;
    684   if (method == nullptr) {
    685     ScopedObjectAccess soa(Thread::Current());
    686     StackHandleScope<1> hs(soa.Self());
    687     Handle<mirror::ClassLoader> loader(hs.NewHandle(
    688         soa.Decode<mirror::ClassLoader*>(class_loader)));
    689     method = compiler_driver->ResolveMethod(
    690         soa, dex_cache, loader, &dex_compilation_unit, method_idx, invoke_type);
    691   }
    692   // For AOT compilation, we may not get a method, for example if its class is erroneous.
    693   // JIT should always have a method.
    694   DCHECK(Runtime::Current()->IsAotCompiler() || method != nullptr);
    695   if (method != nullptr) {
    696     graph->SetArtMethod(method);
    697     ScopedObjectAccess soa(Thread::Current());
    698     interpreter_metadata = method->GetQuickenedInfo();
    699     uint16_t type_index = method->GetDeclaringClass()->GetDexTypeIndex();
    700 
    701     // Update the dex cache if the type is not in it yet. Note that under AOT,
    702     // the verifier must have set it, but under JIT, there's no guarantee, as we
    703     // don't necessarily run the verifier.
    704     // The compiler and the compiler driver assume the compiling class is
    705     // in the dex cache.
    706     if (dex_cache->GetResolvedType(type_index) == nullptr) {
    707       dex_cache->SetResolvedType(type_index, method->GetDeclaringClass());
    708     }
    709   }
    710 
    711   std::unique_ptr<CodeGenerator> codegen(
    712       CodeGenerator::Create(graph,
    713                             instruction_set,
    714                             *compiler_driver->GetInstructionSetFeatures(),
    715                             compiler_driver->GetCompilerOptions(),
    716                             compilation_stats_.get()));
    717   if (codegen.get() == nullptr) {
    718     MaybeRecordStat(MethodCompilationStat::kNotCompiledNoCodegen);
    719     return nullptr;
    720   }
    721   codegen->GetAssembler()->cfi().SetEnabled(
    722       compiler_driver->GetCompilerOptions().GenerateAnyDebugInfo());
    723 
    724   PassObserver pass_observer(graph,
    725                              codegen.get(),
    726                              visualizer_output_.get(),
    727                              compiler_driver);
    728 
    729   VLOG(compiler) << "Building " << pass_observer.GetMethodName();
    730 
    731   {
    732     ScopedObjectAccess soa(Thread::Current());
    733     StackHandleScopeCollection handles(soa.Self());
    734     // Do not hold `mutator_lock_` between optimizations.
    735     ScopedThreadSuspension sts(soa.Self(), kNative);
    736 
    737     {
    738       PassScope scope(HGraphBuilder::kBuilderPassName, &pass_observer);
    739       HGraphBuilder builder(graph,
    740                             &dex_compilation_unit,
    741                             &dex_compilation_unit,
    742                             &dex_file,
    743                             *code_item,
    744                             compiler_driver,
    745                             compilation_stats_.get(),
    746                             interpreter_metadata,
    747                             dex_cache,
    748                             &handles);
    749       GraphAnalysisResult result = builder.BuildGraph();
    750       if (result != kAnalysisSuccess) {
    751         switch (result) {
    752           case kAnalysisSkipped:
    753             MaybeRecordStat(MethodCompilationStat::kNotCompiledSkipped);
    754             break;
    755           case kAnalysisInvalidBytecode:
    756             MaybeRecordStat(MethodCompilationStat::kNotCompiledInvalidBytecode);
    757             break;
    758           case kAnalysisFailThrowCatchLoop:
    759             MaybeRecordStat(MethodCompilationStat::kNotCompiledThrowCatchLoop);
    760             break;
    761           case kAnalysisFailAmbiguousArrayOp:
    762             MaybeRecordStat(MethodCompilationStat::kNotCompiledAmbiguousArrayOp);
    763             break;
    764           case kAnalysisSuccess:
    765             UNREACHABLE();
    766         }
    767         pass_observer.SetGraphInBadState();
    768         return nullptr;
    769       }
    770     }
    771 
    772     RunOptimizations(graph,
    773                      codegen.get(),
    774                      compiler_driver,
    775                      compilation_stats_.get(),
    776                      dex_compilation_unit,
    777                      &pass_observer,
    778                      &handles);
    779 
    780     codegen->Compile(code_allocator);
    781     pass_observer.DumpDisassembly();
    782   }
    783 
    784   return codegen.release();
    785 }
    786 
    787 CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item,
    788                                             uint32_t access_flags,
    789                                             InvokeType invoke_type,
    790                                             uint16_t class_def_idx,
    791                                             uint32_t method_idx,
    792                                             jobject jclass_loader,
    793                                             const DexFile& dex_file,
    794                                             Handle<mirror::DexCache> dex_cache) const {
    795   CompilerDriver* compiler_driver = GetCompilerDriver();
    796   CompiledMethod* method = nullptr;
    797   DCHECK(Runtime::Current()->IsAotCompiler());
    798   const VerifiedMethod* verified_method = compiler_driver->GetVerifiedMethod(&dex_file, method_idx);
    799   DCHECK(!verified_method->HasRuntimeThrow());
    800   if (compiler_driver->IsMethodVerifiedWithoutFailures(method_idx, class_def_idx, dex_file)
    801       || verifier::MethodVerifier::CanCompilerHandleVerificationFailure(
    802             verified_method->GetEncounteredVerificationFailures())) {
    803     ArenaAllocator arena(Runtime::Current()->GetArenaPool());
    804     CodeVectorAllocator code_allocator(&arena);
    805     std::unique_ptr<CodeGenerator> codegen(
    806         TryCompile(&arena,
    807                    &code_allocator,
    808                    code_item,
    809                    access_flags,
    810                    invoke_type,
    811                    class_def_idx,
    812                    method_idx,
    813                    jclass_loader,
    814                    dex_file,
    815                    dex_cache,
    816                    nullptr,
    817                    /* osr */ false));
    818     if (codegen.get() != nullptr) {
    819       MaybeRecordStat(MethodCompilationStat::kCompiled);
    820       method = Emit(&arena, &code_allocator, codegen.get(), compiler_driver, code_item);
    821 
    822       if (kArenaAllocatorCountAllocations) {
    823         if (arena.BytesAllocated() > kArenaAllocatorMemoryReportThreshold) {
    824           MemStats mem_stats(arena.GetMemStats());
    825           LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats);
    826         }
    827       }
    828     }
    829   } else {
    830     if (compiler_driver->GetCompilerOptions().VerifyAtRuntime()) {
    831       MaybeRecordStat(MethodCompilationStat::kNotCompiledVerifyAtRuntime);
    832     } else {
    833       MaybeRecordStat(MethodCompilationStat::kNotCompiledVerificationError);
    834     }
    835   }
    836 
    837   if (kIsDebugBuild &&
    838       IsCompilingWithCoreImage() &&
    839       IsInstructionSetSupported(compiler_driver->GetInstructionSet()) &&
    840       (!kEmitCompilerReadBarrier ||
    841        InstructionSetSupportsReadBarrier(compiler_driver->GetInstructionSet()))) {
    842     // For testing purposes, we put a special marker on method names
    843     // that should be compiled with this compiler (when the the
    844     // instruction set is supported -- and has support for read
    845     // barriers, if they are enabled). This makes sure we're not
    846     // regressing.
    847     std::string method_name = PrettyMethod(method_idx, dex_file);
    848     bool shouldCompile = method_name.find("$opt$") != std::string::npos;
    849     DCHECK((method != nullptr) || !shouldCompile) << "Didn't compile " << method_name;
    850   }
    851 
    852   return method;
    853 }
    854 
    855 Compiler* CreateOptimizingCompiler(CompilerDriver* driver) {
    856   return new OptimizingCompiler(driver);
    857 }
    858 
    859 bool IsCompilingWithCoreImage() {
    860   const std::string& image = Runtime::Current()->GetImageLocation();
    861   // TODO: This is under-approximating...
    862   if (EndsWith(image, "core.art") || EndsWith(image, "core-optimizing.art")) {
    863     return true;
    864   }
    865   return false;
    866 }
    867 
    868 bool OptimizingCompiler::JitCompile(Thread* self,
    869                                     jit::JitCodeCache* code_cache,
    870                                     ArtMethod* method,
    871                                     bool osr) {
    872   StackHandleScope<2> hs(self);
    873   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
    874       method->GetDeclaringClass()->GetClassLoader()));
    875   Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
    876   DCHECK(method->IsCompilable());
    877 
    878   jobject jclass_loader = class_loader.ToJObject();
    879   const DexFile* dex_file = method->GetDexFile();
    880   const uint16_t class_def_idx = method->GetClassDefIndex();
    881   const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
    882   const uint32_t method_idx = method->GetDexMethodIndex();
    883   const uint32_t access_flags = method->GetAccessFlags();
    884   const InvokeType invoke_type = method->GetInvokeType();
    885 
    886   ArenaAllocator arena(Runtime::Current()->GetJitArenaPool());
    887   CodeVectorAllocator code_allocator(&arena);
    888   std::unique_ptr<CodeGenerator> codegen;
    889   {
    890     // Go to native so that we don't block GC during compilation.
    891     ScopedThreadSuspension sts(self, kNative);
    892     codegen.reset(
    893         TryCompile(&arena,
    894                    &code_allocator,
    895                    code_item,
    896                    access_flags,
    897                    invoke_type,
    898                    class_def_idx,
    899                    method_idx,
    900                    jclass_loader,
    901                    *dex_file,
    902                    dex_cache,
    903                    method,
    904                    osr));
    905     if (codegen.get() == nullptr) {
    906       return false;
    907     }
    908 
    909     if (kArenaAllocatorCountAllocations) {
    910       if (arena.BytesAllocated() > kArenaAllocatorMemoryReportThreshold) {
    911         MemStats mem_stats(arena.GetMemStats());
    912         LOG(INFO) << PrettyMethod(method_idx, *dex_file) << " " << Dumpable<MemStats>(mem_stats);
    913       }
    914     }
    915   }
    916 
    917   size_t stack_map_size = codegen->ComputeStackMapsSize();
    918   uint8_t* stack_map_data = code_cache->ReserveData(self, stack_map_size, method);
    919   if (stack_map_data == nullptr) {
    920     return false;
    921   }
    922   MaybeRecordStat(MethodCompilationStat::kCompiled);
    923   codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size), *code_item);
    924   const void* code = code_cache->CommitCode(
    925       self,
    926       method,
    927       stack_map_data,
    928       codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
    929       codegen->GetCoreSpillMask(),
    930       codegen->GetFpuSpillMask(),
    931       code_allocator.GetMemory().data(),
    932       code_allocator.GetSize(),
    933       osr);
    934 
    935   if (code == nullptr) {
    936     code_cache->ClearData(self, stack_map_data);
    937     return false;
    938   }
    939 
    940   const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
    941   if (compiler_options.GetGenerateDebugInfo()) {
    942     const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
    943     const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
    944     debug::MethodDebugInfo info = debug::MethodDebugInfo();
    945     info.trampoline_name = nullptr;
    946     info.dex_file = dex_file;
    947     info.class_def_index = class_def_idx;
    948     info.dex_method_index = method_idx;
    949     info.access_flags = access_flags;
    950     info.code_item = code_item;
    951     info.isa = codegen->GetInstructionSet();
    952     info.deduped = false;
    953     info.is_native_debuggable = compiler_options.GetNativeDebuggable();
    954     info.is_optimized = true;
    955     info.is_code_address_text_relative = false;
    956     info.code_address = code_address;
    957     info.code_size = code_allocator.GetSize();
    958     info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
    959     info.code_info = stack_map_size == 0 ? nullptr : stack_map_data;
    960     info.cfi = ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data());
    961     std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForMethods(
    962         GetCompilerDriver()->GetInstructionSet(),
    963         GetCompilerDriver()->GetInstructionSetFeatures(),
    964         ArrayRef<const debug::MethodDebugInfo>(&info, 1));
    965     CreateJITCodeEntryForAddress(code_address, std::move(elf_file));
    966   }
    967 
    968   Runtime::Current()->GetJit()->AddMemoryUsage(method, arena.BytesUsed());
    969 
    970   return true;
    971 }
    972 
    973 }  // namespace art
    974