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