jit_compiler.cc revision bcd94c8ea9bde4e075c25fbdfb3a2ef6858eed7b
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);
72c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky    ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForClasses(kRuntimeISA, types_array);
73160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer    CreateJITCodeEntry(std::unique_ptr<const uint8_t[]>(elf_file.data()), elf_file.size());
74160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer  }
75160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer}
76160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer
77abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray// Callers of this method assume it has NO_RETURN.
78abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas GeoffrayNO_RETURN static void Usage(const char* fmt, ...) {
79abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  va_list ap;
80abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  va_start(ap, fmt);
81abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  std::string error;
82abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  StringAppendV(&error, fmt, ap);
83abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  LOG(FATAL) << error;
84abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  va_end(ap);
85abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  exit(EXIT_FAILURE);
86abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray}
87abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray
88bcd94c8ea9bde4e075c25fbdfb3a2ef6858eed7bNicolas GeoffrayJitCompiler::JitCompiler() {
89e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_options_.reset(new CompilerOptions(
90e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultCompilerFilter,
91e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultHugeMethodThreshold,
92e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultLargeMethodThreshold,
93e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultSmallMethodThreshold,
94e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultTinyMethodThreshold,
95e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultNumDexMethodsThreshold,
96ec74835a7e4f2660250a2f3f9508cbbe5269e49aCalin Juravle      CompilerOptions::kDefaultInlineDepthLimit,
97ec74835a7e4f2660250a2f3f9508cbbe5269e49aCalin Juravle      CompilerOptions::kDefaultInlineMaxCodeUnits,
98dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao      /* no_inline_from */ nullptr,
997a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* include_patch_information */ false,
100e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      CompilerOptions::kDefaultTopKProfileThreshold,
1017a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      Runtime::Current()->IsDebuggable(),
1028363c772581bf00ebcdc2e38391b4bfae51beb75David Srbecky      CompilerOptions::kDefaultGenerateDebugInfo,
1037a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* implicit_null_checks */ true,
1047a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* implicit_so_checks */ true,
1057a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* implicit_suspend_checks */ false,
1067a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* pic */ true,  // TODO: Support non-PIC in optimizing.
1077a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* verbose_methods */ nullptr,
1087a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* init_failure_output */ nullptr,
109c903b6af634927479915eaa9516d493eea23f911Nicolas Geoffray      /* abort_on_hard_verifier_failure */ false,
110c903b6af634927479915eaa9516d493eea23f911Nicolas Geoffray      /* dump_cfg_file_name */ "",
111ace0dc1dd5480ad458e622085e51583653853fb9Andreas Gampe      /* dump_cfg_append */ false,
112ace0dc1dd5480ad458e622085e51583653853fb9Andreas Gampe      /* force_determinism */ false));
113abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  for (const std::string& argument : Runtime::Current()->GetCompilerOptions()) {
114abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray    compiler_options_->ParseCompilerOption(argument, Usage);
115abbb0f76b07417f13f712f54d5afddb72e3b9931Nicolas Geoffray  }
116e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  const InstructionSet instruction_set = kRuntimeISA;
117085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  for (const StringPiece option : Runtime::Current()->GetCompilerOptions()) {
118085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    VLOG(compiler) << "JIT compiler option " << option;
119085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    std::string error_msg;
120085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    if (option.starts_with("--instruction-set-variant=")) {
121085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      StringPiece str = option.substr(strlen("--instruction-set-variant=")).data();
122085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      VLOG(compiler) << "JIT instruction set variant " << str;
123085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      instruction_set_features_.reset(InstructionSetFeatures::FromVariant(
124085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier          instruction_set, str.as_string(), &error_msg));
125085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      if (instruction_set_features_ == nullptr) {
126085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
127085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      }
128085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    } else if (option.starts_with("--instruction-set-features=")) {
129085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
130085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      VLOG(compiler) << "JIT instruction set features " << str;
131085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      if (instruction_set_features_.get() == nullptr) {
132085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        instruction_set_features_.reset(InstructionSetFeatures::FromVariant(
133085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier            instruction_set, "default", &error_msg));
134085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        if (instruction_set_features_ == nullptr) {
135085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier          LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
136085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        }
137085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      }
138085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      instruction_set_features_.reset(
139085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier          instruction_set_features_->AddFeaturesFromString(str.as_string(), &error_msg));
140085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      if (instruction_set_features_ == nullptr) {
141085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier        LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
142085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier      }
143085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    }
144085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  }
145085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  if (instruction_set_features_ == nullptr) {
146085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier    instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines());
147085fc87e7ea42989a4a00cacb0c9c3a6d2590af6Mathieu Chartier  }
148e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  cumulative_logger_.reset(new CumulativeLogger("jit times"));
149e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  method_inliner_map_.reset(new DexFileToMethodInlinerMap);
150e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_driver_.reset(new CompilerDriver(
1517a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      compiler_options_.get(),
1525b82d339955d1a0dc23eeb8d2d5659459ff987baNicolas Geoffray      /* verification_results */ nullptr,
1537a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      method_inliner_map_.get(),
1547a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      Compiler::kOptimizing,
1557a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      instruction_set,
1567a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      instruction_set_features_.get(),
1577a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* image */ false,
1587a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* image_classes */ nullptr,
1597a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* compiled_classes */ nullptr,
1607a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* compiled_methods */ nullptr,
1617a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* thread_count */ 1,
1627a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* dump_stats */ false,
1637a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* dump_passes */ false,
1647a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      cumulative_logger_.get(),
1657a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray      /* swap_fd */ -1,
166998c21661b5074c293cae818d0ab7c44dcda3a66Calin Juravle      /* profile_compilation_info */ nullptr));
167e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  // Disable dedupe so we can remove compiled methods.
168e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_driver_->SetDedupeEnabled(false);
169e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  compiler_driver_->SetSupportBootImageFixup(false);
170a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray
171a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  if (compiler_options_->GetGenerateDebugInfo()) {
172a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#ifdef __ANDROID__
173f0615a3a8ca649a562e67219ab8b9c6a023f4928Tamas Berghammer    const char* prefix = "/data/misc/trace";
174a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#else
175a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    const char* prefix = "/tmp";
176a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray#endif
177a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    DCHECK_EQ(compiler_driver_->GetThreadCount(), 1u)
178a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray        << "Generating debug info only works with one compiler thread";
179a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    std::string perf_filename = std::string(prefix) + "/perf-" + std::to_string(getpid()) + ".map";
180a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    perf_file_.reset(OS::CreateEmptyFileWriteOnly(perf_filename.c_str()));
181a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    if (perf_file_ == nullptr) {
182f0615a3a8ca649a562e67219ab8b9c6a023f4928Tamas Berghammer      LOG(ERROR) << "Could not create perf file at " << perf_filename <<
183f0615a3a8ca649a562e67219ab8b9c6a023f4928Tamas Berghammer                    " Are you on a user build? Perf only works on userdebug/eng builds";
184a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    }
185a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  }
186e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
187e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
188e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJitCompiler::~JitCompiler() {
189a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  if (perf_file_ != nullptr) {
190a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    UNUSED(perf_file_->Flush());
191a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    UNUSED(perf_file_->Close());
192a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray  }
193e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
194e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
195b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffraybool JitCompiler::CompileMethod(Thread* self, ArtMethod* method, bool osr) {
196d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray  DCHECK(!method->IsProxyMethod());
197a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  TimingLogger logger("JIT compiler timing logger", true, VLOG_IS_ON(jit));
198e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  StackHandleScope<2> hs(self);
199e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  self->AssertNoPendingException();
200e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  Runtime* runtime = Runtime::Current();
2010c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
2020c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  // Ensure the class is initialized.
2030c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
2040c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
2050c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray    VLOG(jit) << "JIT failed to initialize " << PrettyMethod(method);
2060c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray    return false;
207e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  }
2080c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
2090c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  // Do the compilation.
210d28b969c273ab777ca9b147b87fcef671b4f695fNicolas Geoffray  bool success = false;
211a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  {
212a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier    TimingLogger::ScopedTiming t2("Compiling", &logger);
21373be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    JitCodeCache* const code_cache = runtime->GetJit()->GetCodeCache();
214d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray    success = compiler_driver_->GetCompiler()->JitCompile(self, code_cache, method, osr);
215b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray    if (success && (perf_file_ != nullptr)) {
216d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray      const void* ptr = method->GetEntryPointFromQuickCompiledCode();
217a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      std::ostringstream stream;
218a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      stream << std::hex
219a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << reinterpret_cast<uintptr_t>(ptr)
220a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << " "
221a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << code_cache->GetMemorySizeOfCodePointer(ptr)
222a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << " "
223d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray             << PrettyMethod(method)
224a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray             << std::endl;
225a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      std::string str = stream.str();
226a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      bool res = perf_file_->WriteFully(str.c_str(), str.size());
227a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray      CHECK(res);
228a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray    }
229a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  }
2300c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
2310c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray  // Trim maps to reduce memory usage.
23225e0456b6ea13eba290b63ea88b6b7120ed89413Nicolas Geoffray  // TODO: move this to an idle phase.
233a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  {
234a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier    TimingLogger::ScopedTiming t2("TrimMaps", &logger);
23525e0456b6ea13eba290b63ea88b6b7120ed89413Nicolas Geoffray    runtime->GetJitArenaPool()->TrimMaps();
236a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  }
2370c3c2668ef44fdbd18d97f9134a85d1a7d561aa4Nicolas Geoffray
238a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier  runtime->GetJit()->AddTimingLogger(logger);
239d28b969c273ab777ca9b147b87fcef671b4f695fNicolas Geoffray  return success;
240e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}
241e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
242e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}  // namespace jit
243e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier}  // namespace art
244