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 "art_method-inl.h"
26#include "base/arena_allocator.h"
27#include "base/arena_containers.h"
28#include "base/dumpable.h"
29#include "base/macros.h"
30#include "base/mutex.h"
31#include "base/scoped_arena_allocator.h"
32#include "base/timing_logger.h"
33#include "builder.h"
34#include "code_generator.h"
35#include "compiled_method.h"
36#include "compiler.h"
37#include "debug/elf_debug_writer.h"
38#include "debug/method_debug_info.h"
39#include "dex/dex_file_types.h"
40#include "dex/verification_results.h"
41#include "dex/verified_method.h"
42#include "driver/compiler_driver-inl.h"
43#include "driver/compiler_options.h"
44#include "driver/dex_compilation_unit.h"
45#include "graph_checker.h"
46#include "graph_visualizer.h"
47#include "inliner.h"
48#include "jit/debugger_interface.h"
49#include "jit/jit.h"
50#include "jit/jit_code_cache.h"
51#include "jit/jit_logger.h"
52#include "jni/quick/jni_compiler.h"
53#include "linker/linker_patch.h"
54#include "nodes.h"
55#include "oat_quick_method_header.h"
56#include "prepare_for_register_allocation.h"
57#include "reference_type_propagation.h"
58#include "register_allocator_linear_scan.h"
59#include "select_generator.h"
60#include "ssa_builder.h"
61#include "ssa_liveness_analysis.h"
62#include "ssa_phi_elimination.h"
63#include "utils/assembler.h"
64#include "verifier/verifier_compiler_binding.h"
65
66namespace art {
67
68static constexpr size_t kArenaAllocatorMemoryReportThreshold = 8 * MB;
69
70static constexpr const char* kPassNameSeparator = "$";
71
72/**
73 * Used by the code generator, to allocate the code in a vector.
74 */
75class CodeVectorAllocator FINAL : public CodeAllocator {
76 public:
77  explicit CodeVectorAllocator(ArenaAllocator* allocator)
78      : memory_(allocator->Adapter(kArenaAllocCodeBuffer)),
79        size_(0) {}
80
81  virtual uint8_t* Allocate(size_t size) {
82    size_ = size;
83    memory_.resize(size);
84    return &memory_[0];
85  }
86
87  size_t GetSize() const { return size_; }
88  const ArenaVector<uint8_t>& GetMemory() const { return memory_; }
89  uint8_t* GetData() { return memory_.data(); }
90
91 private:
92  ArenaVector<uint8_t> memory_;
93  size_t size_;
94
95  DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator);
96};
97
98/**
99 * Filter to apply to the visualizer. Methods whose name contain that filter will
100 * be dumped.
101 */
102static constexpr const char kStringFilter[] = "";
103
104class PassScope;
105
106class PassObserver : public ValueObject {
107 public:
108  PassObserver(HGraph* graph,
109               CodeGenerator* codegen,
110               std::ostream* visualizer_output,
111               CompilerDriver* compiler_driver,
112               Mutex& dump_mutex)
113      : graph_(graph),
114        cached_method_name_(),
115        timing_logger_enabled_(compiler_driver->GetCompilerOptions().GetDumpTimings()),
116        timing_logger_(timing_logger_enabled_ ? GetMethodName() : "", true, true),
117        disasm_info_(graph->GetAllocator()),
118        visualizer_oss_(),
119        visualizer_output_(visualizer_output),
120        visualizer_enabled_(!compiler_driver->GetCompilerOptions().GetDumpCfgFileName().empty()),
121        visualizer_(&visualizer_oss_, graph, *codegen),
122        visualizer_dump_mutex_(dump_mutex),
123        graph_in_bad_state_(false) {
124    if (timing_logger_enabled_ || visualizer_enabled_) {
125      if (!IsVerboseMethod(compiler_driver, GetMethodName())) {
126        timing_logger_enabled_ = visualizer_enabled_ = false;
127      }
128      if (visualizer_enabled_) {
129        visualizer_.PrintHeader(GetMethodName());
130        codegen->SetDisassemblyInformation(&disasm_info_);
131      }
132    }
133  }
134
135  ~PassObserver() {
136    if (timing_logger_enabled_) {
137      LOG(INFO) << "TIMINGS " << GetMethodName();
138      LOG(INFO) << Dumpable<TimingLogger>(timing_logger_);
139    }
140    DCHECK(visualizer_oss_.str().empty());
141  }
142
143  void DumpDisassembly() REQUIRES(!visualizer_dump_mutex_) {
144    if (visualizer_enabled_) {
145      visualizer_.DumpGraphWithDisassembly();
146      FlushVisualizer();
147    }
148  }
149
150  void SetGraphInBadState() { graph_in_bad_state_ = true; }
151
152  const char* GetMethodName() {
153    // PrettyMethod() is expensive, so we delay calling it until we actually have to.
154    if (cached_method_name_.empty()) {
155      cached_method_name_ = graph_->GetDexFile().PrettyMethod(graph_->GetMethodIdx());
156    }
157    return cached_method_name_.c_str();
158  }
159
160 private:
161  void StartPass(const char* pass_name) REQUIRES(!visualizer_dump_mutex_) {
162    VLOG(compiler) << "Starting pass: " << pass_name;
163    // Dump graph first, then start timer.
164    if (visualizer_enabled_) {
165      visualizer_.DumpGraph(pass_name, /* is_after_pass */ false, graph_in_bad_state_);
166      FlushVisualizer();
167    }
168    if (timing_logger_enabled_) {
169      timing_logger_.StartTiming(pass_name);
170    }
171  }
172
173  void FlushVisualizer() REQUIRES(!visualizer_dump_mutex_) {
174    MutexLock mu(Thread::Current(), visualizer_dump_mutex_);
175    *visualizer_output_ << visualizer_oss_.str();
176    visualizer_output_->flush();
177    visualizer_oss_.str("");
178    visualizer_oss_.clear();
179  }
180
181  void EndPass(const char* pass_name) REQUIRES(!visualizer_dump_mutex_) {
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      FlushVisualizer();
189    }
190
191    // Validate the HGraph if running in debug mode.
192    if (kIsDebugBuild) {
193      if (!graph_in_bad_state_) {
194        GraphChecker checker(graph_);
195        checker.Run();
196        if (!checker.IsValid()) {
197          LOG(FATAL) << "Error after " << pass_name << ": " << Dumpable<GraphChecker>(checker);
198        }
199      }
200    }
201  }
202
203  static bool IsVerboseMethod(CompilerDriver* compiler_driver, const char* method_name) {
204    // Test an exact match to --verbose-methods. If verbose-methods is set, this overrides an
205    // empty kStringFilter matching all methods.
206    if (compiler_driver->GetCompilerOptions().HasVerboseMethods()) {
207      return compiler_driver->GetCompilerOptions().IsVerboseMethod(method_name);
208    }
209
210    // Test the kStringFilter sub-string. constexpr helper variable to silence unreachable-code
211    // warning when the string is empty.
212    constexpr bool kStringFilterEmpty = arraysize(kStringFilter) <= 1;
213    if (kStringFilterEmpty || strstr(method_name, kStringFilter) != nullptr) {
214      return true;
215    }
216
217    return false;
218  }
219
220  HGraph* const graph_;
221
222  std::string cached_method_name_;
223
224  bool timing_logger_enabled_;
225  TimingLogger timing_logger_;
226
227  DisassemblyInformation disasm_info_;
228
229  std::ostringstream visualizer_oss_;
230  std::ostream* visualizer_output_;
231  bool visualizer_enabled_;
232  HGraphVisualizer visualizer_;
233  Mutex& visualizer_dump_mutex_;
234
235  // Flag to be set by the compiler if the pass failed and the graph is not
236  // expected to validate.
237  bool graph_in_bad_state_;
238
239  friend PassScope;
240
241  DISALLOW_COPY_AND_ASSIGN(PassObserver);
242};
243
244class PassScope : public ValueObject {
245 public:
246  PassScope(const char *pass_name, PassObserver* pass_observer)
247      : pass_name_(pass_name),
248        pass_observer_(pass_observer) {
249    pass_observer_->StartPass(pass_name_);
250  }
251
252  ~PassScope() {
253    pass_observer_->EndPass(pass_name_);
254  }
255
256 private:
257  const char* const pass_name_;
258  PassObserver* const pass_observer_;
259};
260
261class OptimizingCompiler FINAL : public Compiler {
262 public:
263  explicit OptimizingCompiler(CompilerDriver* driver);
264  ~OptimizingCompiler() OVERRIDE;
265
266  bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file) const OVERRIDE;
267
268  CompiledMethod* Compile(const DexFile::CodeItem* code_item,
269                          uint32_t access_flags,
270                          InvokeType invoke_type,
271                          uint16_t class_def_idx,
272                          uint32_t method_idx,
273                          Handle<mirror::ClassLoader> class_loader,
274                          const DexFile& dex_file,
275                          Handle<mirror::DexCache> dex_cache) const OVERRIDE;
276
277  CompiledMethod* JniCompile(uint32_t access_flags,
278                             uint32_t method_idx,
279                             const DexFile& dex_file,
280                             Handle<mirror::DexCache> dex_cache) const OVERRIDE;
281
282  uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE
283      REQUIRES_SHARED(Locks::mutator_lock_) {
284    return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
285        InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
286  }
287
288  void Init() OVERRIDE;
289
290  void UnInit() const OVERRIDE;
291
292  bool JitCompile(Thread* self,
293                  jit::JitCodeCache* code_cache,
294                  ArtMethod* method,
295                  bool osr,
296                  jit::JitLogger* jit_logger)
297      OVERRIDE
298      REQUIRES_SHARED(Locks::mutator_lock_);
299
300 private:
301  void RunOptimizations(HGraph* graph,
302                        CodeGenerator* codegen,
303                        const DexCompilationUnit& dex_compilation_unit,
304                        PassObserver* pass_observer,
305                        VariableSizedHandleScope* handles,
306                        const OptimizationDef definitions[],
307                        size_t length) const {
308    // Convert definitions to optimization passes.
309    ArenaVector<HOptimization*> optimizations = ConstructOptimizations(
310        definitions,
311        length,
312        graph->GetAllocator(),
313        graph,
314        compilation_stats_.get(),
315        codegen,
316        GetCompilerDriver(),
317        dex_compilation_unit,
318        handles);
319    DCHECK_EQ(length, optimizations.size());
320    // Run the optimization passes one by one.
321    for (size_t i = 0; i < length; ++i) {
322      PassScope scope(optimizations[i]->GetPassName(), pass_observer);
323      optimizations[i]->Run();
324    }
325  }
326
327  template <size_t length> void RunOptimizations(
328      HGraph* graph,
329      CodeGenerator* codegen,
330      const DexCompilationUnit& dex_compilation_unit,
331      PassObserver* pass_observer,
332      VariableSizedHandleScope* handles,
333      const OptimizationDef (&definitions)[length]) const {
334    RunOptimizations(
335        graph, codegen, dex_compilation_unit, pass_observer, handles, definitions, length);
336  }
337
338  void RunOptimizations(HGraph* graph,
339                        CodeGenerator* codegen,
340                        const DexCompilationUnit& dex_compilation_unit,
341                        PassObserver* pass_observer,
342                        VariableSizedHandleScope* handles) const;
343
344 private:
345  // Create a 'CompiledMethod' for an optimized graph.
346  CompiledMethod* Emit(ArenaAllocator* allocator,
347                       CodeVectorAllocator* code_allocator,
348                       CodeGenerator* codegen,
349                       const DexFile::CodeItem* item) const;
350
351  // Try compiling a method and return the code generator used for
352  // compiling it.
353  // This method:
354  // 1) Builds the graph. Returns null if it failed to build it.
355  // 2) Transforms the graph to SSA. Returns null if it failed.
356  // 3) Runs optimizations on the graph, including register allocator.
357  // 4) Generates code with the `code_allocator` provided.
358  CodeGenerator* TryCompile(ArenaAllocator* allocator,
359                            ArenaStack* arena_stack,
360                            CodeVectorAllocator* code_allocator,
361                            const DexCompilationUnit& dex_compilation_unit,
362                            ArtMethod* method,
363                            bool osr,
364                            VariableSizedHandleScope* handles) const;
365
366  CodeGenerator* TryCompileIntrinsic(ArenaAllocator* allocator,
367                                     ArenaStack* arena_stack,
368                                     CodeVectorAllocator* code_allocator,
369                                     const DexCompilationUnit& dex_compilation_unit,
370                                     ArtMethod* method,
371                                     VariableSizedHandleScope* handles) const;
372
373  void MaybeRunInliner(HGraph* graph,
374                       CodeGenerator* codegen,
375                       const DexCompilationUnit& dex_compilation_unit,
376                       PassObserver* pass_observer,
377                       VariableSizedHandleScope* handles) const;
378
379  void RunArchOptimizations(HGraph* graph,
380                            CodeGenerator* codegen,
381                            const DexCompilationUnit& dex_compilation_unit,
382                            PassObserver* pass_observer,
383                            VariableSizedHandleScope* handles) const;
384
385  void GenerateJitDebugInfo(ArtMethod* method, debug::MethodDebugInfo method_debug_info)
386      REQUIRES_SHARED(Locks::mutator_lock_);
387
388  std::unique_ptr<OptimizingCompilerStats> compilation_stats_;
389
390  std::unique_ptr<std::ostream> visualizer_output_;
391
392  mutable Mutex dump_mutex_;  // To synchronize visualizer writing.
393
394  DISALLOW_COPY_AND_ASSIGN(OptimizingCompiler);
395};
396
397static const int kMaximumCompilationTimeBeforeWarning = 100; /* ms */
398
399OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver)
400    : Compiler(driver, kMaximumCompilationTimeBeforeWarning),
401      dump_mutex_("Visualizer dump lock") {}
402
403void OptimizingCompiler::Init() {
404  // Enable C1visualizer output. Must be done in Init() because the compiler
405  // driver is not fully initialized when passed to the compiler's constructor.
406  CompilerDriver* driver = GetCompilerDriver();
407  const std::string cfg_file_name = driver->GetCompilerOptions().GetDumpCfgFileName();
408  if (!cfg_file_name.empty()) {
409    std::ios_base::openmode cfg_file_mode =
410        driver->GetCompilerOptions().GetDumpCfgAppend() ? std::ofstream::app : std::ofstream::out;
411    visualizer_output_.reset(new std::ofstream(cfg_file_name, cfg_file_mode));
412  }
413  if (driver->GetCompilerOptions().GetDumpStats()) {
414    compilation_stats_.reset(new OptimizingCompilerStats());
415  }
416}
417
418void OptimizingCompiler::UnInit() const {
419}
420
421OptimizingCompiler::~OptimizingCompiler() {
422  if (compilation_stats_.get() != nullptr) {
423    compilation_stats_->Log();
424  }
425}
426
427bool OptimizingCompiler::CanCompileMethod(uint32_t method_idx ATTRIBUTE_UNUSED,
428                                          const DexFile& dex_file ATTRIBUTE_UNUSED) const {
429  return true;
430}
431
432static bool IsInstructionSetSupported(InstructionSet instruction_set) {
433  return instruction_set == InstructionSet::kArm
434      || instruction_set == InstructionSet::kArm64
435      || instruction_set == InstructionSet::kThumb2
436      || instruction_set == InstructionSet::kMips
437      || instruction_set == InstructionSet::kMips64
438      || instruction_set == InstructionSet::kX86
439      || instruction_set == InstructionSet::kX86_64;
440}
441
442void OptimizingCompiler::MaybeRunInliner(HGraph* graph,
443                                         CodeGenerator* codegen,
444                                         const DexCompilationUnit& dex_compilation_unit,
445                                         PassObserver* pass_observer,
446                                         VariableSizedHandleScope* handles) const {
447  const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
448  bool should_inline = (compiler_options.GetInlineMaxCodeUnits() > 0);
449  if (!should_inline) {
450    return;
451  }
452  OptimizationDef optimizations[] = {
453    OptDef(OptimizationPass::kInliner)
454  };
455  RunOptimizations(graph,
456                   codegen,
457                   dex_compilation_unit,
458                   pass_observer,
459                   handles,
460                   optimizations);
461}
462
463void OptimizingCompiler::RunArchOptimizations(HGraph* graph,
464                                              CodeGenerator* codegen,
465                                              const DexCompilationUnit& dex_compilation_unit,
466                                              PassObserver* pass_observer,
467                                              VariableSizedHandleScope* handles) const {
468  switch (GetCompilerDriver()->GetInstructionSet()) {
469#if defined(ART_ENABLE_CODEGEN_arm)
470    case InstructionSet::kThumb2:
471    case InstructionSet::kArm: {
472      OptimizationDef arm_optimizations[] = {
473        OptDef(OptimizationPass::kInstructionSimplifierArm),
474        OptDef(OptimizationPass::kSideEffectsAnalysis),
475        OptDef(OptimizationPass::kGlobalValueNumbering, "GVN$after_arch"),
476        OptDef(OptimizationPass::kScheduling)
477      };
478      RunOptimizations(graph,
479                       codegen,
480                       dex_compilation_unit,
481                       pass_observer,
482                       handles,
483                       arm_optimizations);
484      break;
485    }
486#endif
487#ifdef ART_ENABLE_CODEGEN_arm64
488    case InstructionSet::kArm64: {
489      OptimizationDef arm64_optimizations[] = {
490        OptDef(OptimizationPass::kInstructionSimplifierArm64),
491        OptDef(OptimizationPass::kSideEffectsAnalysis),
492        OptDef(OptimizationPass::kGlobalValueNumbering, "GVN$after_arch"),
493        OptDef(OptimizationPass::kScheduling)
494      };
495      RunOptimizations(graph,
496                       codegen,
497                       dex_compilation_unit,
498                       pass_observer,
499                       handles,
500                       arm64_optimizations);
501      break;
502    }
503#endif
504#ifdef ART_ENABLE_CODEGEN_mips
505    case InstructionSet::kMips: {
506      OptimizationDef mips_optimizations[] = {
507        OptDef(OptimizationPass::kInstructionSimplifierMips),
508        OptDef(OptimizationPass::kSideEffectsAnalysis),
509        OptDef(OptimizationPass::kGlobalValueNumbering, "GVN$after_arch"),
510        OptDef(OptimizationPass::kPcRelativeFixupsMips)
511      };
512      RunOptimizations(graph,
513                       codegen,
514                       dex_compilation_unit,
515                       pass_observer,
516                       handles,
517                       mips_optimizations);
518      break;
519    }
520#endif
521#ifdef ART_ENABLE_CODEGEN_mips64
522    case InstructionSet::kMips64: {
523      OptimizationDef mips64_optimizations[] = {
524        OptDef(OptimizationPass::kSideEffectsAnalysis),
525        OptDef(OptimizationPass::kGlobalValueNumbering, "GVN$after_arch")
526      };
527      RunOptimizations(graph,
528                       codegen,
529                       dex_compilation_unit,
530                       pass_observer,
531                       handles,
532                       mips64_optimizations);
533      break;
534    }
535#endif
536#ifdef ART_ENABLE_CODEGEN_x86
537    case InstructionSet::kX86: {
538      OptimizationDef x86_optimizations[] = {
539        OptDef(OptimizationPass::kSideEffectsAnalysis),
540        OptDef(OptimizationPass::kGlobalValueNumbering, "GVN$after_arch"),
541        OptDef(OptimizationPass::kPcRelativeFixupsX86),
542        OptDef(OptimizationPass::kX86MemoryOperandGeneration)
543      };
544      RunOptimizations(graph,
545                       codegen,
546                       dex_compilation_unit,
547                       pass_observer,
548                       handles,
549                       x86_optimizations);
550      break;
551    }
552#endif
553#ifdef ART_ENABLE_CODEGEN_x86_64
554    case InstructionSet::kX86_64: {
555      OptimizationDef x86_64_optimizations[] = {
556        OptDef(OptimizationPass::kSideEffectsAnalysis),
557        OptDef(OptimizationPass::kGlobalValueNumbering, "GVN$after_arch"),
558        OptDef(OptimizationPass::kX86MemoryOperandGeneration)
559      };
560      RunOptimizations(graph,
561                       codegen,
562                       dex_compilation_unit,
563                       pass_observer,
564                       handles,
565                       x86_64_optimizations);
566      break;
567    }
568#endif
569    default:
570      break;
571  }
572}
573
574NO_INLINE  // Avoid increasing caller's frame size by large stack-allocated objects.
575static void AllocateRegisters(HGraph* graph,
576                              CodeGenerator* codegen,
577                              PassObserver* pass_observer,
578                              RegisterAllocator::Strategy strategy,
579                              OptimizingCompilerStats* stats) {
580  {
581    PassScope scope(PrepareForRegisterAllocation::kPrepareForRegisterAllocationPassName,
582                    pass_observer);
583    PrepareForRegisterAllocation(graph, stats).Run();
584  }
585  // Use local allocator shared by SSA liveness analysis and register allocator.
586  // (Register allocator creates new objects in the liveness data.)
587  ScopedArenaAllocator local_allocator(graph->GetArenaStack());
588  SsaLivenessAnalysis liveness(graph, codegen, &local_allocator);
589  {
590    PassScope scope(SsaLivenessAnalysis::kLivenessPassName, pass_observer);
591    liveness.Analyze();
592  }
593  {
594    PassScope scope(RegisterAllocator::kRegisterAllocatorPassName, pass_observer);
595    std::unique_ptr<RegisterAllocator> register_allocator =
596        RegisterAllocator::Create(&local_allocator, codegen, liveness, strategy);
597    register_allocator->AllocateRegisters();
598  }
599}
600
601// Strip pass name suffix to get optimization name.
602static std::string ConvertPassNameToOptimizationName(const std::string& pass_name) {
603  size_t pos = pass_name.find(kPassNameSeparator);
604  return pos == std::string::npos ? pass_name : pass_name.substr(0, pos);
605}
606
607void OptimizingCompiler::RunOptimizations(HGraph* graph,
608                                          CodeGenerator* codegen,
609                                          const DexCompilationUnit& dex_compilation_unit,
610                                          PassObserver* pass_observer,
611                                          VariableSizedHandleScope* handles) const {
612  const std::vector<std::string>* pass_names =
613      GetCompilerDriver()->GetCompilerOptions().GetPassesToRun();
614  if (pass_names != nullptr) {
615    // If passes were defined on command-line, build the optimization
616    // passes and run these instead of the built-in optimizations.
617    const size_t length = pass_names->size();
618    std::vector<OptimizationDef> optimizations;
619    for (const std::string& pass_name : *pass_names) {
620      std::string opt_name = ConvertPassNameToOptimizationName(pass_name);
621      optimizations.push_back(OptDef(OptimizationPassByName(opt_name.c_str()), pass_name.c_str()));
622    }
623    RunOptimizations(graph,
624                     codegen,
625                     dex_compilation_unit,
626                     pass_observer,
627                     handles,
628                     optimizations.data(),
629                     length);
630    return;
631  }
632
633  OptimizationDef optimizations1[] = {
634    OptDef(OptimizationPass::kIntrinsicsRecognizer),
635    OptDef(OptimizationPass::kSharpening),
636    OptDef(OptimizationPass::kConstantFolding),
637    OptDef(OptimizationPass::kInstructionSimplifier),
638    OptDef(OptimizationPass::kDeadCodeElimination, "dead_code_elimination$initial")
639  };
640  RunOptimizations(graph,
641                   codegen,
642                   dex_compilation_unit,
643                   pass_observer,
644                   handles,
645                   optimizations1);
646
647  MaybeRunInliner(graph, codegen, dex_compilation_unit, pass_observer, handles);
648
649  OptimizationDef optimizations2[] = {
650    // SelectGenerator depends on the InstructionSimplifier removing
651    // redundant suspend checks to recognize empty blocks.
652    OptDef(OptimizationPass::kSelectGenerator),
653    // TODO: if we don't inline we can also skip fold2.
654    OptDef(OptimizationPass::kConstantFolding,       "constant_folding$after_inlining"),
655    OptDef(OptimizationPass::kInstructionSimplifier, "instruction_simplifier$after_inlining"),
656    OptDef(OptimizationPass::kDeadCodeElimination,   "dead_code_elimination$after_inlining"),
657    OptDef(OptimizationPass::kSideEffectsAnalysis,   "side_effects$before_gvn"),
658    OptDef(OptimizationPass::kGlobalValueNumbering),
659    OptDef(OptimizationPass::kInvariantCodeMotion),
660    OptDef(OptimizationPass::kInductionVarAnalysis),
661    OptDef(OptimizationPass::kBoundsCheckElimination),
662    OptDef(OptimizationPass::kLoopOptimization),
663    // Evaluates code generated by dynamic bce.
664    OptDef(OptimizationPass::kConstantFolding,       "constant_folding$after_bce"),
665    OptDef(OptimizationPass::kInstructionSimplifier, "instruction_simplifier$after_bce"),
666    OptDef(OptimizationPass::kSideEffectsAnalysis,   "side_effects$before_lse"),
667    OptDef(OptimizationPass::kLoadStoreAnalysis),
668    OptDef(OptimizationPass::kLoadStoreElimination),
669    OptDef(OptimizationPass::kCHAGuardOptimization),
670    OptDef(OptimizationPass::kDeadCodeElimination,   "dead_code_elimination$final"),
671    OptDef(OptimizationPass::kCodeSinking),
672    // The codegen has a few assumptions that only the instruction simplifier
673    // can satisfy. For example, the code generator does not expect to see a
674    // HTypeConversion from a type to the same type.
675    OptDef(OptimizationPass::kInstructionSimplifier, "instruction_simplifier$before_codegen"),
676    // Eliminate constructor fences after code sinking to avoid
677    // complicated sinking logic to split a fence with many inputs.
678    OptDef(OptimizationPass::kConstructorFenceRedundancyElimination)
679  };
680  RunOptimizations(graph,
681                   codegen,
682                   dex_compilation_unit,
683                   pass_observer,
684                   handles,
685                   optimizations2);
686
687  RunArchOptimizations(graph, codegen, dex_compilation_unit, pass_observer, handles);
688}
689
690static ArenaVector<linker::LinkerPatch> EmitAndSortLinkerPatches(CodeGenerator* codegen) {
691  ArenaVector<linker::LinkerPatch> linker_patches(codegen->GetGraph()->GetAllocator()->Adapter());
692  codegen->EmitLinkerPatches(&linker_patches);
693
694  // Sort patches by literal offset. Required for .oat_patches encoding.
695  std::sort(linker_patches.begin(), linker_patches.end(),
696            [](const linker::LinkerPatch& lhs, const linker::LinkerPatch& rhs) {
697    return lhs.LiteralOffset() < rhs.LiteralOffset();
698  });
699
700  return linker_patches;
701}
702
703CompiledMethod* OptimizingCompiler::Emit(ArenaAllocator* allocator,
704                                         CodeVectorAllocator* code_allocator,
705                                         CodeGenerator* codegen,
706                                         const DexFile::CodeItem* code_item_for_osr_check) const {
707  ArenaVector<linker::LinkerPatch> linker_patches = EmitAndSortLinkerPatches(codegen);
708  ArenaVector<uint8_t> stack_map(allocator->Adapter(kArenaAllocStackMaps));
709  ArenaVector<uint8_t> method_info(allocator->Adapter(kArenaAllocStackMaps));
710  size_t stack_map_size = 0;
711  size_t method_info_size = 0;
712  codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size);
713  stack_map.resize(stack_map_size);
714  method_info.resize(method_info_size);
715  codegen->BuildStackMaps(MemoryRegion(stack_map.data(), stack_map.size()),
716                          MemoryRegion(method_info.data(), method_info.size()),
717                          code_item_for_osr_check);
718
719  CompiledMethod* compiled_method = CompiledMethod::SwapAllocCompiledMethod(
720      GetCompilerDriver(),
721      codegen->GetInstructionSet(),
722      ArrayRef<const uint8_t>(code_allocator->GetMemory()),
723      // Follow Quick's behavior and set the frame size to zero if it is
724      // considered "empty" (see the definition of
725      // art::CodeGenerator::HasEmptyFrame).
726      codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
727      codegen->GetCoreSpillMask(),
728      codegen->GetFpuSpillMask(),
729      ArrayRef<const uint8_t>(method_info),
730      ArrayRef<const uint8_t>(stack_map),
731      ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data()),
732      ArrayRef<const linker::LinkerPatch>(linker_patches));
733
734  return compiled_method;
735}
736
737CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator,
738                                              ArenaStack* arena_stack,
739                                              CodeVectorAllocator* code_allocator,
740                                              const DexCompilationUnit& dex_compilation_unit,
741                                              ArtMethod* method,
742                                              bool osr,
743                                              VariableSizedHandleScope* handles) const {
744  MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kAttemptBytecodeCompilation);
745  CompilerDriver* compiler_driver = GetCompilerDriver();
746  InstructionSet instruction_set = compiler_driver->GetInstructionSet();
747  const DexFile& dex_file = *dex_compilation_unit.GetDexFile();
748  uint32_t method_idx = dex_compilation_unit.GetDexMethodIndex();
749  const DexFile::CodeItem* code_item = dex_compilation_unit.GetCodeItem();
750
751  // Always use the Thumb-2 assembler: some runtime functionality
752  // (like implicit stack overflow checks) assume Thumb-2.
753  DCHECK_NE(instruction_set, InstructionSet::kArm);
754
755  // Do not attempt to compile on architectures we do not support.
756  if (!IsInstructionSetSupported(instruction_set)) {
757    MaybeRecordStat(compilation_stats_.get(),
758                    MethodCompilationStat::kNotCompiledUnsupportedIsa);
759    return nullptr;
760  }
761
762  if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
763    MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kNotCompiledPathological);
764    return nullptr;
765  }
766
767  // Implementation of the space filter: do not compile a code item whose size in
768  // code units is bigger than 128.
769  static constexpr size_t kSpaceFilterOptimizingThreshold = 128;
770  const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions();
771  if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace)
772      && (CodeItemInstructionAccessor(dex_file, code_item).InsnsSizeInCodeUnits() >
773          kSpaceFilterOptimizingThreshold)) {
774    MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kNotCompiledSpaceFilter);
775    return nullptr;
776  }
777
778  CodeItemDebugInfoAccessor code_item_accessor(dex_file, code_item, method_idx);
779  HGraph* graph = new (allocator) HGraph(
780      allocator,
781      arena_stack,
782      dex_file,
783      method_idx,
784      compiler_driver->GetInstructionSet(),
785      kInvalidInvokeType,
786      compiler_driver->GetCompilerOptions().GetDebuggable(),
787      osr);
788
789  ArrayRef<const uint8_t> interpreter_metadata;
790  // For AOT compilation, we may not get a method, for example if its class is erroneous.
791  // JIT should always have a method.
792  DCHECK(Runtime::Current()->IsAotCompiler() || method != nullptr);
793  if (method != nullptr) {
794    graph->SetArtMethod(method);
795    ScopedObjectAccess soa(Thread::Current());
796    interpreter_metadata = method->GetQuickenedInfo();
797  }
798
799  std::unique_ptr<CodeGenerator> codegen(
800      CodeGenerator::Create(graph,
801                            instruction_set,
802                            *compiler_driver->GetInstructionSetFeatures(),
803                            compiler_driver->GetCompilerOptions(),
804                            compilation_stats_.get()));
805  if (codegen.get() == nullptr) {
806    MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kNotCompiledNoCodegen);
807    return nullptr;
808  }
809  codegen->GetAssembler()->cfi().SetEnabled(
810      compiler_driver->GetCompilerOptions().GenerateAnyDebugInfo());
811
812  PassObserver pass_observer(graph,
813                             codegen.get(),
814                             visualizer_output_.get(),
815                             compiler_driver,
816                             dump_mutex_);
817
818  {
819    VLOG(compiler) << "Building " << pass_observer.GetMethodName();
820    PassScope scope(HGraphBuilder::kBuilderPassName, &pass_observer);
821    HGraphBuilder builder(graph,
822                          code_item_accessor,
823                          &dex_compilation_unit,
824                          &dex_compilation_unit,
825                          compiler_driver,
826                          codegen.get(),
827                          compilation_stats_.get(),
828                          interpreter_metadata,
829                          handles);
830    GraphAnalysisResult result = builder.BuildGraph();
831    if (result != kAnalysisSuccess) {
832      switch (result) {
833        case kAnalysisSkipped: {
834          MaybeRecordStat(compilation_stats_.get(),
835                          MethodCompilationStat::kNotCompiledSkipped);
836        }
837          break;
838        case kAnalysisInvalidBytecode: {
839          MaybeRecordStat(compilation_stats_.get(),
840                          MethodCompilationStat::kNotCompiledInvalidBytecode);
841        }
842          break;
843        case kAnalysisFailThrowCatchLoop: {
844          MaybeRecordStat(compilation_stats_.get(),
845                          MethodCompilationStat::kNotCompiledThrowCatchLoop);
846        }
847          break;
848        case kAnalysisFailAmbiguousArrayOp: {
849          MaybeRecordStat(compilation_stats_.get(),
850                          MethodCompilationStat::kNotCompiledAmbiguousArrayOp);
851        }
852          break;
853        case kAnalysisSuccess:
854          UNREACHABLE();
855      }
856      pass_observer.SetGraphInBadState();
857      return nullptr;
858    }
859  }
860
861  RunOptimizations(graph,
862                   codegen.get(),
863                   dex_compilation_unit,
864                   &pass_observer,
865                   handles);
866
867  RegisterAllocator::Strategy regalloc_strategy =
868    compiler_options.GetRegisterAllocationStrategy();
869  AllocateRegisters(graph,
870                    codegen.get(),
871                    &pass_observer,
872                    regalloc_strategy,
873                    compilation_stats_.get());
874
875  codegen->Compile(code_allocator);
876  pass_observer.DumpDisassembly();
877
878  MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kCompiledBytecode);
879  return codegen.release();
880}
881
882CodeGenerator* OptimizingCompiler::TryCompileIntrinsic(
883    ArenaAllocator* allocator,
884    ArenaStack* arena_stack,
885    CodeVectorAllocator* code_allocator,
886    const DexCompilationUnit& dex_compilation_unit,
887    ArtMethod* method,
888    VariableSizedHandleScope* handles) const {
889  MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kAttemptIntrinsicCompilation);
890  CompilerDriver* compiler_driver = GetCompilerDriver();
891  InstructionSet instruction_set = compiler_driver->GetInstructionSet();
892  const DexFile& dex_file = *dex_compilation_unit.GetDexFile();
893  uint32_t method_idx = dex_compilation_unit.GetDexMethodIndex();
894
895  // Always use the Thumb-2 assembler: some runtime functionality
896  // (like implicit stack overflow checks) assume Thumb-2.
897  DCHECK_NE(instruction_set, InstructionSet::kArm);
898
899  // Do not attempt to compile on architectures we do not support.
900  if (!IsInstructionSetSupported(instruction_set)) {
901    return nullptr;
902  }
903
904  HGraph* graph = new (allocator) HGraph(
905      allocator,
906      arena_stack,
907      dex_file,
908      method_idx,
909      compiler_driver->GetInstructionSet(),
910      kInvalidInvokeType,
911      compiler_driver->GetCompilerOptions().GetDebuggable(),
912      /* osr */ false);
913
914  DCHECK(Runtime::Current()->IsAotCompiler());
915  DCHECK(method != nullptr);
916  graph->SetArtMethod(method);
917
918  std::unique_ptr<CodeGenerator> codegen(
919      CodeGenerator::Create(graph,
920                            instruction_set,
921                            *compiler_driver->GetInstructionSetFeatures(),
922                            compiler_driver->GetCompilerOptions(),
923                            compilation_stats_.get()));
924  if (codegen.get() == nullptr) {
925    return nullptr;
926  }
927  codegen->GetAssembler()->cfi().SetEnabled(
928      compiler_driver->GetCompilerOptions().GenerateAnyDebugInfo());
929
930  PassObserver pass_observer(graph,
931                             codegen.get(),
932                             visualizer_output_.get(),
933                             compiler_driver,
934                             dump_mutex_);
935
936  {
937    VLOG(compiler) << "Building intrinsic graph " << pass_observer.GetMethodName();
938    PassScope scope(HGraphBuilder::kBuilderPassName, &pass_observer);
939    HGraphBuilder builder(graph,
940                          CodeItemDebugInfoAccessor(),  // Null code item.
941                          &dex_compilation_unit,
942                          &dex_compilation_unit,
943                          compiler_driver,
944                          codegen.get(),
945                          compilation_stats_.get(),
946                          /* interpreter_metadata */ ArrayRef<const uint8_t>(),
947                          handles);
948    builder.BuildIntrinsicGraph(method);
949  }
950
951  OptimizationDef optimizations[] = {
952    OptDef(OptimizationPass::kIntrinsicsRecognizer),
953    // Some intrinsics are converted to HIR by the simplifier and the codegen also
954    // has a few assumptions that only the instruction simplifier can satisfy.
955    OptDef(OptimizationPass::kInstructionSimplifier),
956  };
957  RunOptimizations(graph,
958                   codegen.get(),
959                   dex_compilation_unit,
960                   &pass_observer,
961                   handles,
962                   optimizations);
963
964  RunArchOptimizations(graph, codegen.get(), dex_compilation_unit, &pass_observer, handles);
965
966  AllocateRegisters(graph,
967                    codegen.get(),
968                    &pass_observer,
969                    compiler_driver->GetCompilerOptions().GetRegisterAllocationStrategy(),
970                    compilation_stats_.get());
971  if (!codegen->IsLeafMethod()) {
972    VLOG(compiler) << "Intrinsic method is not leaf: " << method->GetIntrinsic()
973        << " " << graph->PrettyMethod();
974    return nullptr;
975  }
976
977  codegen->Compile(code_allocator);
978  pass_observer.DumpDisassembly();
979
980  VLOG(compiler) << "Compiled intrinsic: " << method->GetIntrinsic()
981      << " " << graph->PrettyMethod();
982  MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kCompiledIntrinsic);
983  return codegen.release();
984}
985
986CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item,
987                                            uint32_t access_flags,
988                                            InvokeType invoke_type,
989                                            uint16_t class_def_idx,
990                                            uint32_t method_idx,
991                                            Handle<mirror::ClassLoader> jclass_loader,
992                                            const DexFile& dex_file,
993                                            Handle<mirror::DexCache> dex_cache) const {
994  CompilerDriver* compiler_driver = GetCompilerDriver();
995  CompiledMethod* compiled_method = nullptr;
996  Runtime* runtime = Runtime::Current();
997  DCHECK(runtime->IsAotCompiler());
998  const VerifiedMethod* verified_method = compiler_driver->GetVerifiedMethod(&dex_file, method_idx);
999  DCHECK(!verified_method->HasRuntimeThrow());
1000  if (compiler_driver->IsMethodVerifiedWithoutFailures(method_idx, class_def_idx, dex_file) ||
1001      verifier::CanCompilerHandleVerificationFailure(
1002          verified_method->GetEncounteredVerificationFailures())) {
1003    ArenaAllocator allocator(runtime->GetArenaPool());
1004    ArenaStack arena_stack(runtime->GetArenaPool());
1005    CodeVectorAllocator code_allocator(&allocator);
1006    std::unique_ptr<CodeGenerator> codegen;
1007    bool compiled_intrinsic = false;
1008    {
1009      DexCompilationUnit dex_compilation_unit(
1010          jclass_loader,
1011          runtime->GetClassLinker(),
1012          dex_file,
1013          code_item,
1014          class_def_idx,
1015          method_idx,
1016          access_flags,
1017          /* verified_method */ nullptr,  // Not needed by the Optimizing compiler.
1018          dex_cache);
1019      ScopedObjectAccess soa(Thread::Current());
1020      ArtMethod* method = compiler_driver->ResolveMethod(
1021            soa, dex_cache, jclass_loader, &dex_compilation_unit, method_idx, invoke_type);
1022      VariableSizedHandleScope handles(soa.Self());
1023      // Go to native so that we don't block GC during compilation.
1024      ScopedThreadSuspension sts(soa.Self(), kNative);
1025      if (method != nullptr && UNLIKELY(method->IsIntrinsic())) {
1026        DCHECK(compiler_driver->GetCompilerOptions().IsBootImage());
1027        codegen.reset(
1028            TryCompileIntrinsic(&allocator,
1029                                &arena_stack,
1030                                &code_allocator,
1031                                dex_compilation_unit,
1032                                method,
1033                                &handles));
1034        if (codegen != nullptr) {
1035          compiled_intrinsic = true;
1036        }
1037      }
1038      if (codegen == nullptr) {
1039        codegen.reset(
1040            TryCompile(&allocator,
1041                       &arena_stack,
1042                       &code_allocator,
1043                       dex_compilation_unit,
1044                       method,
1045                       /* osr */ false,
1046                       &handles));
1047      }
1048    }
1049    if (codegen.get() != nullptr) {
1050      compiled_method = Emit(&allocator,
1051                             &code_allocator,
1052                             codegen.get(),
1053                             compiled_intrinsic ? nullptr : code_item);
1054      if (compiled_intrinsic) {
1055        compiled_method->MarkAsIntrinsic();
1056      }
1057
1058      if (kArenaAllocatorCountAllocations) {
1059        codegen.reset();  // Release codegen's ScopedArenaAllocator for memory accounting.
1060        size_t total_allocated = allocator.BytesAllocated() + arena_stack.PeakBytesAllocated();
1061        if (total_allocated > kArenaAllocatorMemoryReportThreshold) {
1062          MemStats mem_stats(allocator.GetMemStats());
1063          MemStats peak_stats(arena_stack.GetPeakStats());
1064          LOG(INFO) << "Used " << total_allocated << " bytes of arena memory for compiling "
1065                    << dex_file.PrettyMethod(method_idx)
1066                    << "\n" << Dumpable<MemStats>(mem_stats)
1067                    << "\n" << Dumpable<MemStats>(peak_stats);
1068        }
1069      }
1070    }
1071  } else {
1072    MethodCompilationStat method_stat;
1073    if (compiler_driver->GetCompilerOptions().VerifyAtRuntime()) {
1074      method_stat = MethodCompilationStat::kNotCompiledVerifyAtRuntime;
1075    } else {
1076      method_stat = MethodCompilationStat::kNotCompiledVerificationError;
1077    }
1078    MaybeRecordStat(compilation_stats_.get(), method_stat);
1079  }
1080
1081  if (kIsDebugBuild &&
1082      IsCompilingWithCoreImage() &&
1083      IsInstructionSetSupported(compiler_driver->GetInstructionSet())) {
1084    // For testing purposes, we put a special marker on method names
1085    // that should be compiled with this compiler (when the
1086    // instruction set is supported). This makes sure we're not
1087    // regressing.
1088    std::string method_name = dex_file.PrettyMethod(method_idx);
1089    bool shouldCompile = method_name.find("$opt$") != std::string::npos;
1090    DCHECK((compiled_method != nullptr) || !shouldCompile) << "Didn't compile " << method_name;
1091  }
1092
1093  return compiled_method;
1094}
1095
1096CompiledMethod* OptimizingCompiler::JniCompile(uint32_t access_flags,
1097                                               uint32_t method_idx,
1098                                               const DexFile& dex_file,
1099                                               Handle<mirror::DexCache> dex_cache) const {
1100  if (GetCompilerDriver()->GetCompilerOptions().IsBootImage()) {
1101    ScopedObjectAccess soa(Thread::Current());
1102    Runtime* runtime = Runtime::Current();
1103    ArtMethod* method = runtime->GetClassLinker()->LookupResolvedMethod(
1104        method_idx, dex_cache.Get(), /* class_loader */ nullptr);
1105    if (method != nullptr && UNLIKELY(method->IsIntrinsic())) {
1106      ScopedNullHandle<mirror::ClassLoader> class_loader;  // null means boot class path loader.
1107      DexCompilationUnit dex_compilation_unit(
1108          class_loader,
1109          runtime->GetClassLinker(),
1110          dex_file,
1111          /* code_item */ nullptr,
1112          /* class_def_idx */ DexFile::kDexNoIndex16,
1113          method_idx,
1114          access_flags,
1115          /* verified_method */ nullptr,
1116          dex_cache);
1117      ArenaAllocator allocator(runtime->GetArenaPool());
1118      ArenaStack arena_stack(runtime->GetArenaPool());
1119      CodeVectorAllocator code_allocator(&allocator);
1120      VariableSizedHandleScope handles(soa.Self());
1121      // Go to native so that we don't block GC during compilation.
1122      ScopedThreadSuspension sts(soa.Self(), kNative);
1123      std::unique_ptr<CodeGenerator> codegen(
1124          TryCompileIntrinsic(&allocator,
1125                              &arena_stack,
1126                              &code_allocator,
1127                              dex_compilation_unit,
1128                              method,
1129                              &handles));
1130      if (codegen != nullptr) {
1131        CompiledMethod* compiled_method = Emit(&allocator,
1132                                               &code_allocator,
1133                                               codegen.get(),
1134                                               /* code_item_for_osr_check */ nullptr);
1135        compiled_method->MarkAsIntrinsic();
1136        return compiled_method;
1137      }
1138    }
1139  }
1140
1141  JniCompiledMethod jni_compiled_method = ArtQuickJniCompileMethod(
1142      GetCompilerDriver(), access_flags, method_idx, dex_file);
1143  MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kCompiledNativeStub);
1144  return CompiledMethod::SwapAllocCompiledMethod(
1145      GetCompilerDriver(),
1146      jni_compiled_method.GetInstructionSet(),
1147      jni_compiled_method.GetCode(),
1148      jni_compiled_method.GetFrameSize(),
1149      jni_compiled_method.GetCoreSpillMask(),
1150      jni_compiled_method.GetFpSpillMask(),
1151      /* method_info */ ArrayRef<const uint8_t>(),
1152      /* vmap_table */ ArrayRef<const uint8_t>(),
1153      jni_compiled_method.GetCfi(),
1154      /* patches */ ArrayRef<const linker::LinkerPatch>());
1155}
1156
1157Compiler* CreateOptimizingCompiler(CompilerDriver* driver) {
1158  return new OptimizingCompiler(driver);
1159}
1160
1161bool IsCompilingWithCoreImage() {
1162  const std::string& image = Runtime::Current()->GetImageLocation();
1163  return CompilerDriver::IsCoreImageFilename(image);
1164}
1165
1166bool EncodeArtMethodInInlineInfo(ArtMethod* method ATTRIBUTE_UNUSED) {
1167  // Note: the runtime is null only for unit testing.
1168  return Runtime::Current() == nullptr || !Runtime::Current()->IsAotCompiler();
1169}
1170
1171bool CanEncodeInlinedMethodInStackMap(const DexFile& caller_dex_file, ArtMethod* callee) {
1172  if (!Runtime::Current()->IsAotCompiler()) {
1173    // JIT can always encode methods in stack maps.
1174    return true;
1175  }
1176  if (IsSameDexFile(caller_dex_file, *callee->GetDexFile())) {
1177    return true;
1178  }
1179  // TODO(ngeoffray): Support more AOT cases for inlining:
1180  // - methods in multidex
1181  // - methods in boot image for on-device non-PIC compilation.
1182  return false;
1183}
1184
1185bool OptimizingCompiler::JitCompile(Thread* self,
1186                                    jit::JitCodeCache* code_cache,
1187                                    ArtMethod* method,
1188                                    bool osr,
1189                                    jit::JitLogger* jit_logger) {
1190  StackHandleScope<3> hs(self);
1191  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
1192      method->GetDeclaringClass()->GetClassLoader()));
1193  Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
1194  DCHECK(method->IsCompilable());
1195
1196  const DexFile* dex_file = method->GetDexFile();
1197  const uint16_t class_def_idx = method->GetClassDefIndex();
1198  const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
1199  const uint32_t method_idx = method->GetDexMethodIndex();
1200  const uint32_t access_flags = method->GetAccessFlags();
1201
1202  Runtime* runtime = Runtime::Current();
1203  ArenaAllocator allocator(runtime->GetJitArenaPool());
1204
1205  if (UNLIKELY(method->IsNative())) {
1206    JniCompiledMethod jni_compiled_method = ArtQuickJniCompileMethod(
1207        GetCompilerDriver(), access_flags, method_idx, *dex_file);
1208    ScopedNullHandle<mirror::ObjectArray<mirror::Object>> roots;
1209    ArenaSet<ArtMethod*, std::less<ArtMethod*>> cha_single_implementation_list(
1210        allocator.Adapter(kArenaAllocCHA));
1211    const void* code = code_cache->CommitCode(
1212        self,
1213        method,
1214        /* stack_map_data */ nullptr,
1215        /* method_info_data */ nullptr,
1216        /* roots_data */ nullptr,
1217        jni_compiled_method.GetFrameSize(),
1218        jni_compiled_method.GetCoreSpillMask(),
1219        jni_compiled_method.GetFpSpillMask(),
1220        jni_compiled_method.GetCode().data(),
1221        jni_compiled_method.GetCode().size(),
1222        /* data_size */ 0u,
1223        osr,
1224        roots,
1225        /* has_should_deoptimize_flag */ false,
1226        cha_single_implementation_list);
1227    if (code == nullptr) {
1228      return false;
1229    }
1230
1231    const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
1232    if (compiler_options.GenerateAnyDebugInfo()) {
1233      const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
1234      const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
1235      debug::MethodDebugInfo info = {};
1236      DCHECK(info.custom_name.empty());
1237      info.dex_file = dex_file;
1238      info.class_def_index = class_def_idx;
1239      info.dex_method_index = method_idx;
1240      info.access_flags = access_flags;
1241      info.code_item = code_item;
1242      info.isa = jni_compiled_method.GetInstructionSet();
1243      info.deduped = false;
1244      info.is_native_debuggable = compiler_options.GetNativeDebuggable();
1245      info.is_optimized = true;
1246      info.is_code_address_text_relative = false;
1247      info.code_address = code_address;
1248      info.code_size = jni_compiled_method.GetCode().size();
1249      info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
1250      info.code_info = nullptr;
1251      info.cfi = jni_compiled_method.GetCfi();
1252      GenerateJitDebugInfo(method, info);
1253    }
1254
1255    Runtime::Current()->GetJit()->AddMemoryUsage(method, allocator.BytesUsed());
1256    if (jit_logger != nullptr) {
1257      jit_logger->WriteLog(code, jni_compiled_method.GetCode().size(), method);
1258    }
1259    return true;
1260  }
1261
1262  ArenaStack arena_stack(runtime->GetJitArenaPool());
1263  CodeVectorAllocator code_allocator(&allocator);
1264  VariableSizedHandleScope handles(self);
1265
1266  std::unique_ptr<CodeGenerator> codegen;
1267  {
1268    DexCompilationUnit dex_compilation_unit(
1269        class_loader,
1270        runtime->GetClassLinker(),
1271        *dex_file,
1272        code_item,
1273        class_def_idx,
1274        method_idx,
1275        access_flags,
1276        /* verified_method */ nullptr,
1277        dex_cache);
1278
1279    // Go to native so that we don't block GC during compilation.
1280    ScopedThreadSuspension sts(self, kNative);
1281    codegen.reset(
1282        TryCompile(&allocator,
1283                   &arena_stack,
1284                   &code_allocator,
1285                   dex_compilation_unit,
1286                   method,
1287                   osr,
1288                   &handles));
1289    if (codegen.get() == nullptr) {
1290      return false;
1291    }
1292  }
1293
1294  size_t stack_map_size = 0;
1295  size_t method_info_size = 0;
1296  codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size);
1297  size_t number_of_roots = codegen->GetNumberOfJitRoots();
1298  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1299  // We allocate an object array to ensure the JIT roots that we will collect in EmitJitRoots
1300  // will be visible by the GC between EmitLiterals and CommitCode. Once CommitCode is
1301  // executed, this array is not needed.
1302  Handle<mirror::ObjectArray<mirror::Object>> roots(
1303      hs.NewHandle(mirror::ObjectArray<mirror::Object>::Alloc(
1304          self, class_linker->GetClassRoot(ClassLinker::kObjectArrayClass), number_of_roots)));
1305  if (roots == nullptr) {
1306    // Out of memory, just clear the exception to avoid any Java exception uncaught problems.
1307    MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kJitOutOfMemoryForCommit);
1308    DCHECK(self->IsExceptionPending());
1309    self->ClearException();
1310    return false;
1311  }
1312  uint8_t* stack_map_data = nullptr;
1313  uint8_t* method_info_data = nullptr;
1314  uint8_t* roots_data = nullptr;
1315  uint32_t data_size = code_cache->ReserveData(self,
1316                                               stack_map_size,
1317                                               method_info_size,
1318                                               number_of_roots,
1319                                               method,
1320                                               &stack_map_data,
1321                                               &method_info_data,
1322                                               &roots_data);
1323  if (stack_map_data == nullptr || roots_data == nullptr) {
1324    MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kJitOutOfMemoryForCommit);
1325    return false;
1326  }
1327  codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size),
1328                          MemoryRegion(method_info_data, method_info_size),
1329                          code_item);
1330  codegen->EmitJitRoots(code_allocator.GetData(), roots, roots_data);
1331
1332  const void* code = code_cache->CommitCode(
1333      self,
1334      method,
1335      stack_map_data,
1336      method_info_data,
1337      roots_data,
1338      codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
1339      codegen->GetCoreSpillMask(),
1340      codegen->GetFpuSpillMask(),
1341      code_allocator.GetMemory().data(),
1342      code_allocator.GetSize(),
1343      data_size,
1344      osr,
1345      roots,
1346      codegen->GetGraph()->HasShouldDeoptimizeFlag(),
1347      codegen->GetGraph()->GetCHASingleImplementationList());
1348
1349  if (code == nullptr) {
1350    MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kJitOutOfMemoryForCommit);
1351    code_cache->ClearData(self, stack_map_data, roots_data);
1352    return false;
1353  }
1354
1355  const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
1356  if (compiler_options.GenerateAnyDebugInfo()) {
1357    const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
1358    const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
1359    debug::MethodDebugInfo info = {};
1360    DCHECK(info.custom_name.empty());
1361    info.dex_file = dex_file;
1362    info.class_def_index = class_def_idx;
1363    info.dex_method_index = method_idx;
1364    info.access_flags = access_flags;
1365    info.code_item = code_item;
1366    info.isa = codegen->GetInstructionSet();
1367    info.deduped = false;
1368    info.is_native_debuggable = compiler_options.GetNativeDebuggable();
1369    info.is_optimized = true;
1370    info.is_code_address_text_relative = false;
1371    info.code_address = code_address;
1372    info.code_size = code_allocator.GetSize();
1373    info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
1374    info.code_info = stack_map_size == 0 ? nullptr : stack_map_data;
1375    info.cfi = ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data());
1376    GenerateJitDebugInfo(method, info);
1377  }
1378
1379  Runtime::Current()->GetJit()->AddMemoryUsage(method, allocator.BytesUsed());
1380  if (jit_logger != nullptr) {
1381    jit_logger->WriteLog(code, code_allocator.GetSize(), method);
1382  }
1383
1384  if (kArenaAllocatorCountAllocations) {
1385    codegen.reset();  // Release codegen's ScopedArenaAllocator for memory accounting.
1386    size_t total_allocated = allocator.BytesAllocated() + arena_stack.PeakBytesAllocated();
1387    if (total_allocated > kArenaAllocatorMemoryReportThreshold) {
1388      MemStats mem_stats(allocator.GetMemStats());
1389      MemStats peak_stats(arena_stack.GetPeakStats());
1390      LOG(INFO) << "Used " << total_allocated << " bytes of arena memory for compiling "
1391                << dex_file->PrettyMethod(method_idx)
1392                << "\n" << Dumpable<MemStats>(mem_stats)
1393                << "\n" << Dumpable<MemStats>(peak_stats);
1394    }
1395  }
1396
1397  return true;
1398}
1399
1400void OptimizingCompiler::GenerateJitDebugInfo(ArtMethod* method, debug::MethodDebugInfo info) {
1401  const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
1402  DCHECK(compiler_options.GenerateAnyDebugInfo());
1403
1404  // If both flags are passed, generate full debug info.
1405  const bool mini_debug_info = !compiler_options.GetGenerateDebugInfo();
1406
1407  // Create entry for the single method that we just compiled.
1408  std::vector<uint8_t> elf_file = debug::MakeElfFileForJIT(
1409      GetCompilerDriver()->GetInstructionSet(),
1410      GetCompilerDriver()->GetInstructionSetFeatures(),
1411      mini_debug_info,
1412      ArrayRef<const debug::MethodDebugInfo>(&info, 1));
1413  MutexLock mu(Thread::Current(), *Locks::native_debug_interface_lock_);
1414  AddNativeDebugInfoForJit(reinterpret_cast<const void*>(info.code_address), elf_file);
1415
1416  VLOG(jit)
1417      << "JIT mini-debug-info added for " << ArtMethod::PrettyMethod(method)
1418      << " size=" << PrettySize(elf_file.size())
1419      << " total_size=" << PrettySize(GetJitNativeDebugInfoMemUsage());
1420}
1421
1422}  // namespace art
1423