blob: b98c6d39c07ee4f44e6f65f7aad461451d7fabb0 [file] [log] [blame]
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001/*
2 * Copyright 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#ifndef ART_RUNTIME_JIT_JIT_H_
18#define ART_RUNTIME_JIT_JIT_H_
19
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000020#include "base/arena_allocator.h"
21#include "base/histogram-inl.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080022#include "base/macros.h"
23#include "base/mutex.h"
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070024#include "base/timing_logger.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080025#include "object_callbacks.h"
Calin Juravle31f2c152015-10-23 17:56:15 +010026#include "offline_profiling_info.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080027#include "thread_pool.h"
28
29namespace art {
30
Mathieu Chartiere401d142015-04-22 13:56:20 -070031class ArtMethod;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080032struct RuntimeArgumentMap;
33
34namespace jit {
35
36class JitCodeCache;
37class JitInstrumentationCache;
38class JitOptions;
39
40class Jit {
41 public:
42 static constexpr bool kStressMode = kIsDebugBuild;
Nicolas Geoffray83f080a2016-03-08 16:50:21 +000043 static constexpr size_t kDefaultCompileThreshold = kStressMode ? 2 : 10000;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080044
45 virtual ~Jit();
46 static Jit* Create(JitOptions* options, std::string* error_msg);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000047 bool CompileMethod(ArtMethod* method, Thread* self, bool osr)
Mathieu Chartier90443472015-07-16 20:32:27 -070048 SHARED_REQUIRES(Locks::mutator_lock_);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000049 void CreateInstrumentationCache(size_t compile_threshold,
50 size_t warmup_threshold,
51 size_t osr_threshold);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080052 void CreateThreadPool();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080053 const JitCodeCache* GetCodeCache() const {
54 return code_cache_.get();
55 }
56 JitCodeCache* GetCodeCache() {
57 return code_cache_.get();
58 }
59 void DeleteThreadPool();
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070060 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
61 // loggers.
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000062 void DumpInfo(std::ostream& os) REQUIRES(!lock_);
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070063 // Add a timing logger to cumulative_timings_.
64 void AddTimingLogger(const TimingLogger& logger);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000065
66 void AddMemoryUsage(ArtMethod* method, size_t bytes)
67 REQUIRES(!lock_)
68 SHARED_REQUIRES(Locks::mutator_lock_);
69
Mathieu Chartiera50f9cf2015-09-25 11:34:45 -070070 JitInstrumentationCache* GetInstrumentationCache() const {
71 return instrumentation_cache_.get();
72 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080073
Calin Juravlec90bc922016-02-24 10:13:09 +000074 // Starts the profile saver if the config options allow profile recording.
75 // The profile will be stored in the specified `filename` and will contain
76 // information collected from the given `code_paths` (a set of dex locations).
77 // The `foreign_dex_profile_path` is the path where the saver will put the
78 // profile markers for loaded dex files which are not owned by the application.
79 // The `app_dir` is the application directory and is used to decide which
80 // dex files belong to the application.
81 void StartProfileSaver(const std::string& filename,
82 const std::vector<std::string>& code_paths,
83 const std::string& foreign_dex_profile_path,
84 const std::string& app_dir);
Calin Juravle4d77b6a2015-12-01 18:38:09 +000085 void StopProfileSaver();
Calin Juravle31f2c152015-10-23 17:56:15 +010086
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000087 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_) {
Nicolas Geoffrayaee21562015-12-15 16:39:44 +000088 DumpInfo(os);
89 }
90
Tamas Berghammer160e6df2016-01-05 14:29:02 +000091 static void NewTypeLoadedIfUsingJit(mirror::Class* type)
92 SHARED_REQUIRES(Locks::mutator_lock_);
93
Tamas Berghammerfffbee42016-01-15 13:09:34 +000094 // If debug info generation is turned on then write the type information for types already loaded
95 // into the specified class linker to the jit debug interface,
96 void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
97
Nicolas Geoffray35122442016-03-02 12:05:30 +000098 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
Siva Chandra05d24152016-01-05 17:43:17 -080099 bool JitAtFirstUse();
100
Nicolas Geoffray35122442016-03-02 12:05:30 +0000101 // Return whether we can invoke JIT code for `method`.
102 bool CanInvokeCompiledCode(ArtMethod* method);
103
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000104 // If an OSR compiled version is available for `method`,
105 // and `dex_pc + dex_pc_offset` is an entry point of that compiled
106 // version, this method will jump to the compiled code, let it run,
107 // and return true afterwards. Return false otherwise.
108 static bool MaybeDoOnStackReplacement(Thread* thread,
109 ArtMethod* method,
110 uint32_t dex_pc,
111 int32_t dex_pc_offset,
112 JValue* result)
113 SHARED_REQUIRES(Locks::mutator_lock_);
114
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700115 static bool LoadCompiler(std::string* error_msg);
116
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800117 private:
118 Jit();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800119
120 // JIT compiler
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700121 static void* jit_library_handle_;
122 static void* jit_compiler_handle_;
123 static void* (*jit_load_)(bool*);
124 static void (*jit_unload_)(void*);
125 static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool);
126 static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800127
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700128 // Performance monitoring.
129 bool dump_info_on_shutdown_;
130 CumulativeLogger cumulative_timings_;
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000131 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
132 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700133
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800134 std::unique_ptr<jit::JitInstrumentationCache> instrumentation_cache_;
135 std::unique_ptr<jit::JitCodeCache> code_cache_;
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700136
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000137 bool save_profiling_info_;
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700138 static bool generate_debug_info_;
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000139
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700140 DISALLOW_COPY_AND_ASSIGN(Jit);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800141};
142
143class JitOptions {
144 public:
145 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
146 size_t GetCompileThreshold() const {
147 return compile_threshold_;
148 }
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100149 size_t GetWarmupThreshold() const {
150 return warmup_threshold_;
151 }
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000152 size_t GetOsrThreshold() const {
153 return osr_threshold_;
154 }
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000155 size_t GetCodeCacheInitialCapacity() const {
156 return code_cache_initial_capacity_;
157 }
158 size_t GetCodeCacheMaxCapacity() const {
159 return code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800160 }
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700161 bool DumpJitInfoOnShutdown() const {
162 return dump_info_on_shutdown_;
163 }
Calin Juravle31f2c152015-10-23 17:56:15 +0100164 bool GetSaveProfilingInfo() const {
165 return save_profiling_info_;
166 }
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700167 bool UseJIT() const {
168 return use_jit_;
169 }
170 void SetUseJIT(bool b) {
171 use_jit_ = b;
172 }
Calin Juravle31f2c152015-10-23 17:56:15 +0100173 void SetSaveProfilingInfo(bool b) {
174 save_profiling_info_ = b;
175 }
Siva Chandra05d24152016-01-05 17:43:17 -0800176 void SetJitAtFirstUse() {
177 use_jit_ = true;
178 compile_threshold_ = 0;
179 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800180
181 private:
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700182 bool use_jit_;
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000183 size_t code_cache_initial_capacity_;
184 size_t code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800185 size_t compile_threshold_;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100186 size_t warmup_threshold_;
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000187 size_t osr_threshold_;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700188 bool dump_info_on_shutdown_;
Calin Juravle31f2c152015-10-23 17:56:15 +0100189 bool save_profiling_info_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800190
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000191 JitOptions()
192 : use_jit_(false),
193 code_cache_initial_capacity_(0),
194 code_cache_max_capacity_(0),
195 compile_threshold_(0),
Calin Juravle31f2c152015-10-23 17:56:15 +0100196 dump_info_on_shutdown_(false),
197 save_profiling_info_(false) { }
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700198
199 DISALLOW_COPY_AND_ASSIGN(JitOptions);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800200};
201
202} // namespace jit
203} // namespace art
204
205#endif // ART_RUNTIME_JIT_JIT_H_