1e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier/*
2e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * Copyright 2014 The Android Open Source Project
3e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *
4e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
5e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * you may not use this file except in compliance with the License.
6e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * You may obtain a copy of the License at
7e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *
8e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
9e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *
10e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * Unless required by applicable law or agreed to in writing, software
11e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
12e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * See the License for the specific language governing permissions and
14e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * limitations under the License.
15e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier */
16e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
17e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "jit_compiler.h"
18e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
19e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "arch/instruction_set.h"
20e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "arch/instruction_set_features.h"
214fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "art_method-inl.h"
22085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier#include "base/stringpiece.h"
2380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/time_utils.h"
24a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier#include "base/timing_logger.h"
25a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#include "base/unix_file/fd_file.h"
26c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_debug_writer.h"
27e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "driver/compiler_driver.h"
28e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "driver/compiler_options.h"
29160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer#include "jit/debugger_interface.h"
30e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "jit/jit.h"
31e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "jit/jit_code_cache.h"
32e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "oat_file-inl.h"
33524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02Nicolas Geoffray#include "oat_quick_method_header.h"
34e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "object_lock.h"
35e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "thread_list.h"
36e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
37e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiernamespace art {
38e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiernamespace jit {
39e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
40e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJitCompiler* JitCompiler::Create() {
41e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  return new JitCompiler();
42e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
43e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
445b82d339955d1a0dc23eeb8d2d5659459ff987baNicolas Geoffrayextern "C" void* jit_load(bool* generate_debug_info) {
45e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  VLOG(jit) << "loading jit compiler";
46e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  auto* const jit_compiler = JitCompiler::Create();
47e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  CHECK(jit_compiler != nullptr);
48a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  *generate_debug_info = jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo();
49e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  VLOG(jit) << "Done loading jit compiler";
50e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  return jit_compiler;
51e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
52e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
53e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartierextern "C" void jit_unload(void* handle) {
54e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  DCHECK(handle != nullptr);
55e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  delete reinterpret_cast<JitCompiler*>(handle);
56e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
57e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
58b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffrayextern "C" bool jit_compile_method(
59b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray    void* handle, ArtMethod* method, Thread* self, bool osr)
6090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
61e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
62e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  DCHECK(jit_compiler != nullptr);
63b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray  return jit_compiler->CompileMethod(self, method, osr);
64e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
65e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
66fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammerextern "C" void jit_types_loaded(void* handle, mirror::Class** types, size_t count)
67160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer    SHARED_REQUIRES(Locks::mutator_lock_) {
68160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer  auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
69160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer  DCHECK(jit_compiler != nullptr);
70160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer  if (jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo()) {
71fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer    const ArrayRef<mirror::Class*> types_array(types, count);
72d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko    std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForClasses(
735d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky        kRuntimeISA, jit_compiler->GetCompilerDriver()->GetInstructionSetFeatures(), types_array);
74d1ee80948144526b985afb44a0574248cf7da58aVladimir Marko    CreateJITCodeEntry(std::move(elf_file));
75160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer  }
76160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer}
77160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer
78abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray// Callers of this method assume it has NO_RETURN.
79abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas GeoffrayNO_RETURN static void Usage(const char* fmt, ...) {
80abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  va_list ap;
81abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  va_start(ap, fmt);
82abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  std::string error;
83abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  StringAppendV(&error, fmt, ap);
84abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  LOG(FATAL) << error;
85abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  va_end(ap);
86abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  exit(EXIT_FAILURE);
87abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray}
88abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray
89bcd94c8ea9bde4e075c25fbdfb3a2ef6858eed7bNicolas GeoffrayJitCompiler::JitCompiler() {
90e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_options_.reset(new CompilerOptions(
91e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultCompilerFilter,
92e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultHugeMethodThreshold,
93e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultLargeMethodThreshold,
94e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultSmallMethodThreshold,
95e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultTinyMethodThreshold,
96e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultNumDexMethodsThreshold,
97ec74835a7e4f2660250a2f3f9508cbbe5269e49aCalin Juravle      CompilerOptions::kDefaultInlineDepthLimit,
98ec74835a7e4f2660250a2f3f9508cbbe5269e49aCalin Juravle      CompilerOptions::kDefaultInlineMaxCodeUnits,
99dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao      /* no_inline_from */ nullptr,
1007a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* include_patch_information */ false,
101e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultTopKProfileThreshold,
1027a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      Runtime::Current()->IsDebuggable(),
1038363c772581bf00ebcdc2e38391b4bfae51beb75David Srbecky      CompilerOptions::kDefaultGenerateDebugInfo,
1047a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* implicit_null_checks */ true,
1057a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* implicit_so_checks */ true,
1067a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* implicit_suspend_checks */ false,
1077a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* pic */ true,  // TODO: Support non-PIC in optimizing.
1087a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* verbose_methods */ nullptr,
1097a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* init_failure_output */ nullptr,
110c903b6af634927479915eaa9516d493eea23f911Nicolas Geoffray      /* abort_on_hard_verifier_failure */ false,
111c903b6af634927479915eaa9516d493eea23f911Nicolas Geoffray      /* dump_cfg_file_name */ "",
112ace0dc1dd5480ad458e622085e51583653853fb9Andreas Gampe      /* dump_cfg_append */ false,
113ace0dc1dd5480ad458e622085e51583653853fb9Andreas Gampe      /* force_determinism */ false));
114abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  for (const std::string& argument : Runtime::Current()->GetCompilerOptions()) {
115abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray    compiler_options_->ParseCompilerOption(argument, Usage);
116abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  }
117e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  const InstructionSet instruction_set = kRuntimeISA;
118085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  for (const StringPiece option : Runtime::Current()->GetCompilerOptions()) {
119085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    VLOG(compiler) << "JIT compiler option " << option;
120085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    std::string error_msg;
121085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    if (option.starts_with("--instruction-set-variant=")) {
122085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      StringPiece str = option.substr(strlen("--instruction-set-variant=")).data();
123085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      VLOG(compiler) << "JIT instruction set variant " << str;
124085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      instruction_set_features_.reset(InstructionSetFeatures::FromVariant(
125085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier          instruction_set, str.as_string(), &error_msg));
126085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      if (instruction_set_features_ == nullptr) {
127085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
128085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      }
129085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    } else if (option.starts_with("--instruction-set-features=")) {
130085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
131085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      VLOG(compiler) << "JIT instruction set features " << str;
132085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      if (instruction_set_features_.get() == nullptr) {
133085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        instruction_set_features_.reset(InstructionSetFeatures::FromVariant(
134085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier            instruction_set, "default", &error_msg));
135085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        if (instruction_set_features_ == nullptr) {
136085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier          LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
137085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        }
138085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      }
139085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      instruction_set_features_.reset(
140085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier          instruction_set_features_->AddFeaturesFromString(str.as_string(), &error_msg));
141085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      if (instruction_set_features_ == nullptr) {
142085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
143085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      }
144085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    }
145085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  }
146085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  if (instruction_set_features_ == nullptr) {
147085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines());
148085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  }
149e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  cumulative_logger_.reset(new CumulativeLogger("jit times"));
150e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  method_inliner_map_.reset(new DexFileToMethodInlinerMap);
151e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_driver_.reset(new CompilerDriver(
1527a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      compiler_options_.get(),
1535b82d339955d1a0dc23eeb8d2d5659459ff987baNicolas Geoffray      /* verification_results */ nullptr,
1547a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      method_inliner_map_.get(),
1557a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      Compiler::kOptimizing,
1567a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      instruction_set,
1577a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      instruction_set_features_.get(),
158cdca476bf3394ce9d97a369e84e701b427009318Mathieu Chartier      /* boot_image */ false,
159cdca476bf3394ce9d97a369e84e701b427009318Mathieu Chartier      /* app_image */ false,
1607a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* image_classes */ nullptr,
1617a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* compiled_classes */ nullptr,
1627a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* compiled_methods */ nullptr,
1637a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* thread_count */ 1,
1647a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* dump_stats */ false,
1657a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* dump_passes */ false,
1667a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      cumulative_logger_.get(),
1677a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* swap_fd */ -1,
168998c21661b5074c293cae818d0ab7c44dcda3a66Calin Juravle      /* profile_compilation_info */ nullptr));
169e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  // Disable dedupe so we can remove compiled methods.
170e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_driver_->SetDedupeEnabled(false);
171e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_driver_->SetSupportBootImageFixup(false);
172a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray
173b6e20ae17d0881a66c22532e4152ce6779454a92Nicolas Geoffray  size_t thread_count = compiler_driver_->GetThreadCount();
174a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  if (compiler_options_->GetGenerateDebugInfo()) {
175a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#ifdef __ANDROID__
176f0615a3a8ca649a562e67219ab8b9c6a023f4928Tamas Berghammer    const char* prefix = "/data/misc/trace";
177a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#else
178a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    const char* prefix = "/tmp";
179a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#endif
180b6e20ae17d0881a66c22532e4152ce6779454a92Nicolas Geoffray    DCHECK_EQ(thread_count, 1u)
181a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray        << "Generating debug info only works with one compiler thread";
182a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    std::string perf_filename = std::string(prefix) + "/perf-" + std::to_string(getpid()) + ".map";
183a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    perf_file_.reset(OS::CreateEmptyFileWriteOnly(perf_filename.c_str()));
184a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    if (perf_file_ == nullptr) {
185f0615a3a8ca649a562e67219ab8b9c6a023f4928Tamas Berghammer      LOG(ERROR) << "Could not create perf file at " << perf_filename <<
186f0615a3a8ca649a562e67219ab8b9c6a023f4928Tamas Berghammer                    " Are you on a user build? Perf only works on userdebug/eng builds";
187a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    }
188a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  }
189b6e20ae17d0881a66c22532e4152ce6779454a92Nicolas Geoffray
190b6e20ae17d0881a66c22532e4152ce6779454a92Nicolas Geoffray  size_t inline_depth_limit = compiler_driver_->GetCompilerOptions().GetInlineDepthLimit();
191b6e20ae17d0881a66c22532e4152ce6779454a92Nicolas Geoffray  DCHECK_LT(thread_count * inline_depth_limit, std::numeric_limits<uint16_t>::max())
192b6e20ae17d0881a66c22532e4152ce6779454a92Nicolas Geoffray      << "ProfilingInfo's inline counter can potentially overflow";
193e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
194e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
195e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJitCompiler::~JitCompiler() {
196a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  if (perf_file_ != nullptr) {
197a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    UNUSED(perf_file_->Flush());
198a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    UNUSED(perf_file_->Close());
199a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  }
200e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
201e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
202b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffraybool JitCompiler::CompileMethod(Thread* self, ArtMethod* method, bool osr) {
203d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray  DCHECK(!method->IsProxyMethod());
204a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  TimingLogger logger("JIT compiler timing logger", true, VLOG_IS_ON(jit));
205e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  StackHandleScope<2> hs(self);
206e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  self->AssertNoPendingException();
207e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  Runtime* runtime = Runtime::Current();
2080c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
2090c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  // Ensure the class is initialized.
2100c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
2110c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
2120c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray    VLOG(jit) << "JIT failed to initialize " << PrettyMethod(method);
2130c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray    return false;
214e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  }
2150c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
2160c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  // Do the compilation.
217d28b969c273ab777ca9b147b87fcef671b4f695fNicolas Geoffray  bool success = false;
218a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  {
219a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier    TimingLogger::ScopedTiming t2("Compiling", &logger);
22073be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    JitCodeCache* const code_cache = runtime->GetJit()->GetCodeCache();
221d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray    success = compiler_driver_->GetCompiler()->JitCompile(self, code_cache, method, osr);
222b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray    if (success && (perf_file_ != nullptr)) {
223d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray      const void* ptr = method->GetEntryPointFromQuickCompiledCode();
224a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      std::ostringstream stream;
225a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      stream << std::hex
226a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << reinterpret_cast<uintptr_t>(ptr)
227a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << " "
228a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << code_cache->GetMemorySizeOfCodePointer(ptr)
229a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << " "
230d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray             << PrettyMethod(method)
231a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << std::endl;
232a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      std::string str = stream.str();
233a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      bool res = perf_file_->WriteFully(str.c_str(), str.size());
234a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      CHECK(res);
235a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    }
236a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  }
2370c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
2380c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  // Trim maps to reduce memory usage.
23925e0456b6ea13eba290b63ea88b6b7120ed89413Nicolas Geoffray  // TODO: move this to an idle phase.
240a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  {
241a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier    TimingLogger::ScopedTiming t2("TrimMaps", &logger);
24225e0456b6ea13eba290b63ea88b6b7120ed89413Nicolas Geoffray    runtime->GetJitArenaPool()->TrimMaps();
243a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  }
2440c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
245a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  runtime->GetJit()->AddTimingLogger(logger);
246d28b969c273ab777ca9b147b87fcef671b4f695fNicolas Geoffray  return success;
247e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
248e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
249e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}  // namespace jit
250e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}  // namespace art
251