blob: ff3acf62c8581e179740c55c1d929d76b2ca0249 [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;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080037class JitOptions;
38
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010039static constexpr int16_t kJitCheckForOSR = -1;
40static constexpr int16_t kJitHotnessDisabled = -2;
41
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080042class Jit {
43 public:
44 static constexpr bool kStressMode = kIsDebugBuild;
Nicolas Geoffray83f080a2016-03-08 16:50:21 +000045 static constexpr size_t kDefaultCompileThreshold = kStressMode ? 2 : 10000;
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010046 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
47 static constexpr size_t kDefaultTransitionRatio = 100;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080048
49 virtual ~Jit();
50 static Jit* Create(JitOptions* options, std::string* error_msg);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000051 bool CompileMethod(ArtMethod* method, Thread* self, bool osr)
Mathieu Chartier90443472015-07-16 20:32:27 -070052 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080053 void CreateThreadPool();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010054
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080055 const JitCodeCache* GetCodeCache() const {
56 return code_cache_.get();
57 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010058
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080059 JitCodeCache* GetCodeCache() {
60 return code_cache_.get();
61 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010062
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080063 void DeleteThreadPool();
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070064 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
65 // loggers.
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000066 void DumpInfo(std::ostream& os) REQUIRES(!lock_);
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070067 // Add a timing logger to cumulative_timings_.
68 void AddTimingLogger(const TimingLogger& logger);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000069
70 void AddMemoryUsage(ArtMethod* method, size_t bytes)
71 REQUIRES(!lock_)
72 SHARED_REQUIRES(Locks::mutator_lock_);
73
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010074 size_t OSRMethodThreshold() const {
75 return osr_method_threshold_;
Mathieu Chartiera50f9cf2015-09-25 11:34:45 -070076 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080077
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010078 size_t HotMethodThreshold() const {
79 return hot_method_threshold_;
80 }
81
82 size_t WarmMethodThreshold() const {
83 return warm_method_threshold_;
84 }
85
86 uint16_t PriorityThreadWeight() const {
87 return priority_thread_weight_;
88 }
89
90 // Wait until there is no more pending compilation tasks.
91 void WaitForCompilationToFinish(Thread* self);
92
93 // Profiling methods.
94 void MethodEntered(Thread* thread, ArtMethod* method)
95 SHARED_REQUIRES(Locks::mutator_lock_);
96
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010097 void AddSamples(Thread* self, ArtMethod* method, uint16_t samples, bool with_backedges)
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010098 SHARED_REQUIRES(Locks::mutator_lock_);
99
100 void InvokeVirtualOrInterface(Thread* thread,
101 mirror::Object* this_object,
102 ArtMethod* caller,
103 uint32_t dex_pc,
104 ArtMethod* callee)
105 SHARED_REQUIRES(Locks::mutator_lock_);
106
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100107 void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
108 SHARED_REQUIRES(Locks::mutator_lock_) {
109 AddSamples(self, caller, transition_weight_, false);
110 }
111
112 void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
113 SHARED_REQUIRES(Locks::mutator_lock_) {
114 AddSamples(self, callee, transition_weight_, false);
115 }
116
Calin Juravlec90bc922016-02-24 10:13:09 +0000117 // Starts the profile saver if the config options allow profile recording.
118 // The profile will be stored in the specified `filename` and will contain
119 // information collected from the given `code_paths` (a set of dex locations).
120 // The `foreign_dex_profile_path` is the path where the saver will put the
121 // profile markers for loaded dex files which are not owned by the application.
122 // The `app_dir` is the application directory and is used to decide which
123 // dex files belong to the application.
124 void StartProfileSaver(const std::string& filename,
125 const std::vector<std::string>& code_paths,
126 const std::string& foreign_dex_profile_path,
127 const std::string& app_dir);
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000128 void StopProfileSaver();
Calin Juravle31f2c152015-10-23 17:56:15 +0100129
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000130 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_) {
Nicolas Geoffrayaee21562015-12-15 16:39:44 +0000131 DumpInfo(os);
132 }
133
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000134 static void NewTypeLoadedIfUsingJit(mirror::Class* type)
135 SHARED_REQUIRES(Locks::mutator_lock_);
136
Tamas Berghammerfffbee42016-01-15 13:09:34 +0000137 // If debug info generation is turned on then write the type information for types already loaded
138 // into the specified class linker to the jit debug interface,
139 void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
140
Nicolas Geoffray35122442016-03-02 12:05:30 +0000141 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
Siva Chandra05d24152016-01-05 17:43:17 -0800142 bool JitAtFirstUse();
143
Nicolas Geoffray35122442016-03-02 12:05:30 +0000144 // Return whether we can invoke JIT code for `method`.
145 bool CanInvokeCompiledCode(ArtMethod* method);
146
Calin Juravleb2771b42016-04-07 17:09:25 +0100147 // Return whether the runtime should use a priority thread weight when sampling.
148 static bool ShouldUsePriorityThreadWeight();
149
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000150 // If an OSR compiled version is available for `method`,
151 // and `dex_pc + dex_pc_offset` is an entry point of that compiled
152 // version, this method will jump to the compiled code, let it run,
153 // and return true afterwards. Return false otherwise.
154 static bool MaybeDoOnStackReplacement(Thread* thread,
155 ArtMethod* method,
156 uint32_t dex_pc,
157 int32_t dex_pc_offset,
158 JValue* result)
159 SHARED_REQUIRES(Locks::mutator_lock_);
160
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700161 static bool LoadCompilerLibrary(std::string* error_msg);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700162
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800163 private:
164 Jit();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800165
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700166 static bool LoadCompiler(std::string* error_msg);
167
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800168 // JIT compiler
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700169 static void* jit_library_handle_;
170 static void* jit_compiler_handle_;
171 static void* (*jit_load_)(bool*);
172 static void (*jit_unload_)(void*);
173 static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool);
174 static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800175
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700176 // Performance monitoring.
177 bool dump_info_on_shutdown_;
178 CumulativeLogger cumulative_timings_;
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000179 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
180 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700181
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800182 std::unique_ptr<jit::JitCodeCache> code_cache_;
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700183
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000184 bool save_profiling_info_;
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700185 static bool generate_debug_info_;
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100186 uint16_t hot_method_threshold_;
187 uint16_t warm_method_threshold_;
188 uint16_t osr_method_threshold_;
189 uint16_t priority_thread_weight_;
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100190 uint16_t transition_weight_;
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100191 std::unique_ptr<ThreadPool> thread_pool_;
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000192
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700193 DISALLOW_COPY_AND_ASSIGN(Jit);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800194};
195
196class JitOptions {
197 public:
198 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
199 size_t GetCompileThreshold() const {
200 return compile_threshold_;
201 }
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100202 size_t GetWarmupThreshold() const {
203 return warmup_threshold_;
204 }
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000205 size_t GetOsrThreshold() const {
206 return osr_threshold_;
207 }
Calin Juravleb2771b42016-04-07 17:09:25 +0100208 uint16_t GetPriorityThreadWeight() const {
209 return priority_thread_weight_;
210 }
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000211 size_t GetCodeCacheInitialCapacity() const {
212 return code_cache_initial_capacity_;
213 }
214 size_t GetCodeCacheMaxCapacity() const {
215 return code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800216 }
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700217 bool DumpJitInfoOnShutdown() const {
218 return dump_info_on_shutdown_;
219 }
Calin Juravle31f2c152015-10-23 17:56:15 +0100220 bool GetSaveProfilingInfo() const {
221 return save_profiling_info_;
222 }
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700223 bool UseJIT() const {
224 return use_jit_;
225 }
226 void SetUseJIT(bool b) {
227 use_jit_ = b;
228 }
Calin Juravle31f2c152015-10-23 17:56:15 +0100229 void SetSaveProfilingInfo(bool b) {
230 save_profiling_info_ = b;
231 }
Siva Chandra05d24152016-01-05 17:43:17 -0800232 void SetJitAtFirstUse() {
233 use_jit_ = true;
234 compile_threshold_ = 0;
235 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800236
237 private:
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700238 bool use_jit_;
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000239 size_t code_cache_initial_capacity_;
240 size_t code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800241 size_t compile_threshold_;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100242 size_t warmup_threshold_;
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000243 size_t osr_threshold_;
Calin Juravleb2771b42016-04-07 17:09:25 +0100244 uint16_t priority_thread_weight_;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700245 bool dump_info_on_shutdown_;
Calin Juravle31f2c152015-10-23 17:56:15 +0100246 bool save_profiling_info_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800247
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000248 JitOptions()
249 : use_jit_(false),
250 code_cache_initial_capacity_(0),
251 code_cache_max_capacity_(0),
252 compile_threshold_(0),
Calin Juravle31f2c152015-10-23 17:56:15 +0100253 dump_info_on_shutdown_(false),
254 save_profiling_info_(false) { }
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700255
256 DISALLOW_COPY_AND_ASSIGN(JitOptions);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800257};
258
259} // namespace jit
260} // namespace art
261
262#endif // ART_RUNTIME_JIT_JIT_H_