blob: 051b310f89e22618192f43077be4e1bec27f05b7 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
2 * Copyright (C) 2011 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#include "compiler_driver.h"
18
Anwar Ghuloum67f99412013-08-12 14:19:48 -070019#define ATRACE_TAG ATRACE_TAG_DALVIK
20#include <utils/Trace.h>
Brian Carlstrom7940e442013-07-12 13:46:57 -070021
Andreas Gampeb0f370e2014-09-25 22:51:40 -070022#include <unordered_set>
Anwar Ghuloum67f99412013-08-12 14:19:48 -070023#include <vector>
Brian Carlstrom7940e442013-07-12 13:46:57 -070024#include <unistd.h>
25
Mathieu Chartierab972ef2014-12-03 17:38:22 -080026#ifndef __APPLE__
27#include <malloc.h> // For mallinfo
28#endif
29
Brian Carlstrom7940e442013-07-12 13:46:57 -070030#include "base/stl_util.h"
31#include "base/timing_logger.h"
32#include "class_linker.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070033#include "compiled_class.h"
Nicolas Geoffrayb34f69a2014-03-07 15:28:39 +000034#include "compiler.h"
Vladimir Markobe0e5462014-02-26 11:24:15 +000035#include "compiler_driver-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070036#include "dex_compilation_unit.h"
37#include "dex_file-inl.h"
Vladimir Markoc7f83202014-01-24 17:55:18 +000038#include "dex/verification_results.h"
Vladimir Marko2730db02014-01-27 11:15:17 +000039#include "dex/verified_method.h"
Vladimir Marko2bc47802014-02-10 09:43:07 +000040#include "dex/quick/dex_file_method_inliner.h"
Mark Mendellae9fd932014-02-10 16:14:35 -080041#include "driver/compiler_options.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070042#include "jni_internal.h"
Ian Rogers22d5e732014-07-15 22:23:51 -070043#include "object_lock.h"
Calin Juravlebb0b53f2014-05-23 17:33:29 +010044#include "profiler.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070045#include "runtime.h"
46#include "gc/accounting/card_table-inl.h"
47#include "gc/accounting/heap_bitmap.h"
48#include "gc/space/space.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070049#include "mirror/art_field-inl.h"
50#include "mirror/art_method-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070051#include "mirror/class_loader.h"
52#include "mirror/class-inl.h"
53#include "mirror/dex_cache-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070054#include "mirror/object-inl.h"
55#include "mirror/object_array-inl.h"
56#include "mirror/throwable.h"
57#include "scoped_thread_state_change.h"
58#include "ScopedLocalRef.h"
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070059#include "handle_scope-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070060#include "thread.h"
Andreas Gampeb0f370e2014-09-25 22:51:40 -070061#include "thread_list.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070062#include "thread_pool.h"
Ian Rogers848871b2013-08-05 10:56:33 -070063#include "trampolines/trampoline_compiler.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010064#include "transaction.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070065#include "verifier/method_verifier.h"
Vladimir Marko2bc47802014-02-10 09:43:07 +000066#include "verifier/method_verifier-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070067
Brian Carlstrom7940e442013-07-12 13:46:57 -070068namespace art {
69
Mathieu Chartier8e219ae2014-08-19 14:29:46 -070070static constexpr bool kTimeCompileMethod = !kIsDebugBuild;
71
Brian Carlstrom7940e442013-07-12 13:46:57 -070072static double Percentage(size_t x, size_t y) {
73 return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y));
74}
75
76static void DumpStat(size_t x, size_t y, const char* str) {
77 if (x == 0 && y == 0) {
78 return;
79 }
Ian Rogerse732ef12013-10-09 15:22:24 -070080 LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases";
Brian Carlstrom7940e442013-07-12 13:46:57 -070081}
82
Vladimir Markof096aad2014-01-23 15:51:58 +000083class CompilerDriver::AOTCompilationStats {
Brian Carlstrom7940e442013-07-12 13:46:57 -070084 public:
85 AOTCompilationStats()
86 : stats_lock_("AOT compilation statistics lock"),
87 types_in_dex_cache_(0), types_not_in_dex_cache_(0),
88 strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
89 resolved_types_(0), unresolved_types_(0),
90 resolved_instance_fields_(0), unresolved_instance_fields_(0),
91 resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
92 type_based_devirtualization_(0),
93 safe_casts_(0), not_safe_casts_(0) {
94 for (size_t i = 0; i <= kMaxInvokeType; i++) {
95 resolved_methods_[i] = 0;
96 unresolved_methods_[i] = 0;
97 virtual_made_direct_[i] = 0;
98 direct_calls_to_boot_[i] = 0;
99 direct_methods_to_boot_[i] = 0;
100 }
101 }
102
103 void Dump() {
104 DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
105 DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
106 DumpStat(resolved_types_, unresolved_types_, "types resolved");
107 DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
108 DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
109 "static fields resolved");
110 DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_,
111 "static fields local to a class");
112 DumpStat(safe_casts_, not_safe_casts_, "check-casts removed based on type information");
113 // Note, the code below subtracts the stat value so that when added to the stat value we have
114 // 100% of samples. TODO: clean this up.
115 DumpStat(type_based_devirtualization_,
116 resolved_methods_[kVirtual] + unresolved_methods_[kVirtual] +
117 resolved_methods_[kInterface] + unresolved_methods_[kInterface] -
118 type_based_devirtualization_,
119 "virtual/interface calls made direct based on type information");
120
121 for (size_t i = 0; i <= kMaxInvokeType; i++) {
122 std::ostringstream oss;
123 oss << static_cast<InvokeType>(i) << " methods were AOT resolved";
124 DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
125 if (virtual_made_direct_[i] > 0) {
126 std::ostringstream oss2;
127 oss2 << static_cast<InvokeType>(i) << " methods made direct";
128 DumpStat(virtual_made_direct_[i],
129 resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i],
130 oss2.str().c_str());
131 }
132 if (direct_calls_to_boot_[i] > 0) {
133 std::ostringstream oss2;
134 oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot";
135 DumpStat(direct_calls_to_boot_[i],
136 resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i],
137 oss2.str().c_str());
138 }
139 if (direct_methods_to_boot_[i] > 0) {
140 std::ostringstream oss2;
141 oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot";
142 DumpStat(direct_methods_to_boot_[i],
143 resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i],
144 oss2.str().c_str());
145 }
146 }
147 }
148
149// Allow lossy statistics in non-debug builds.
150#ifndef NDEBUG
151#define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_)
152#else
153#define STATS_LOCK()
154#endif
155
156 void TypeInDexCache() {
157 STATS_LOCK();
158 types_in_dex_cache_++;
159 }
160
161 void TypeNotInDexCache() {
162 STATS_LOCK();
163 types_not_in_dex_cache_++;
164 }
165
166 void StringInDexCache() {
167 STATS_LOCK();
168 strings_in_dex_cache_++;
169 }
170
171 void StringNotInDexCache() {
172 STATS_LOCK();
173 strings_not_in_dex_cache_++;
174 }
175
176 void TypeDoesntNeedAccessCheck() {
177 STATS_LOCK();
178 resolved_types_++;
179 }
180
181 void TypeNeedsAccessCheck() {
182 STATS_LOCK();
183 unresolved_types_++;
184 }
185
186 void ResolvedInstanceField() {
187 STATS_LOCK();
188 resolved_instance_fields_++;
189 }
190
191 void UnresolvedInstanceField() {
192 STATS_LOCK();
193 unresolved_instance_fields_++;
194 }
195
196 void ResolvedLocalStaticField() {
197 STATS_LOCK();
198 resolved_local_static_fields_++;
199 }
200
201 void ResolvedStaticField() {
202 STATS_LOCK();
203 resolved_static_fields_++;
204 }
205
206 void UnresolvedStaticField() {
207 STATS_LOCK();
208 unresolved_static_fields_++;
209 }
210
211 // Indicate that type information from the verifier led to devirtualization.
212 void PreciseTypeDevirtualization() {
213 STATS_LOCK();
214 type_based_devirtualization_++;
215 }
216
217 // Indicate that a method of the given type was resolved at compile time.
218 void ResolvedMethod(InvokeType type) {
219 DCHECK_LE(type, kMaxInvokeType);
220 STATS_LOCK();
221 resolved_methods_[type]++;
222 }
223
224 // Indicate that a method of the given type was unresolved at compile time as it was in an
225 // unknown dex file.
226 void UnresolvedMethod(InvokeType type) {
227 DCHECK_LE(type, kMaxInvokeType);
228 STATS_LOCK();
229 unresolved_methods_[type]++;
230 }
231
232 // Indicate that a type of virtual method dispatch has been converted into a direct method
233 // dispatch.
234 void VirtualMadeDirect(InvokeType type) {
235 DCHECK(type == kVirtual || type == kInterface || type == kSuper);
236 STATS_LOCK();
237 virtual_made_direct_[type]++;
238 }
239
240 // Indicate that a method of the given type was able to call directly into boot.
241 void DirectCallsToBoot(InvokeType type) {
242 DCHECK_LE(type, kMaxInvokeType);
243 STATS_LOCK();
244 direct_calls_to_boot_[type]++;
245 }
246
247 // Indicate that a method of the given type was able to be resolved directly from boot.
248 void DirectMethodsToBoot(InvokeType type) {
249 DCHECK_LE(type, kMaxInvokeType);
250 STATS_LOCK();
251 direct_methods_to_boot_[type]++;
252 }
253
Vladimir Markof096aad2014-01-23 15:51:58 +0000254 void ProcessedInvoke(InvokeType type, int flags) {
255 STATS_LOCK();
256 if (flags == 0) {
257 unresolved_methods_[type]++;
258 } else {
259 DCHECK_NE((flags & kFlagMethodResolved), 0);
260 resolved_methods_[type]++;
261 if ((flags & kFlagVirtualMadeDirect) != 0) {
262 virtual_made_direct_[type]++;
263 if ((flags & kFlagPreciseTypeDevirtualization) != 0) {
264 type_based_devirtualization_++;
265 }
266 } else {
267 DCHECK_EQ((flags & kFlagPreciseTypeDevirtualization), 0);
268 }
269 if ((flags & kFlagDirectCallToBoot) != 0) {
270 direct_calls_to_boot_[type]++;
271 }
272 if ((flags & kFlagDirectMethodToBoot) != 0) {
273 direct_methods_to_boot_[type]++;
274 }
275 }
276 }
277
Brian Carlstrom7940e442013-07-12 13:46:57 -0700278 // A check-cast could be eliminated due to verifier type analysis.
279 void SafeCast() {
280 STATS_LOCK();
281 safe_casts_++;
282 }
283
284 // A check-cast couldn't be eliminated due to verifier type analysis.
285 void NotASafeCast() {
286 STATS_LOCK();
287 not_safe_casts_++;
288 }
289
290 private:
291 Mutex stats_lock_;
292
293 size_t types_in_dex_cache_;
294 size_t types_not_in_dex_cache_;
295
296 size_t strings_in_dex_cache_;
297 size_t strings_not_in_dex_cache_;
298
299 size_t resolved_types_;
300 size_t unresolved_types_;
301
302 size_t resolved_instance_fields_;
303 size_t unresolved_instance_fields_;
304
305 size_t resolved_local_static_fields_;
306 size_t resolved_static_fields_;
307 size_t unresolved_static_fields_;
308 // Type based devirtualization for invoke interface and virtual.
309 size_t type_based_devirtualization_;
310
311 size_t resolved_methods_[kMaxInvokeType + 1];
312 size_t unresolved_methods_[kMaxInvokeType + 1];
313 size_t virtual_made_direct_[kMaxInvokeType + 1];
314 size_t direct_calls_to_boot_[kMaxInvokeType + 1];
315 size_t direct_methods_to_boot_[kMaxInvokeType + 1];
316
317 size_t safe_casts_;
318 size_t not_safe_casts_;
319
320 DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
321};
322
Brian Carlstrom7940e442013-07-12 13:46:57 -0700323
324extern "C" art::CompiledMethod* ArtCompileDEX(art::CompilerDriver& compiler,
325 const art::DexFile::CodeItem* code_item,
326 uint32_t access_flags,
327 art::InvokeType invoke_type,
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700328 uint16_t class_def_idx,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700329 uint32_t method_idx,
330 jobject class_loader,
331 const art::DexFile& dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700332
Brian Carlstrom6449c622014-02-10 23:48:36 -0800333CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options,
334 VerificationResults* verification_results,
Vladimir Marko5816ed42013-11-27 17:04:20 +0000335 DexFileToMethodInlinerMap* method_inliner_map,
Nicolas Geoffrayb34f69a2014-03-07 15:28:39 +0000336 Compiler::Kind compiler_kind,
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000337 InstructionSet instruction_set,
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700338 const InstructionSetFeatures* instruction_set_features,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -0800339 bool image, std::set<std::string>* image_classes,
340 std::set<std::string>* compiled_classes, size_t thread_count,
Dave Allison39c3bfb2014-01-28 18:33:52 -0800341 bool dump_stats, bool dump_passes, CumulativeLogger* timer,
Ian Rogersd4c4d952014-10-16 20:31:53 -0700342 const std::string& profile_file)
Calin Juravlec1b643c2014-05-30 23:44:11 +0100343 : profile_present_(false), compiler_options_(compiler_options),
Brian Carlstrom6449c622014-02-10 23:48:36 -0800344 verification_results_(verification_results),
Vladimir Marko5816ed42013-11-27 17:04:20 +0000345 method_inliner_map_(method_inliner_map),
Ian Rogers72d32622014-05-06 16:20:11 -0700346 compiler_(Compiler::Create(this, compiler_kind)),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700347 instruction_set_(instruction_set),
Dave Allison70202782013-10-22 17:52:19 -0700348 instruction_set_features_(instruction_set_features),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700349 freezing_constructor_lock_("freezing constructor lock"),
350 compiled_classes_lock_("compiled classes lock"),
351 compiled_methods_lock_("compiled method lock"),
Vladimir Markof4da6752014-08-01 19:04:18 +0100352 compiled_methods_(),
353 non_relative_linker_patch_count_(0u),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700354 image_(image),
355 image_classes_(image_classes),
Andreas Gampe4bf3ae92014-11-11 13:28:29 -0800356 classes_to_compile_(compiled_classes),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700357 thread_count_(thread_count),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700358 stats_(new AOTCompilationStats),
359 dump_stats_(dump_stats),
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000360 dump_passes_(dump_passes),
361 timings_logger_(timer),
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700362 compiler_context_(nullptr),
Mark Mendell55d0eac2014-02-06 11:02:52 -0800363 support_boot_image_fixup_(instruction_set != kMips),
Ian Rogersd133b972013-09-05 11:01:30 -0700364 dedupe_code_("dedupe code"),
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700365 dedupe_src_mapping_table_("dedupe source mapping table"),
Ian Rogersd133b972013-09-05 11:01:30 -0700366 dedupe_mapping_table_("dedupe mapping table"),
367 dedupe_vmap_table_("dedupe vmap table"),
Mark Mendellae9fd932014-02-10 16:14:35 -0800368 dedupe_gc_map_("dedupe gc map"),
369 dedupe_cfi_info_("dedupe cfi info") {
Brian Carlstrom6449c622014-02-10 23:48:36 -0800370 DCHECK(compiler_options_ != nullptr);
371 DCHECK(verification_results_ != nullptr);
372 DCHECK(method_inliner_map_ != nullptr);
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700373
Sebastien Hertz75021222013-07-16 18:34:50 +0200374 dex_to_dex_compiler_ = reinterpret_cast<DexToDexCompilerFn>(ArtCompileDEX);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700375
Ian Rogers72d32622014-05-06 16:20:11 -0700376 compiler_->Init();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700377
378 CHECK(!Runtime::Current()->IsStarted());
Kenny Rootd5185342014-05-13 14:47:05 -0700379 if (image_) {
380 CHECK(image_classes_.get() != nullptr);
381 } else {
382 CHECK(image_classes_.get() == nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700383 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800384
Calin Juravlec1b643c2014-05-30 23:44:11 +0100385 // Read the profile file if one is provided.
386 if (!profile_file.empty()) {
387 profile_present_ = profile_file_.LoadFile(profile_file);
388 if (profile_present_) {
389 LOG(INFO) << "Using profile data form file " << profile_file;
390 } else {
391 LOG(INFO) << "Failed to load profile file " << profile_file;
392 }
393 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700394}
395
Mathieu Chartier193bad92013-08-29 18:46:00 -0700396std::vector<uint8_t>* CompilerDriver::DeduplicateCode(const std::vector<uint8_t>& code) {
397 return dedupe_code_.Add(Thread::Current(), code);
398}
399
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700400SrcMap* CompilerDriver::DeduplicateSrcMappingTable(const SrcMap& src_map) {
401 return dedupe_src_mapping_table_.Add(Thread::Current(), src_map);
402}
403
Mathieu Chartier193bad92013-08-29 18:46:00 -0700404std::vector<uint8_t>* CompilerDriver::DeduplicateMappingTable(const std::vector<uint8_t>& code) {
405 return dedupe_mapping_table_.Add(Thread::Current(), code);
406}
407
408std::vector<uint8_t>* CompilerDriver::DeduplicateVMapTable(const std::vector<uint8_t>& code) {
409 return dedupe_vmap_table_.Add(Thread::Current(), code);
410}
411
412std::vector<uint8_t>* CompilerDriver::DeduplicateGCMap(const std::vector<uint8_t>& code) {
413 return dedupe_gc_map_.Add(Thread::Current(), code);
414}
415
Mark Mendellae9fd932014-02-10 16:14:35 -0800416std::vector<uint8_t>* CompilerDriver::DeduplicateCFIInfo(const std::vector<uint8_t>* cfi_info) {
417 if (cfi_info == nullptr) {
418 return nullptr;
419 }
420 return dedupe_cfi_info_.Add(Thread::Current(), *cfi_info);
421}
422
Brian Carlstrom7940e442013-07-12 13:46:57 -0700423CompilerDriver::~CompilerDriver() {
424 Thread* self = Thread::Current();
425 {
426 MutexLock mu(self, compiled_classes_lock_);
427 STLDeleteValues(&compiled_classes_);
428 }
429 {
430 MutexLock mu(self, compiled_methods_lock_);
431 STLDeleteValues(&compiled_methods_);
432 }
Ian Rogers72d32622014-05-06 16:20:11 -0700433 compiler_->UnInit();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700434}
435
Ian Rogersdd7624d2014-03-14 17:43:00 -0700436#define CREATE_TRAMPOLINE(type, abi, offset) \
Andreas Gampeaf13ad92014-04-11 12:07:48 -0700437 if (Is64BitInstructionSet(instruction_set_)) { \
Ian Rogersdd7624d2014-03-14 17:43:00 -0700438 return CreateTrampoline64(instruction_set_, abi, \
439 type ## _ENTRYPOINT_OFFSET(8, offset)); \
440 } else { \
441 return CreateTrampoline32(instruction_set_, abi, \
442 type ## _ENTRYPOINT_OFFSET(4, offset)); \
443 }
444
Ian Rogers848871b2013-08-05 10:56:33 -0700445const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToInterpreterBridge() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700446 CREATE_TRAMPOLINE(INTERPRETER, kInterpreterAbi, pInterpreterToInterpreterBridge)
Ian Rogers848871b2013-08-05 10:56:33 -0700447}
448
449const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToCompiledCodeBridge() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700450 CREATE_TRAMPOLINE(INTERPRETER, kInterpreterAbi, pInterpreterToCompiledCodeBridge)
Ian Rogers848871b2013-08-05 10:56:33 -0700451}
452
453const std::vector<uint8_t>* CompilerDriver::CreateJniDlsymLookup() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700454 CREATE_TRAMPOLINE(JNI, kJniAbi, pDlsymLookup)
Ian Rogers848871b2013-08-05 10:56:33 -0700455}
456
Andreas Gampe2da88232014-02-27 12:26:20 -0800457const std::vector<uint8_t>* CompilerDriver::CreateQuickGenericJniTrampoline() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700458 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickGenericJniTrampoline)
Andreas Gampe2da88232014-02-27 12:26:20 -0800459}
460
Jeff Hao88474b42013-10-23 16:24:40 -0700461const std::vector<uint8_t>* CompilerDriver::CreateQuickImtConflictTrampoline() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700462 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickImtConflictTrampoline)
Jeff Hao88474b42013-10-23 16:24:40 -0700463}
464
Brian Carlstrom7940e442013-07-12 13:46:57 -0700465const std::vector<uint8_t>* CompilerDriver::CreateQuickResolutionTrampoline() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700466 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickResolutionTrampoline)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700467}
468
Ian Rogers848871b2013-08-05 10:56:33 -0700469const std::vector<uint8_t>* CompilerDriver::CreateQuickToInterpreterBridge() const {
Ian Rogersdd7624d2014-03-14 17:43:00 -0700470 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickToInterpreterBridge)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700471}
Ian Rogersdd7624d2014-03-14 17:43:00 -0700472#undef CREATE_TRAMPOLINE
Brian Carlstrom7940e442013-07-12 13:46:57 -0700473
474void CompilerDriver::CompileAll(jobject class_loader,
Brian Carlstrom45602482013-07-21 22:07:55 -0700475 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -0800476 TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700477 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogers700a4022014-05-19 16:49:03 -0700478 std::unique_ptr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", thread_count_ - 1));
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800479 VLOG(compiler) << "Before precompile " << GetMemoryUsageString();
Ian Rogers3d504072014-03-01 09:16:49 -0800480 PreCompile(class_loader, dex_files, thread_pool.get(), timings);
481 Compile(class_loader, dex_files, thread_pool.get(), timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700482 if (dump_stats_) {
483 stats_->Dump();
484 }
485}
486
Mathieu Chartier590fee92013-09-13 13:46:47 -0700487static DexToDexCompilationLevel GetDexToDexCompilationlevel(
Mathieu Chartier0cd81352014-05-22 16:48:55 -0700488 Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file,
Mathieu Chartier590fee92013-09-13 13:46:47 -0700489 const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700490 const char* descriptor = dex_file.GetClassDescriptor(class_def);
491 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogers98379392014-02-24 16:53:16 -0800492 mirror::Class* klass = class_linker->FindClass(self, descriptor, class_loader);
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700493 if (klass == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700494 CHECK(self->IsExceptionPending());
495 self->ClearException();
Sebastien Hertz75021222013-07-16 18:34:50 +0200496 return kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700497 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700498 // DexToDex at the kOptimize level may introduce quickened opcodes, which replace symbolic
499 // references with actual offsets. We cannot re-verify such instructions.
500 //
501 // We store the verification information in the class status in the oat file, which the linker
502 // can validate (checksums) and use to skip load-time verification. It is thus safe to
503 // optimize when a class has been fully verified before.
504 if (klass->IsVerified()) {
Sebastien Hertz75021222013-07-16 18:34:50 +0200505 // Class is verified so we can enable DEX-to-DEX compilation for performance.
506 return kOptimize;
507 } else if (klass->IsCompileTimeVerified()) {
508 // Class verification has soft-failed. Anyway, ensure at least correctness.
509 DCHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime);
510 return kRequired;
511 } else {
512 // Class verification has failed: do not run DEX-to-DEX compilation.
513 return kDontDexToDexCompile;
514 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700515}
516
Ian Rogers3d504072014-03-01 09:16:49 -0800517void CompilerDriver::CompileOne(mirror::ArtMethod* method, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700518 DCHECK(!Runtime::Current()->IsStarted());
519 Thread* self = Thread::Current();
520 jobject jclass_loader;
521 const DexFile* dex_file;
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700522 uint16_t class_def_idx;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800523 uint32_t method_idx = method->GetDexMethodIndex();
524 uint32_t access_flags = method->GetAccessFlags();
525 InvokeType invoke_type = method->GetInvokeType();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700526 {
527 ScopedObjectAccessUnchecked soa(self);
528 ScopedLocalRef<jobject>
529 local_class_loader(soa.Env(),
530 soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
531 jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
532 // Find the dex_file
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700533 dex_file = method->GetDexFile();
534 class_def_idx = method->GetClassDefIndex();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700535 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800536 const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
Brian Carlstrom7940e442013-07-12 13:46:57 -0700537 self->TransitionFromRunnableToSuspended(kNative);
538
539 std::vector<const DexFile*> dex_files;
540 dex_files.push_back(dex_file);
541
Ian Rogers700a4022014-05-19 16:49:03 -0700542 std::unique_ptr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", 0U));
Ian Rogers3d504072014-03-01 09:16:49 -0800543 PreCompile(jclass_loader, dex_files, thread_pool.get(), timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700544
Brian Carlstrom7940e442013-07-12 13:46:57 -0700545 // Can we run DEX-to-DEX compiler on this class ?
Sebastien Hertz75021222013-07-16 18:34:50 +0200546 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700547 {
548 ScopedObjectAccess soa(Thread::Current());
549 const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700550 StackHandleScope<1> hs(soa.Self());
551 Handle<mirror::ClassLoader> class_loader(
552 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
Ian Rogers98379392014-02-24 16:53:16 -0800553 dex_to_dex_compilation_level = GetDexToDexCompilationlevel(self, class_loader, *dex_file,
554 class_def);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700555 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800556 CompileMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx, jclass_loader,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -0800557 *dex_file, dex_to_dex_compilation_level, true);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700558
559 self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
560
561 self->TransitionFromSuspendedToRunnable();
562}
563
564void CompilerDriver::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -0800565 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700566 for (size_t i = 0; i != dex_files.size(); ++i) {
567 const DexFile* dex_file = dex_files[i];
Kenny Rootd5185342014-05-13 14:47:05 -0700568 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -0700569 ResolveDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700570 }
571}
572
573void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -0800574 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700575 LoadImageClasses(timings);
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800576 VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700577
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700578 Resolve(class_loader, dex_files, thread_pool, timings);
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800579 VLOG(compiler) << "Resolve: " << GetMemoryUsageString();
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700580
Jeff Hao4a200f52014-04-01 14:58:49 -0700581 if (!compiler_options_->IsVerificationEnabled()) {
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800582 VLOG(compiler) << "Verify none mode specified, skipping verification.";
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700583 SetVerified(class_loader, dex_files, thread_pool, timings);
Jeff Hao4a200f52014-04-01 14:58:49 -0700584 return;
585 }
586
Brian Carlstrom7940e442013-07-12 13:46:57 -0700587 Verify(class_loader, dex_files, thread_pool, timings);
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800588 VLOG(compiler) << "Verify: " << GetMemoryUsageString();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700589
590 InitializeClasses(class_loader, dex_files, thread_pool, timings);
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800591 VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700592
593 UpdateImageClasses(timings);
Mathieu Chartierab972ef2014-12-03 17:38:22 -0800594 VLOG(compiler) << "UpdateImageClasses: " << GetMemoryUsageString();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700595}
596
Ian Rogersdfb325e2013-10-30 01:00:44 -0700597bool CompilerDriver::IsImageClass(const char* descriptor) const {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700598 if (!IsImage()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700599 return true;
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700600 } else {
Ian Rogersdfb325e2013-10-30 01:00:44 -0700601 return image_classes_->find(descriptor) != image_classes_->end();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700602 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700603}
604
Andreas Gampe4bf3ae92014-11-11 13:28:29 -0800605bool CompilerDriver::IsClassToCompile(const char* descriptor) const {
606 if (!IsImage()) {
607 return true;
608 } else {
609 if (classes_to_compile_ == nullptr) {
610 return true;
611 }
612 return classes_to_compile_->find(descriptor) != classes_to_compile_->end();
613 }
614}
615
Ian Rogerse94652f2014-12-02 11:13:19 -0800616static void ResolveExceptionsForMethod(MutableHandle<mirror::ArtMethod> method_handle,
Ian Rogers700a4022014-05-19 16:49:03 -0700617 std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700618 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogerse94652f2014-12-02 11:13:19 -0800619 const DexFile::CodeItem* code_item = method_handle->GetCodeItem();
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700620 if (code_item == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700621 return; // native or abstract method
622 }
623 if (code_item->tries_size_ == 0) {
624 return; // nothing to process
625 }
Ian Rogers13735952014-10-08 12:43:28 -0700626 const uint8_t* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700627 size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list);
628 for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
629 int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list);
630 bool has_catch_all = false;
631 if (encoded_catch_handler_size <= 0) {
632 encoded_catch_handler_size = -encoded_catch_handler_size;
633 has_catch_all = true;
634 }
635 for (int32_t j = 0; j < encoded_catch_handler_size; j++) {
636 uint16_t encoded_catch_handler_handlers_type_idx =
637 DecodeUnsignedLeb128(&encoded_catch_handler_list);
638 // Add to set of types to resolve if not already in the dex cache resolved types
Ian Rogerse94652f2014-12-02 11:13:19 -0800639 if (!method_handle->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700640 exceptions_to_resolve.insert(
641 std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx,
Ian Rogerse94652f2014-12-02 11:13:19 -0800642 method_handle->GetDexFile()));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700643 }
644 // ignore address associated with catch handler
645 DecodeUnsignedLeb128(&encoded_catch_handler_list);
646 }
647 if (has_catch_all) {
648 // ignore catch all address
649 DecodeUnsignedLeb128(&encoded_catch_handler_list);
650 }
651 }
652}
653
654static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
655 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers700a4022014-05-19 16:49:03 -0700656 std::set<std::pair<uint16_t, const DexFile*>>* exceptions_to_resolve =
657 reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*>>*>(arg);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700658 StackHandleScope<1> hs(Thread::Current());
Ian Rogerse94652f2014-12-02 11:13:19 -0800659 MutableHandle<mirror::ArtMethod> method_handle(hs.NewHandle<mirror::ArtMethod>(nullptr));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700660 for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
Ian Rogerse94652f2014-12-02 11:13:19 -0800661 method_handle.Assign(c->GetVirtualMethod(i));
662 ResolveExceptionsForMethod(method_handle, *exceptions_to_resolve);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700663 }
664 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
Ian Rogerse94652f2014-12-02 11:13:19 -0800665 method_handle.Assign(c->GetDirectMethod(i));
666 ResolveExceptionsForMethod(method_handle, *exceptions_to_resolve);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700667 }
668 return true;
669}
670
671static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
672 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700673 std::set<std::string>* image_classes = reinterpret_cast<std::set<std::string>*>(arg);
674 std::string temp;
675 image_classes->insert(klass->GetDescriptor(&temp));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700676 return true;
677}
678
679// Make a list of descriptors for classes to include in the image
Ian Rogers3d504072014-03-01 09:16:49 -0800680void CompilerDriver::LoadImageClasses(TimingLogger* timings)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700681 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Kenny Rootd5185342014-05-13 14:47:05 -0700682 CHECK(timings != nullptr);
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700683 if (!IsImage()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700684 return;
685 }
686
Mathieu Chartierf5997b42014-06-20 10:37:54 -0700687 TimingLogger::ScopedTiming t("LoadImageClasses", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700688 // Make a first class to load all classes explicitly listed in the file
689 Thread* self = Thread::Current();
690 ScopedObjectAccess soa(self);
691 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Kenny Rootd5185342014-05-13 14:47:05 -0700692 CHECK(image_classes_.get() != nullptr);
Mathieu Chartier02e25112013-08-14 16:14:24 -0700693 for (auto it = image_classes_->begin(), end = image_classes_->end(); it != end;) {
Vladimir Markoe9c36b32013-11-21 15:49:16 +0000694 const std::string& descriptor(*it);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700695 StackHandleScope<1> hs(self);
696 Handle<mirror::Class> klass(
697 hs.NewHandle(class_linker->FindSystemClass(self, descriptor.c_str())));
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700698 if (klass.Get() == nullptr) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700699 VLOG(compiler) << "Failed to find class " << descriptor;
Vladimir Markoe9c36b32013-11-21 15:49:16 +0000700 image_classes_->erase(it++);
Ian Rogersa436fde2013-08-27 23:34:06 -0700701 self->ClearException();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700702 } else {
703 ++it;
704 }
705 }
706
707 // Resolve exception classes referenced by the loaded classes. The catch logic assumes
708 // exceptions are resolved by the verifier when there is a catch block in an interested method.
709 // Do this here so that exception classes appear to have been specified image classes.
Ian Rogers700a4022014-05-19 16:49:03 -0700710 std::set<std::pair<uint16_t, const DexFile*>> unresolved_exception_types;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700711 StackHandleScope<1> hs(self);
712 Handle<mirror::Class> java_lang_Throwable(
713 hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;")));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700714 do {
715 unresolved_exception_types.clear();
716 class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor,
717 &unresolved_exception_types);
Mathieu Chartier02e25112013-08-14 16:14:24 -0700718 for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) {
719 uint16_t exception_type_idx = exception_type.first;
720 const DexFile* dex_file = exception_type.second;
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800721 StackHandleScope<2> hs2(self);
722 Handle<mirror::DexCache> dex_cache(hs2.NewHandle(class_linker->FindDexCache(*dex_file)));
723 Handle<mirror::Class> klass(hs2.NewHandle(
Mathieu Chartier0cd81352014-05-22 16:48:55 -0700724 class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache,
725 NullHandle<mirror::ClassLoader>())));
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700726 if (klass.Get() == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700727 const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
728 const char* descriptor = dex_file->GetTypeDescriptor(type_id);
729 LOG(FATAL) << "Failed to resolve class " << descriptor;
730 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700731 DCHECK(java_lang_Throwable->IsAssignableFrom(klass.Get()));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700732 }
733 // Resolving exceptions may load classes that reference more exceptions, iterate until no
734 // more are found
735 } while (!unresolved_exception_types.empty());
736
737 // We walk the roots looking for classes so that we'll pick up the
738 // above classes plus any classes them depend on such super
739 // classes, interfaces, and the required ClassLinker roots.
740 class_linker->VisitClasses(RecordImageClassesVisitor, image_classes_.get());
741
742 CHECK_NE(image_classes_->size(), 0U);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700743}
744
Ian Rogers1ff3c982014-08-12 02:30:58 -0700745static void MaybeAddToImageClasses(Handle<mirror::Class> c, std::set<std::string>* image_classes)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700746 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700747 Thread* self = Thread::Current();
748 StackHandleScope<1> hs(self);
749 // Make a copy of the handle so that we don't clobber it doing Assign.
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700750 MutableHandle<mirror::Class> klass(hs.NewHandle(c.Get()));
Ian Rogers1ff3c982014-08-12 02:30:58 -0700751 std::string temp;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700752 while (!klass->IsObjectClass()) {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700753 const char* descriptor = klass->GetDescriptor(&temp);
754 std::pair<std::set<std::string>::iterator, bool> result = image_classes->insert(descriptor);
755 if (!result.second) { // Previously inserted.
756 break;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700757 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700758 VLOG(compiler) << "Adding " << descriptor << " to image classes";
Mathieu Chartierf8322842014-05-16 10:59:25 -0700759 for (size_t i = 0; i < klass->NumDirectInterfaces(); ++i) {
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800760 StackHandleScope<1> hs2(self);
761 MaybeAddToImageClasses(hs2.NewHandle(mirror::Class::GetDirectInterface(self, klass, i)),
Mathieu Chartierf8322842014-05-16 10:59:25 -0700762 image_classes);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700763 }
764 if (klass->IsArrayClass()) {
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800765 StackHandleScope<1> hs2(self);
766 MaybeAddToImageClasses(hs2.NewHandle(klass->GetComponentType()), image_classes);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700767 }
Mathieu Chartierf8322842014-05-16 10:59:25 -0700768 klass.Assign(klass->GetSuperClass());
Brian Carlstrom7940e442013-07-12 13:46:57 -0700769 }
770}
771
Andreas Gampeb0f370e2014-09-25 22:51:40 -0700772// Keeps all the data for the update together. Also doubles as the reference visitor.
773// Note: we can use object pointers because we suspend all threads.
774class ClinitImageUpdate {
775 public:
776 static ClinitImageUpdate* Create(std::set<std::string>* image_class_descriptors, Thread* self,
777 ClassLinker* linker, std::string* error_msg) {
778 std::unique_ptr<ClinitImageUpdate> res(new ClinitImageUpdate(image_class_descriptors, self,
779 linker));
780 if (res->art_method_class_ == nullptr) {
781 *error_msg = "Could not find ArtMethod class.";
782 return nullptr;
783 } else if (res->dex_cache_class_ == nullptr) {
784 *error_msg = "Could not find DexCache class.";
785 return nullptr;
786 }
787
788 return res.release();
789 }
790
791 ~ClinitImageUpdate() {
792 // Allow others to suspend again.
793 self_->EndAssertNoThreadSuspension(old_cause_);
794 }
795
796 // Visitor for VisitReferences.
797 void operator()(mirror::Object* object, MemberOffset field_offset, bool /* is_static */) const
798 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
799 mirror::Object* ref = object->GetFieldObject<mirror::Object>(field_offset);
800 if (ref != nullptr) {
801 VisitClinitClassesObject(ref);
802 }
803 }
804
805 // java.lang.Reference visitor for VisitReferences.
Andreas Gampedc8b63c2014-12-02 14:39:52 -0800806 void operator()(mirror::Class* /* klass */, mirror::Reference* /* ref */) const {
Andreas Gampeb0f370e2014-09-25 22:51:40 -0700807 }
808
809 void Walk() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
810 // Use the initial classes as roots for a search.
811 for (mirror::Class* klass_root : image_classes_) {
812 VisitClinitClassesObject(klass_root);
813 }
814 }
815
816 private:
817 ClinitImageUpdate(std::set<std::string>* image_class_descriptors, Thread* self,
818 ClassLinker* linker)
819 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) :
820 image_class_descriptors_(image_class_descriptors), self_(self) {
821 CHECK(linker != nullptr);
822 CHECK(image_class_descriptors != nullptr);
823
824 // Make sure nobody interferes with us.
825 old_cause_ = self->StartAssertNoThreadSuspension("Boot image closure");
826
827 // Find the interesting classes.
Andreas Gampedc8b63c2014-12-02 14:39:52 -0800828 art_method_class_ = linker->LookupClass(self, "Ljava/lang/reflect/ArtMethod;",
829 ComputeModifiedUtf8Hash("Ljava/lang/reflect/ArtMethod;"), nullptr);
830 dex_cache_class_ = linker->LookupClass(self, "Ljava/lang/DexCache;",
831 ComputeModifiedUtf8Hash("Ljava/lang/DexCache;"), nullptr);
Andreas Gampeb0f370e2014-09-25 22:51:40 -0700832
833 // Find all the already-marked classes.
834 WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
835 linker->VisitClasses(FindImageClasses, this);
836 }
837
838 static bool FindImageClasses(mirror::Class* klass, void* arg)
839 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
840 ClinitImageUpdate* data = reinterpret_cast<ClinitImageUpdate*>(arg);
841 std::string temp;
842 const char* name = klass->GetDescriptor(&temp);
843 if (data->image_class_descriptors_->find(name) != data->image_class_descriptors_->end()) {
844 data->image_classes_.push_back(klass);
845 }
846
847 return true;
848 }
849
850 void VisitClinitClassesObject(mirror::Object* object) const
851 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
852 DCHECK(object != nullptr);
853 if (marked_objects_.find(object) != marked_objects_.end()) {
854 // Already processed.
855 return;
856 }
857
858 // Mark it.
859 marked_objects_.insert(object);
860
861 if (object->IsClass()) {
862 // If it is a class, add it.
863 StackHandleScope<1> hs(self_);
864 MaybeAddToImageClasses(hs.NewHandle(object->AsClass()), image_class_descriptors_);
865 } else {
866 // Else visit the object's class.
867 VisitClinitClassesObject(object->GetClass());
868 }
869
870 // If it is not a dex cache or an ArtMethod, visit all references.
871 mirror::Class* klass = object->GetClass();
872 if (klass != art_method_class_ && klass != dex_cache_class_) {
873 object->VisitReferences<false /* visit class */>(*this, *this);
874 }
875 }
876
877 mutable std::unordered_set<mirror::Object*> marked_objects_;
878 std::set<std::string>* const image_class_descriptors_;
879 std::vector<mirror::Class*> image_classes_;
880 const mirror::Class* art_method_class_;
881 const mirror::Class* dex_cache_class_;
882 Thread* const self_;
883 const char* old_cause_;
884
885 DISALLOW_COPY_AND_ASSIGN(ClinitImageUpdate);
886};
Brian Carlstrom7940e442013-07-12 13:46:57 -0700887
Ian Rogers3d504072014-03-01 09:16:49 -0800888void CompilerDriver::UpdateImageClasses(TimingLogger* timings) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700889 if (IsImage()) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -0700890 TimingLogger::ScopedTiming t("UpdateImageClasses", timings);
Andreas Gampeb0f370e2014-09-25 22:51:40 -0700891
892 Runtime* current = Runtime::Current();
893
894 // Suspend all threads.
895 current->GetThreadList()->SuspendAll();
896
897 std::string error_msg;
898 std::unique_ptr<ClinitImageUpdate> update(ClinitImageUpdate::Create(image_classes_.get(),
899 Thread::Current(),
900 current->GetClassLinker(),
901 &error_msg));
902 CHECK(update.get() != nullptr) << error_msg; // TODO: Soft failure?
903
904 // Do the marking.
905 update->Walk();
906
907 // Resume threads.
908 current->GetThreadList()->ResumeAll();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700909 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700910}
911
Mathieu Chartier590fee92013-09-13 13:46:47 -0700912bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx) {
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700913 if (IsImage() &&
Ian Rogersdfb325e2013-10-30 01:00:44 -0700914 IsImageClass(dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_))) {
Andreas Gampe58a5af82014-07-31 16:23:49 -0700915 {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700916 ScopedObjectAccess soa(Thread::Current());
917 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
918 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
Andreas Gampe58a5af82014-07-31 16:23:49 -0700919 if (resolved_class == nullptr) {
920 // Erroneous class.
921 stats_->TypeNotInDexCache();
922 return false;
923 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700924 }
925 stats_->TypeInDexCache();
926 return true;
927 } else {
928 stats_->TypeNotInDexCache();
929 return false;
930 }
931}
932
933bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
934 uint32_t string_idx) {
935 // See also Compiler::ResolveDexFile
936
937 bool result = false;
938 if (IsImage()) {
939 // We resolve all const-string strings when building for the image.
940 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700941 StackHandleScope<1> hs(soa.Self());
942 Handle<mirror::DexCache> dex_cache(
943 hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(dex_file)));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700944 Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache);
945 result = true;
946 }
947 if (result) {
948 stats_->StringInDexCache();
949 } else {
950 stats_->StringNotInDexCache();
951 }
952 return result;
953}
954
955bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
956 uint32_t type_idx,
957 bool* type_known_final, bool* type_known_abstract,
958 bool* equals_referrers_class) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700959 if (type_known_final != nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700960 *type_known_final = false;
961 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700962 if (type_known_abstract != nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700963 *type_known_abstract = false;
964 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700965 if (equals_referrers_class != nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700966 *equals_referrers_class = false;
967 }
968 ScopedObjectAccess soa(Thread::Current());
969 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
970 // Get type from dex cache assuming it was populated by the verifier
971 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700972 if (resolved_class == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700973 stats_->TypeNeedsAccessCheck();
974 return false; // Unknown class needs access checks.
975 }
976 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700977 if (equals_referrers_class != nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700978 *equals_referrers_class = (method_id.class_idx_ == type_idx);
979 }
980 mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700981 if (referrer_class == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700982 stats_->TypeNeedsAccessCheck();
983 return false; // Incomplete referrer knowledge needs access check.
984 }
985 // Perform access check, will return true if access is ok or false if we're going to have to
986 // check this at runtime (for example for class loaders).
987 bool result = referrer_class->CanAccess(resolved_class);
988 if (result) {
989 stats_->TypeDoesntNeedAccessCheck();
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700990 if (type_known_final != nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700991 *type_known_final = resolved_class->IsFinal() && !resolved_class->IsArrayClass();
992 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700993 if (type_known_abstract != nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700994 *type_known_abstract = resolved_class->IsAbstract() && !resolved_class->IsArrayClass();
995 }
996 } else {
997 stats_->TypeNeedsAccessCheck();
998 }
999 return result;
1000}
1001
1002bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
1003 const DexFile& dex_file,
1004 uint32_t type_idx) {
1005 ScopedObjectAccess soa(Thread::Current());
1006 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
1007 // Get type from dex cache assuming it was populated by the verifier.
1008 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001009 if (resolved_class == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001010 stats_->TypeNeedsAccessCheck();
1011 return false; // Unknown class needs access checks.
1012 }
1013 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
1014 mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001015 if (referrer_class == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001016 stats_->TypeNeedsAccessCheck();
1017 return false; // Incomplete referrer knowledge needs access check.
1018 }
1019 // Perform access and instantiable checks, will return true if access is ok or false if we're
1020 // going to have to check this at runtime (for example for class loaders).
1021 bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
1022 if (result) {
1023 stats_->TypeDoesntNeedAccessCheck();
1024 } else {
1025 stats_->TypeNeedsAccessCheck();
1026 }
1027 return result;
1028}
1029
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001030bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
1031 bool* is_type_initialized, bool* use_direct_type_ptr,
Mathieu Chartier8668c3c2014-04-24 16:48:11 -07001032 uintptr_t* direct_type_ptr, bool* out_is_finalizable) {
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001033 ScopedObjectAccess soa(Thread::Current());
1034 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
1035 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
1036 if (resolved_class == nullptr) {
1037 return false;
1038 }
Igor Murashkind6dee672014-10-16 18:36:16 -07001039 if (GetCompilerOptions().GetCompilePic()) {
1040 // Do not allow a direct class pointer to be used when compiling for position-independent
1041 return false;
1042 }
Mathieu Chartier8668c3c2014-04-24 16:48:11 -07001043 *out_is_finalizable = resolved_class->IsFinalizable();
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001044 const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot();
Alex Light6e183f22014-07-18 14:57:04 -07001045 const bool support_boot_image_fixup = GetSupportBootImageFixup();
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001046 if (compiling_boot) {
1047 // boot -> boot class pointers.
1048 // True if the class is in the image at boot compiling time.
1049 const bool is_image_class = IsImage() && IsImageClass(
1050 dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_));
1051 // True if pc relative load works.
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001052 if (is_image_class && support_boot_image_fixup) {
1053 *is_type_initialized = resolved_class->IsInitialized();
1054 *use_direct_type_ptr = false;
1055 *direct_type_ptr = 0;
1056 return true;
1057 } else {
1058 return false;
1059 }
1060 } else {
1061 // True if the class is in the image at app compiling time.
1062 const bool class_in_image =
1063 Runtime::Current()->GetHeap()->FindSpaceFromObject(resolved_class, false)->IsImageSpace();
Alex Light6e183f22014-07-18 14:57:04 -07001064 if (class_in_image && support_boot_image_fixup) {
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001065 // boot -> app class pointers.
1066 *is_type_initialized = resolved_class->IsInitialized();
Alex Lighta59dd802014-07-02 16:28:08 -07001067 // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
1068 *use_direct_type_ptr = !GetCompilerOptions().GetIncludePatchInformation();
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001069 *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
1070 return true;
1071 } else {
1072 // app -> app class pointers.
1073 // Give up because app does not have an image and class
1074 // isn't created at compile time. TODO: implement this
1075 // if/when each app gets an image.
1076 return false;
1077 }
1078 }
1079}
1080
Fred Shihe7f82e22014-08-06 10:46:37 -07001081bool CompilerDriver::CanEmbedReferenceTypeInCode(ClassReference* ref,
1082 bool* use_direct_ptr,
1083 uintptr_t* direct_type_ptr) {
1084 CHECK(ref != nullptr);
1085 CHECK(use_direct_ptr != nullptr);
1086 CHECK(direct_type_ptr != nullptr);
1087
1088 ScopedObjectAccess soa(Thread::Current());
1089 mirror::Class* reference_class = mirror::Reference::GetJavaLangRefReference();
Andreas Gampe928f72b2014-09-09 19:53:48 -07001090 bool is_initialized = false;
Fred Shihe7f82e22014-08-06 10:46:37 -07001091 bool unused_finalizable;
1092 // Make sure we have a finished Reference class object before attempting to use it.
1093 if (!CanEmbedTypeInCode(*reference_class->GetDexCache()->GetDexFile(),
1094 reference_class->GetDexTypeIndex(), &is_initialized,
1095 use_direct_ptr, direct_type_ptr, &unused_finalizable) ||
1096 !is_initialized) {
1097 return false;
1098 }
1099 ref->first = &reference_class->GetDexFile();
1100 ref->second = reference_class->GetDexClassDefIndex();
1101 return true;
1102}
1103
1104uint32_t CompilerDriver::GetReferenceSlowFlagOffset() const {
1105 ScopedObjectAccess soa(Thread::Current());
1106 mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
1107 DCHECK(klass->IsInitialized());
1108 return klass->GetSlowPathFlagOffset().Uint32Value();
1109}
1110
1111uint32_t CompilerDriver::GetReferenceDisableFlagOffset() const {
1112 ScopedObjectAccess soa(Thread::Current());
1113 mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
1114 DCHECK(klass->IsInitialized());
1115 return klass->GetDisableIntrinsicFlagOffset().Uint32Value();
1116}
1117
Vladimir Markobe0e5462014-02-26 11:24:15 +00001118void CompilerDriver::ProcessedInstanceField(bool resolved) {
1119 if (!resolved) {
1120 stats_->UnresolvedInstanceField();
1121 } else {
1122 stats_->ResolvedInstanceField();
1123 }
1124}
1125
1126void CompilerDriver::ProcessedStaticField(bool resolved, bool local) {
1127 if (!resolved) {
1128 stats_->UnresolvedStaticField();
1129 } else if (local) {
1130 stats_->ResolvedLocalStaticField();
1131 } else {
1132 stats_->ResolvedStaticField();
1133 }
1134}
1135
Vladimir Markof096aad2014-01-23 15:51:58 +00001136void CompilerDriver::ProcessedInvoke(InvokeType invoke_type, int flags) {
1137 stats_->ProcessedInvoke(invoke_type, flags);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001138}
1139
Nicolas Geoffraye5038322014-07-04 09:41:32 +01001140mirror::ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
1141 const DexCompilationUnit* mUnit,
1142 bool is_put,
1143 const ScopedObjectAccess& soa) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001144 // Try to resolve the field and compiling method's class.
1145 mirror::ArtField* resolved_field;
1146 mirror::Class* referrer_class;
1147 mirror::DexCache* dex_cache;
1148 {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001149 StackHandleScope<3> hs(soa.Self());
1150 Handle<mirror::DexCache> dex_cache_handle(
1151 hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
1152 Handle<mirror::ClassLoader> class_loader_handle(
1153 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
1154 Handle<mirror::ArtField> resolved_field_handle(hs.NewHandle(
1155 ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false)));
1156 referrer_class = (resolved_field_handle.Get() != nullptr)
1157 ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
1158 resolved_field = resolved_field_handle.Get();
1159 dex_cache = dex_cache_handle.Get();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001160 }
Nicolas Geoffraye5038322014-07-04 09:41:32 +01001161 bool can_link = false;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001162 if (resolved_field != nullptr && referrer_class != nullptr) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001163 std::pair<bool, bool> fast_path = IsFastInstanceField(
Nicolas Geoffraye5038322014-07-04 09:41:32 +01001164 dex_cache, referrer_class, resolved_field, field_idx);
1165 can_link = is_put ? fast_path.second : fast_path.first;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001166 }
Nicolas Geoffraye5038322014-07-04 09:41:32 +01001167 ProcessedInstanceField(can_link);
1168 return can_link ? resolved_field : nullptr;
1169}
1170
1171bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
1172 bool is_put, MemberOffset* field_offset,
1173 bool* is_volatile) {
1174 ScopedObjectAccess soa(Thread::Current());
1175 StackHandleScope<1> hs(soa.Self());
1176 Handle<mirror::ArtField> resolved_field =
1177 hs.NewHandle(ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa));
1178
1179 if (resolved_field.Get() == nullptr) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001180 // Conservative defaults.
1181 *is_volatile = true;
1182 *field_offset = MemberOffset(static_cast<size_t>(-1));
Nicolas Geoffraye5038322014-07-04 09:41:32 +01001183 return false;
1184 } else {
1185 *is_volatile = resolved_field->IsVolatile();
1186 *field_offset = resolved_field->GetOffset();
1187 return true;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001188 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001189}
1190
1191bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
Vladimir Markobe0e5462014-02-26 11:24:15 +00001192 bool is_put, MemberOffset* field_offset,
1193 uint32_t* storage_index, bool* is_referrers_class,
Nicolas Geoffray19a19cf2014-10-22 16:07:05 +01001194 bool* is_volatile, bool* is_initialized,
1195 Primitive::Type* type) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001196 ScopedObjectAccess soa(Thread::Current());
Vladimir Markobe0e5462014-02-26 11:24:15 +00001197 // Try to resolve the field and compiling method's class.
1198 mirror::ArtField* resolved_field;
1199 mirror::Class* referrer_class;
1200 mirror::DexCache* dex_cache;
1201 {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001202 StackHandleScope<3> hs(soa.Self());
1203 Handle<mirror::DexCache> dex_cache_handle(
1204 hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
1205 Handle<mirror::ClassLoader> class_loader_handle(
1206 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
1207 Handle<mirror::ArtField> resolved_field_handle(hs.NewHandle(
1208 ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true)));
1209 referrer_class = (resolved_field_handle.Get() != nullptr)
1210 ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
1211 resolved_field = resolved_field_handle.Get();
1212 dex_cache = dex_cache_handle.Get();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001213 }
Vladimir Markobe0e5462014-02-26 11:24:15 +00001214 bool result = false;
1215 if (resolved_field != nullptr && referrer_class != nullptr) {
1216 *is_volatile = IsFieldVolatile(resolved_field);
1217 std::pair<bool, bool> fast_path = IsFastStaticField(
Vladimir Marko66c6d7b2014-10-16 15:41:48 +01001218 dex_cache, referrer_class, resolved_field, field_idx, storage_index);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001219 result = is_put ? fast_path.second : fast_path.first;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001220 }
Vladimir Marko66c6d7b2014-10-16 15:41:48 +01001221 if (result) {
1222 *field_offset = GetFieldOffset(resolved_field);
1223 *is_referrers_class = IsStaticFieldInReferrerClass(referrer_class, resolved_field);
1224 // *is_referrers_class == true implies no worrying about class initialization.
1225 *is_initialized = (*is_referrers_class) ||
1226 (IsStaticFieldsClassInitialized(referrer_class, resolved_field) &&
1227 CanAssumeTypeIsPresentInDexCache(*mUnit->GetDexFile(), *storage_index));
Nicolas Geoffray19a19cf2014-10-22 16:07:05 +01001228 *type = resolved_field->GetTypeAsPrimitiveType();
Vladimir Marko66c6d7b2014-10-16 15:41:48 +01001229 } else {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001230 // Conservative defaults.
1231 *is_volatile = true;
1232 *field_offset = MemberOffset(static_cast<size_t>(-1));
1233 *storage_index = -1;
1234 *is_referrers_class = false;
1235 *is_initialized = false;
Nicolas Geoffray19a19cf2014-10-22 16:07:05 +01001236 *type = Primitive::kPrimVoid;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001237 }
1238 ProcessedStaticField(result, *is_referrers_class);
1239 return result;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001240}
1241
Ian Rogers83883d72013-10-21 21:07:24 -07001242void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type,
1243 bool no_guarantee_of_dex_cache_entry,
Igor Murashkind6dee672014-10-16 18:36:16 -07001244 const mirror::Class* referrer_class,
Brian Carlstromea46f952013-07-30 01:26:50 -07001245 mirror::ArtMethod* method,
Vladimir Markof096aad2014-01-23 15:51:58 +00001246 int* stats_flags,
Ian Rogers83883d72013-10-21 21:07:24 -07001247 MethodReference* target_method,
Ian Rogers65ec92c2013-09-06 10:49:58 -07001248 uintptr_t* direct_code,
1249 uintptr_t* direct_method) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001250 // For direct and static methods compute possible direct_code and direct_method values, ie
1251 // an address for the Method* being invoked and an address of the code for that Method*.
1252 // For interface calls compute a value for direct_method that is the interface method being
1253 // invoked, so this can be passed to the out-of-line runtime support code.
Ian Rogers65ec92c2013-09-06 10:49:58 -07001254 *direct_code = 0;
1255 *direct_method = 0;
Igor Murashkind6dee672014-10-16 18:36:16 -07001256 bool use_dex_cache = GetCompilerOptions().GetCompilePic(); // Off by default
Mathieu Chartier590fee92013-09-13 13:46:47 -07001257 const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot();
Alex Lighta59dd802014-07-02 16:28:08 -07001258 // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
1259 const bool force_relocations = (compiling_boot ||
1260 GetCompilerOptions().GetIncludePatchInformation());
Elliott Hughes956af0f2014-12-11 14:34:28 -08001261 if (sharp_type != kStatic && sharp_type != kDirect) {
1262 return;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001263 }
Elliott Hughes956af0f2014-12-11 14:34:28 -08001264 // TODO: support patching on all architectures.
1265 use_dex_cache = use_dex_cache || (force_relocations && !support_boot_image_fixup_);
Ian Rogers83883d72013-10-21 21:07:24 -07001266 bool method_code_in_boot = (method->GetDeclaringClass()->GetClassLoader() == nullptr);
1267 if (!use_dex_cache) {
1268 if (!method_code_in_boot) {
1269 use_dex_cache = true;
1270 } else {
1271 bool has_clinit_trampoline =
1272 method->IsStatic() && !method->GetDeclaringClass()->IsInitialized();
1273 if (has_clinit_trampoline && (method->GetDeclaringClass() != referrer_class)) {
1274 // Ensure we run the clinit trampoline unless we are invoking a static method in the same
1275 // class.
1276 use_dex_cache = true;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001277 }
1278 }
Ian Rogers83883d72013-10-21 21:07:24 -07001279 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001280 if (method_code_in_boot) {
1281 *stats_flags |= kFlagDirectCallToBoot | kFlagDirectMethodToBoot;
Ian Rogers83883d72013-10-21 21:07:24 -07001282 }
Alex Lighta59dd802014-07-02 16:28:08 -07001283 if (!use_dex_cache && force_relocations) {
1284 if (!IsImage() || !IsImageClass(method->GetDeclaringClassDescriptor())) {
Ian Rogers83883d72013-10-21 21:07:24 -07001285 // We can only branch directly to Methods that are resolved in the DexCache.
1286 // Otherwise we won't invoke the resolution trampoline.
1287 use_dex_cache = true;
1288 }
1289 }
1290 // The method is defined not within this dex file. We need a dex cache slot within the current
1291 // dex file or direct pointers.
1292 bool must_use_direct_pointers = false;
1293 if (target_method->dex_file == method->GetDeclaringClass()->GetDexCache()->GetDexFile()) {
1294 target_method->dex_method_index = method->GetDexMethodIndex();
1295 } else {
Ian Rogers83883d72013-10-21 21:07:24 -07001296 if (no_guarantee_of_dex_cache_entry) {
1297 // See if the method is also declared in this dex cache.
Ian Rogerse0a02da2014-12-02 14:10:53 -08001298 uint32_t dex_method_idx =
1299 method->FindDexMethodIndexInOtherDexFile(*target_method->dex_file,
1300 target_method->dex_method_index);
Ian Rogers83883d72013-10-21 21:07:24 -07001301 if (dex_method_idx != DexFile::kDexNoIndex) {
1302 target_method->dex_method_index = dex_method_idx;
1303 } else {
Alex Lighta59dd802014-07-02 16:28:08 -07001304 if (force_relocations && !use_dex_cache) {
Jeff Hao49161ce2014-03-12 11:05:25 -07001305 target_method->dex_method_index = method->GetDexMethodIndex();
1306 target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
1307 }
Ian Rogers83883d72013-10-21 21:07:24 -07001308 must_use_direct_pointers = true;
1309 }
1310 }
1311 }
1312 if (use_dex_cache) {
1313 if (must_use_direct_pointers) {
1314 // Fail. Test above showed the only safe dispatch was via the dex cache, however, the direct
1315 // pointers are required as the dex cache lacks an appropriate entry.
1316 VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
1317 } else {
1318 *type = sharp_type;
1319 }
1320 } else {
Alex Lighta59dd802014-07-02 16:28:08 -07001321 bool method_in_image =
Vladimir Markoa51a0b02014-05-21 12:08:39 +01001322 Runtime::Current()->GetHeap()->FindSpaceFromObject(method, false)->IsImageSpace();
Alex Lighta59dd802014-07-02 16:28:08 -07001323 if (method_in_image || compiling_boot) {
1324 // We know we must be able to get to the method in the image, so use that pointer.
Vladimir Markoa51a0b02014-05-21 12:08:39 +01001325 CHECK(!method->IsAbstract());
Ian Rogers83883d72013-10-21 21:07:24 -07001326 *type = sharp_type;
Alex Lighta59dd802014-07-02 16:28:08 -07001327 *direct_method = force_relocations ? -1 : reinterpret_cast<uintptr_t>(method);
1328 *direct_code = force_relocations ? -1 : compiler_->GetEntryPointOf(method);
Vladimir Markoa51a0b02014-05-21 12:08:39 +01001329 target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
1330 target_method->dex_method_index = method->GetDexMethodIndex();
1331 } else if (!must_use_direct_pointers) {
1332 // Set the code and rely on the dex cache for the method.
1333 *type = sharp_type;
Alex Lighta59dd802014-07-02 16:28:08 -07001334 if (force_relocations) {
1335 *direct_code = -1;
1336 target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
1337 target_method->dex_method_index = method->GetDexMethodIndex();
1338 } else {
1339 *direct_code = compiler_->GetEntryPointOf(method);
1340 }
Ian Rogers83883d72013-10-21 21:07:24 -07001341 } else {
Vladimir Markoa51a0b02014-05-21 12:08:39 +01001342 // Direct pointers were required but none were available.
1343 VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
Ian Rogers83883d72013-10-21 21:07:24 -07001344 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001345 }
1346}
1347
1348bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc,
Ian Rogers65ec92c2013-09-06 10:49:58 -07001349 bool update_stats, bool enable_devirtualization,
1350 InvokeType* invoke_type, MethodReference* target_method,
1351 int* vtable_idx, uintptr_t* direct_code,
1352 uintptr_t* direct_method) {
Vladimir Markof096aad2014-01-23 15:51:58 +00001353 InvokeType orig_invoke_type = *invoke_type;
1354 int stats_flags = 0;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001355 ScopedObjectAccess soa(Thread::Current());
Vladimir Markof096aad2014-01-23 15:51:58 +00001356 // Try to resolve the method and compiling method's class.
1357 mirror::ArtMethod* resolved_method;
1358 mirror::Class* referrer_class;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001359 StackHandleScope<3> hs(soa.Self());
1360 Handle<mirror::DexCache> dex_cache(
1361 hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
1362 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
1363 soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
Vladimir Markof096aad2014-01-23 15:51:58 +00001364 {
1365 uint32_t method_idx = target_method->dex_method_index;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001366 Handle<mirror::ArtMethod> resolved_method_handle(hs.NewHandle(
1367 ResolveMethod(soa, dex_cache, class_loader, mUnit, method_idx, orig_invoke_type)));
1368 referrer_class = (resolved_method_handle.Get() != nullptr)
Vladimir Markof096aad2014-01-23 15:51:58 +00001369 ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit) : nullptr;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001370 resolved_method = resolved_method_handle.Get();
Vladimir Markof096aad2014-01-23 15:51:58 +00001371 }
1372 bool result = false;
1373 if (resolved_method != nullptr) {
1374 *vtable_idx = GetResolvedMethodVTableIndex(resolved_method, orig_invoke_type);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001375
Nicolas Geoffraye53798a2014-12-01 10:31:54 +00001376 if (enable_devirtualization && mUnit->GetVerifiedMethod() != nullptr) {
Vladimir Markof096aad2014-01-23 15:51:58 +00001377 const MethodReference* devirt_target = mUnit->GetVerifiedMethod()->GetDevirtTarget(dex_pc);
1378
1379 stats_flags = IsFastInvoke(
1380 soa, dex_cache, class_loader, mUnit, referrer_class, resolved_method,
1381 invoke_type, target_method, devirt_target, direct_code, direct_method);
1382 result = stats_flags != 0;
1383 } else {
1384 // Devirtualization not enabled. Inline IsFastInvoke(), dropping the devirtualization parts.
1385 if (UNLIKELY(referrer_class == nullptr) ||
1386 UNLIKELY(!referrer_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001387 resolved_method, dex_cache.Get(),
Vladimir Markof096aad2014-01-23 15:51:58 +00001388 target_method->dex_method_index)) ||
1389 *invoke_type == kSuper) {
1390 // Slow path. (Without devirtualization, all super calls go slow path as well.)
1391 } else {
1392 // Sharpening failed so generate a regular resolved method dispatch.
1393 stats_flags = kFlagMethodResolved;
1394 GetCodeAndMethodForDirectCall(invoke_type, *invoke_type, false, referrer_class, resolved_method,
1395 &stats_flags, target_method, direct_code, direct_method);
1396 result = true;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001397 }
1398 }
1399 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001400 if (!result) {
1401 // Conservative defaults.
1402 *vtable_idx = -1;
1403 *direct_code = 0u;
1404 *direct_method = 0u;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001405 }
1406 if (update_stats) {
Vladimir Markof096aad2014-01-23 15:51:58 +00001407 ProcessedInvoke(orig_invoke_type, stats_flags);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001408 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001409 return result;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001410}
1411
Vladimir Marko2730db02014-01-27 11:15:17 +00001412const VerifiedMethod* CompilerDriver::GetVerifiedMethod(const DexFile* dex_file,
1413 uint32_t method_idx) const {
1414 MethodReference ref(dex_file, method_idx);
1415 return verification_results_->GetVerifiedMethod(ref);
1416}
1417
1418bool CompilerDriver::IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001419 if (!compiler_options_->IsVerificationEnabled()) {
1420 // If we didn't verify, every cast has to be treated as non-safe.
1421 return false;
1422 }
Vladimir Marko2730db02014-01-27 11:15:17 +00001423 DCHECK(mUnit->GetVerifiedMethod() != nullptr);
1424 bool result = mUnit->GetVerifiedMethod()->IsSafeCast(dex_pc);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001425 if (result) {
1426 stats_->SafeCast();
1427 } else {
1428 stats_->NotASafeCast();
1429 }
1430 return result;
1431}
1432
Brian Carlstrom7940e442013-07-12 13:46:57 -07001433class ParallelCompilationManager {
1434 public:
1435 typedef void Callback(const ParallelCompilationManager* manager, size_t index);
1436
1437 ParallelCompilationManager(ClassLinker* class_linker,
1438 jobject class_loader,
1439 CompilerDriver* compiler,
1440 const DexFile* dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001441 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001442 ThreadPool* thread_pool)
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001443 : index_(0),
1444 class_linker_(class_linker),
Brian Carlstrom7940e442013-07-12 13:46:57 -07001445 class_loader_(class_loader),
1446 compiler_(compiler),
1447 dex_file_(dex_file),
Andreas Gampede7b4362014-07-28 18:38:57 -07001448 dex_files_(dex_files),
Ian Rogers3d504072014-03-01 09:16:49 -08001449 thread_pool_(thread_pool) {}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001450
1451 ClassLinker* GetClassLinker() const {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001452 CHECK(class_linker_ != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001453 return class_linker_;
1454 }
1455
1456 jobject GetClassLoader() const {
1457 return class_loader_;
1458 }
1459
1460 CompilerDriver* GetCompiler() const {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001461 CHECK(compiler_ != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001462 return compiler_;
1463 }
1464
1465 const DexFile* GetDexFile() const {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001466 CHECK(dex_file_ != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001467 return dex_file_;
1468 }
1469
Andreas Gampede7b4362014-07-28 18:38:57 -07001470 const std::vector<const DexFile*>& GetDexFiles() const {
1471 return dex_files_;
1472 }
1473
Brian Carlstrom7940e442013-07-12 13:46:57 -07001474 void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
1475 Thread* self = Thread::Current();
1476 self->AssertNoPendingException();
1477 CHECK_GT(work_units, 0U);
1478
Ian Rogers3e5cf302014-05-20 16:40:37 -07001479 index_.StoreRelaxed(begin);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001480 for (size_t i = 0; i < work_units; ++i) {
Sebastien Hertz501baec2013-12-13 12:02:36 +01001481 thread_pool_->AddTask(self, new ForAllClosure(this, end, callback));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001482 }
1483 thread_pool_->StartWorkers(self);
1484
1485 // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
1486 // thread destructor's called below perform join).
1487 CHECK_NE(self->GetState(), kRunnable);
1488
1489 // Wait for all the worker threads to finish.
1490 thread_pool_->Wait(self, true, false);
1491 }
1492
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001493 size_t NextIndex() {
Ian Rogers3e5cf302014-05-20 16:40:37 -07001494 return index_.FetchAndAddSequentiallyConsistent(1);
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001495 }
1496
Brian Carlstrom7940e442013-07-12 13:46:57 -07001497 private:
Brian Carlstrom7940e442013-07-12 13:46:57 -07001498 class ForAllClosure : public Task {
1499 public:
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001500 ForAllClosure(ParallelCompilationManager* manager, size_t end, Callback* callback)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001501 : manager_(manager),
Brian Carlstrom7940e442013-07-12 13:46:57 -07001502 end_(end),
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001503 callback_(callback) {}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001504
1505 virtual void Run(Thread* self) {
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001506 while (true) {
1507 const size_t index = manager_->NextIndex();
1508 if (UNLIKELY(index >= end_)) {
1509 break;
1510 }
1511 callback_(manager_, index);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001512 self->AssertNoPendingException();
1513 }
1514 }
1515
1516 virtual void Finalize() {
1517 delete this;
1518 }
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -07001519
Brian Carlstrom7940e442013-07-12 13:46:57 -07001520 private:
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001521 ParallelCompilationManager* const manager_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001522 const size_t end_;
Bernhard Rosenkränzer46053622013-12-12 02:15:52 +01001523 Callback* const callback_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001524 };
1525
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001526 AtomicInteger index_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001527 ClassLinker* const class_linker_;
1528 const jobject class_loader_;
1529 CompilerDriver* const compiler_;
1530 const DexFile* const dex_file_;
Andreas Gampede7b4362014-07-28 18:38:57 -07001531 const std::vector<const DexFile*>& dex_files_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001532 ThreadPool* const thread_pool_;
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001533
1534 DISALLOW_COPY_AND_ASSIGN(ParallelCompilationManager);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001535};
1536
Jeff Hao0e49b422013-11-08 12:16:56 -08001537// A fast version of SkipClass above if the class pointer is available
1538// that avoids the expensive FindInClassPath search.
1539static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Class* klass)
1540 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001541 DCHECK(klass != nullptr);
Jeff Hao0e49b422013-11-08 12:16:56 -08001542 const DexFile& original_dex_file = *klass->GetDexCache()->GetDexFile();
1543 if (&dex_file != &original_dex_file) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001544 if (class_loader == nullptr) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001545 LOG(WARNING) << "Skipping class " << PrettyDescriptor(klass) << " from "
1546 << dex_file.GetLocation() << " previously found in "
1547 << original_dex_file.GetLocation();
1548 }
1549 return true;
1550 }
1551 return false;
1552}
1553
Mathieu Chartier70b63482014-06-27 17:19:04 -07001554static void CheckAndClearResolveException(Thread* self)
1555 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1556 CHECK(self->IsExceptionPending());
1557 mirror::Throwable* exception = self->GetException(nullptr);
Ian Rogers1ff3c982014-08-12 02:30:58 -07001558 std::string temp;
1559 const char* descriptor = exception->GetClass()->GetDescriptor(&temp);
1560 const char* expected_exceptions[] = {
1561 "Ljava/lang/IllegalAccessError;",
1562 "Ljava/lang/IncompatibleClassChangeError;",
1563 "Ljava/lang/InstantiationError;",
Brian Carlstrom898fcb52014-08-25 23:07:30 -07001564 "Ljava/lang/LinkageError;",
Ian Rogers1ff3c982014-08-12 02:30:58 -07001565 "Ljava/lang/NoClassDefFoundError;",
1566 "Ljava/lang/NoSuchFieldError;",
1567 "Ljava/lang/NoSuchMethodError;"
1568 };
1569 bool found = false;
1570 for (size_t i = 0; (found == false) && (i < arraysize(expected_exceptions)); ++i) {
1571 if (strcmp(descriptor, expected_exceptions[i]) == 0) {
1572 found = true;
1573 }
1574 }
1575 if (!found) {
Brian Carlstrom898fcb52014-08-25 23:07:30 -07001576 LOG(FATAL) << "Unexpected exception " << exception->Dump();
Mathieu Chartier70b63482014-06-27 17:19:04 -07001577 }
1578 self->ClearException();
1579}
1580
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001581static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager,
1582 size_t class_def_index)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001583 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001584 ATRACE_CALL();
Ian Rogersbe7149f2013-08-20 09:29:39 -07001585 Thread* self = Thread::Current();
1586 jobject jclass_loader = manager->GetClassLoader();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001587 const DexFile& dex_file = *manager->GetDexFile();
Ian Rogersbe7149f2013-08-20 09:29:39 -07001588 ClassLinker* class_linker = manager->GetClassLinker();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001589
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001590 // If an instance field is final then we need to have a barrier on the return, static final
1591 // fields are assigned within the lock held for class initialization. Conservatively assume
1592 // constructor barriers are always required.
1593 bool requires_constructor_barrier = true;
1594
Brian Carlstrom7940e442013-07-12 13:46:57 -07001595 // Method and Field are the worst. We can't resolve without either
1596 // context from the code use (to disambiguate virtual vs direct
1597 // method and instance vs static field) or from class
1598 // definitions. While the compiler will resolve what it can as it
1599 // needs it, here we try to resolve fields and methods used in class
1600 // definitions, since many of them many never be referenced by
1601 // generated code.
1602 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogers68b56852014-08-29 20:19:11 -07001603 ScopedObjectAccess soa(self);
1604 StackHandleScope<2> hs(soa.Self());
1605 Handle<mirror::ClassLoader> class_loader(
1606 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1607 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1608 // Resolve the class.
1609 mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
1610 class_loader);
1611 bool resolve_fields_and_methods;
1612 if (klass == nullptr) {
1613 // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
1614 // attempt to resolve methods and fields when there is no declaring class.
1615 CheckAndClearResolveException(soa.Self());
1616 resolve_fields_and_methods = false;
1617 } else {
1618 // We successfully resolved a class, should we skip it?
1619 if (SkipClass(jclass_loader, dex_file, klass)) {
1620 return;
Brian Carlstromcb5f5e52013-09-23 17:48:16 -07001621 }
Ian Rogers68b56852014-08-29 20:19:11 -07001622 // We want to resolve the methods and fields eagerly.
1623 resolve_fields_and_methods = true;
1624 }
1625 // Note the class_data pointer advances through the headers,
1626 // static fields, instance fields, direct methods, and virtual
1627 // methods.
Ian Rogers13735952014-10-08 12:43:28 -07001628 const uint8_t* class_data = dex_file.GetClassData(class_def);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001629 if (class_data == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001630 // Empty class such as a marker interface.
1631 requires_constructor_barrier = false;
1632 } else {
1633 ClassDataItemIterator it(dex_file, class_data);
1634 while (it.HasNextStaticField()) {
1635 if (resolve_fields_and_methods) {
1636 mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1637 dex_cache, class_loader, true);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001638 if (field == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001639 CheckAndClearResolveException(soa.Self());
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001640 }
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001641 }
Ian Rogers68b56852014-08-29 20:19:11 -07001642 it.Next();
1643 }
1644 // We require a constructor barrier if there are final instance fields.
1645 requires_constructor_barrier = false;
1646 while (it.HasNextInstanceField()) {
Andreas Gampe51829322014-08-25 15:05:04 -07001647 if (it.MemberIsFinal()) {
Ian Rogers68b56852014-08-29 20:19:11 -07001648 requires_constructor_barrier = true;
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001649 }
1650 if (resolve_fields_and_methods) {
Ian Rogers68b56852014-08-29 20:19:11 -07001651 mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1652 dex_cache, class_loader, false);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001653 if (field == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001654 CheckAndClearResolveException(soa.Self());
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001655 }
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001656 }
Ian Rogers68b56852014-08-29 20:19:11 -07001657 it.Next();
1658 }
1659 if (resolve_fields_and_methods) {
1660 while (it.HasNextDirectMethod()) {
1661 mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
1662 dex_cache, class_loader,
1663 NullHandle<mirror::ArtMethod>(),
1664 it.GetMethodInvokeType(class_def));
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001665 if (method == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001666 CheckAndClearResolveException(soa.Self());
1667 }
1668 it.Next();
1669 }
1670 while (it.HasNextVirtualMethod()) {
1671 mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
1672 dex_cache, class_loader,
1673 NullHandle<mirror::ArtMethod>(),
1674 it.GetMethodInvokeType(class_def));
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001675 if (method == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001676 CheckAndClearResolveException(soa.Self());
1677 }
1678 it.Next();
1679 }
1680 DCHECK(!it.HasNext());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001681 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001682 }
1683 if (requires_constructor_barrier) {
Ian Rogersbe7149f2013-08-20 09:29:39 -07001684 manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001685 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001686}
1687
1688static void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
1689 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1690 // Class derived values are more complicated, they require the linker and loader.
1691 ScopedObjectAccess soa(Thread::Current());
1692 ClassLinker* class_linker = manager->GetClassLinker();
1693 const DexFile& dex_file = *manager->GetDexFile();
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001694 StackHandleScope<2> hs(soa.Self());
1695 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1696 Handle<mirror::ClassLoader> class_loader(
1697 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader())));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001698 mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
1699
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001700 if (klass == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001701 CHECK(soa.Self()->IsExceptionPending());
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001702 mirror::Throwable* exception = soa.Self()->GetException(nullptr);
Ian Rogersa436fde2013-08-27 23:34:06 -07001703 VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
Mathieu Chartierf8322842014-05-16 10:59:25 -07001704 if (exception->GetClass()->DescriptorEquals("Ljava/lang/OutOfMemoryError;")) {
Ian Rogersa436fde2013-08-27 23:34:06 -07001705 // There's little point continuing compilation if the heap is exhausted.
1706 LOG(FATAL) << "Out of memory during type resolution for compilation";
1707 }
1708 soa.Self()->ClearException();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001709 }
1710}
1711
1712void CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001713 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001714 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001715 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1716
1717 // TODO: we could resolve strings here, although the string table is largely filled with class
1718 // and method names.
1719
Andreas Gampede7b4362014-07-28 18:38:57 -07001720 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1721 thread_pool);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001722 if (IsImage()) {
1723 // For images we resolve all types, such as array, whereas for applications just those with
1724 // classdefs are resolved by ResolveClassFieldsAndMethods.
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001725 TimingLogger::ScopedTiming t("Resolve Types", timings);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001726 context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
1727 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001728
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001729 TimingLogger::ScopedTiming t("Resolve MethodsAndFields", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001730 context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001731}
1732
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001733void CompilerDriver::SetVerified(jobject class_loader, const std::vector<const DexFile*>& dex_files,
1734 ThreadPool* thread_pool, TimingLogger* timings) {
1735 for (size_t i = 0; i != dex_files.size(); ++i) {
1736 const DexFile* dex_file = dex_files[i];
1737 CHECK(dex_file != nullptr);
1738 SetVerifiedDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
1739 }
1740}
1741
Brian Carlstrom7940e442013-07-12 13:46:57 -07001742void CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001743 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001744 for (size_t i = 0; i != dex_files.size(); ++i) {
1745 const DexFile* dex_file = dex_files[i];
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001746 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -07001747 VerifyDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001748 }
1749}
1750
1751static void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index)
1752 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001753 ATRACE_CALL();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001754 ScopedObjectAccess soa(Thread::Current());
Jeff Hao0e49b422013-11-08 12:16:56 -08001755 const DexFile& dex_file = *manager->GetDexFile();
1756 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1757 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1758 ClassLinker* class_linker = manager->GetClassLinker();
1759 jobject jclass_loader = manager->GetClassLoader();
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001760 StackHandleScope<3> hs(soa.Self());
1761 Handle<mirror::ClassLoader> class_loader(
1762 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1763 Handle<mirror::Class> klass(
1764 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1765 if (klass.Get() == nullptr) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001766 CHECK(soa.Self()->IsExceptionPending());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001767 soa.Self()->ClearException();
1768
1769 /*
1770 * At compile time, we can still structurally verify the class even if FindClass fails.
1771 * This is to ensure the class is structurally sound for compilation. An unsound class
1772 * will be rejected by the verifier and later skipped during compilation in the compiler.
1773 */
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001774 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001775 std::string error_msg;
Ian Rogers7b078e82014-09-10 14:44:24 -07001776 if (verifier::MethodVerifier::VerifyClass(soa.Self(), &dex_file, dex_cache, class_loader,
1777 &class_def, true, &error_msg) ==
Brian Carlstrom7940e442013-07-12 13:46:57 -07001778 verifier::MethodVerifier::kHardFailure) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001779 LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001780 << " because: " << error_msg;
1781 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001782 } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
1783 CHECK(klass->IsResolved()) << PrettyClass(klass.Get());
Ian Rogers7b078e82014-09-10 14:44:24 -07001784 class_linker->VerifyClass(soa.Self(), klass);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001785
1786 if (klass->IsErroneous()) {
1787 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1788 CHECK(soa.Self()->IsExceptionPending());
1789 soa.Self()->ClearException();
1790 }
1791
1792 CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001793 << PrettyDescriptor(klass.Get()) << ": state=" << klass->GetStatus();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001794 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001795 soa.Self()->AssertNoPendingException();
1796}
1797
1798void CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001799 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001800 ThreadPool* thread_pool, TimingLogger* timings) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001801 TimingLogger::ScopedTiming t("Verify Dex File", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001802 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Andreas Gampede7b4362014-07-28 18:38:57 -07001803 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1804 thread_pool);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001805 context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001806}
1807
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001808static void SetVerifiedClass(const ParallelCompilationManager* manager, size_t class_def_index)
1809 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1810 ATRACE_CALL();
1811 ScopedObjectAccess soa(Thread::Current());
1812 const DexFile& dex_file = *manager->GetDexFile();
1813 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1814 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1815 ClassLinker* class_linker = manager->GetClassLinker();
1816 jobject jclass_loader = manager->GetClassLoader();
1817 StackHandleScope<3> hs(soa.Self());
1818 Handle<mirror::ClassLoader> class_loader(
1819 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1820 Handle<mirror::Class> klass(
1821 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1822 // Class might have failed resolution. Then don't set it to verified.
1823 if (klass.Get() != nullptr) {
1824 // Only do this if the class is resolved. If even resolution fails, quickening will go very,
1825 // very wrong.
1826 if (klass->IsResolved()) {
1827 if (klass->GetStatus() < mirror::Class::kStatusVerified) {
1828 ObjectLock<mirror::Class> lock(soa.Self(), klass);
1829 klass->SetStatus(mirror::Class::kStatusVerified, soa.Self());
1830 }
1831 // Record the final class status if necessary.
1832 ClassReference ref(manager->GetDexFile(), class_def_index);
1833 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
1834 }
Andreas Gampe61ff0092014-09-16 11:23:23 -07001835 } else {
1836 Thread* self = soa.Self();
1837 DCHECK(self->IsExceptionPending());
1838 self->ClearException();
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001839 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001840}
1841
1842void CompilerDriver::SetVerifiedDexFile(jobject class_loader, const DexFile& dex_file,
1843 const std::vector<const DexFile*>& dex_files,
1844 ThreadPool* thread_pool, TimingLogger* timings) {
1845 TimingLogger::ScopedTiming t("Verify Dex File", timings);
1846 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1847 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1848 thread_pool);
1849 context.ForAll(0, dex_file.NumClassDefs(), SetVerifiedClass, thread_count_);
1850}
1851
Brian Carlstrom7940e442013-07-12 13:46:57 -07001852static void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
1853 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001854 ATRACE_CALL();
Jeff Hao0e49b422013-11-08 12:16:56 -08001855 jobject jclass_loader = manager->GetClassLoader();
1856 const DexFile& dex_file = *manager->GetDexFile();
1857 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Jeff Haobcdbbfe2013-11-08 18:03:22 -08001858 const DexFile::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
1859 const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_);
Ian Rogersfc0e94b2013-09-23 23:51:32 -07001860
Brian Carlstrom7940e442013-07-12 13:46:57 -07001861 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001862 StackHandleScope<3> hs(soa.Self());
1863 Handle<mirror::ClassLoader> class_loader(
1864 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1865 Handle<mirror::Class> klass(
1866 hs.NewHandle(manager->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
Jeff Hao0e49b422013-11-08 12:16:56 -08001867
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001868 if (klass.Get() != nullptr && !SkipClass(jclass_loader, dex_file, klass.Get())) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001869 // Only try to initialize classes that were successfully verified.
1870 if (klass->IsVerified()) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001871 // Attempt to initialize the class but bail if we either need to initialize the super-class
1872 // or static fields.
Ian Rogers7b078e82014-09-10 14:44:24 -07001873 manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001874 if (!klass->IsInitialized()) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001875 // We don't want non-trivial class initialization occurring on multiple threads due to
1876 // deadlock problems. For example, a parent class is initialized (holding its lock) that
1877 // refers to a sub-class in its static/class initializer causing it to try to acquire the
1878 // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
1879 // after first initializing its parents, whose locks are acquired. This leads to a
1880 // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
1881 // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
1882 // than use a special Object for the purpose we use the Class of java.lang.Class.
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001883 Handle<mirror::Class> h_klass(hs.NewHandle(klass->GetClass()));
Mathieu Chartierdb2633c2014-05-16 09:59:29 -07001884 ObjectLock<mirror::Class> lock(soa.Self(), h_klass);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001885 // Attempt to initialize allowing initialization of parent classes but still not static
1886 // fields.
Ian Rogers7b078e82014-09-10 14:44:24 -07001887 manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001888 if (!klass->IsInitialized()) {
1889 // We need to initialize static fields, we only do this for image classes that aren't
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001890 // marked with the $NoPreloadHolder (which implies this should not be initialized early).
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001891 bool can_init_static_fields = manager->GetCompiler()->IsImage() &&
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001892 manager->GetCompiler()->IsImageClass(descriptor) &&
1893 !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001894 if (can_init_static_fields) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001895 VLOG(compiler) << "Initializing: " << descriptor;
Ian Rogersc45b8b52014-05-03 01:39:59 -07001896 // TODO multithreading support. We should ensure the current compilation thread has
1897 // exclusive access to the runtime and the transaction. To achieve this, we could use
1898 // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity
1899 // checks in Thread::AssertThreadSuspensionIsAllowable.
1900 Runtime* const runtime = Runtime::Current();
1901 Transaction transaction;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001902
Ian Rogersc45b8b52014-05-03 01:39:59 -07001903 // Run the class initializer in transaction mode.
1904 runtime->EnterTransactionMode(&transaction);
1905 const mirror::Class::Status old_status = klass->GetStatus();
Ian Rogers7b078e82014-09-10 14:44:24 -07001906 bool success = manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, true,
1907 true);
Ian Rogersc45b8b52014-05-03 01:39:59 -07001908 // TODO we detach transaction from runtime to indicate we quit the transactional
1909 // mode which prevents the GC from visiting objects modified during the transaction.
1910 // Ensure GC is not run so don't access freed objects when aborting transaction.
Mathieu Chartier2d5f39e2014-09-19 17:52:37 -07001911
1912 ScopedAssertNoThreadSuspension ants(soa.Self(), "Transaction end");
Ian Rogersc45b8b52014-05-03 01:39:59 -07001913 runtime->ExitTransactionMode();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001914
Ian Rogersc45b8b52014-05-03 01:39:59 -07001915 if (!success) {
1916 CHECK(soa.Self()->IsExceptionPending());
1917 ThrowLocation throw_location;
1918 mirror::Throwable* exception = soa.Self()->GetException(&throw_location);
1919 VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
1920 << exception->Dump();
Andreas Gampedbfe2542014-11-25 22:21:42 -08001921 std::ostream* file_log = manager->GetCompiler()->
1922 GetCompilerOptions().GetInitFailureOutput();
1923 if (file_log != nullptr) {
1924 *file_log << descriptor << "\n";
1925 *file_log << exception->Dump() << "\n";
1926 }
Ian Rogersc45b8b52014-05-03 01:39:59 -07001927 soa.Self()->ClearException();
1928 transaction.Abort();
1929 CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
Brian Carlstrom7940e442013-07-12 13:46:57 -07001930 }
1931 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001932 }
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001933 soa.Self()->AssertNoPendingException();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001934 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001935 }
1936 // Record the final class status if necessary.
Brian Carlstrom7940e442013-07-12 13:46:57 -07001937 ClassReference ref(manager->GetDexFile(), class_def_index);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001938 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001939 }
1940 // Clear any class not found or verification exceptions.
1941 soa.Self()->ClearException();
1942}
1943
1944void CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001945 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001946 ThreadPool* thread_pool, TimingLogger* timings) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001947 TimingLogger::ScopedTiming t("InitializeNoClinit", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001948 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Andreas Gampede7b4362014-07-28 18:38:57 -07001949 ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, dex_files,
1950 thread_pool);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001951 size_t thread_count;
1952 if (IsImage()) {
1953 // TODO: remove this when transactional mode supports multithreading.
1954 thread_count = 1U;
1955 } else {
1956 thread_count = thread_count_;
1957 }
1958 context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001959}
1960
1961void CompilerDriver::InitializeClasses(jobject class_loader,
1962 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001963 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001964 for (size_t i = 0; i != dex_files.size(); ++i) {
1965 const DexFile* dex_file = dex_files[i];
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001966 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -07001967 InitializeClasses(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001968 }
Mathieu Chartier093ef212014-08-11 13:52:12 -07001969 if (IsImage()) {
1970 // Prune garbage objects created during aborted transactions.
1971 Runtime::Current()->GetHeap()->CollectGarbage(true);
1972 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001973}
1974
1975void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001976 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001977 for (size_t i = 0; i != dex_files.size(); ++i) {
1978 const DexFile* dex_file = dex_files[i];
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001979 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -07001980 CompileDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001981 }
Mathieu Chartierab972ef2014-12-03 17:38:22 -08001982 VLOG(compiler) << "Compile: " << GetMemoryUsageString();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001983}
1984
1985void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, size_t class_def_index) {
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001986 ATRACE_CALL();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001987 const DexFile& dex_file = *manager->GetDexFile();
1988 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogersbe7149f2013-08-20 09:29:39 -07001989 ClassLinker* class_linker = manager->GetClassLinker();
Ian Rogers1ff3c982014-08-12 02:30:58 -07001990 jobject jclass_loader = manager->GetClassLoader();
1991 {
1992 // Use a scoped object access to perform to the quick SkipClass check.
1993 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1994 ScopedObjectAccess soa(Thread::Current());
1995 StackHandleScope<3> hs(soa.Self());
1996 Handle<mirror::ClassLoader> class_loader(
1997 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1998 Handle<mirror::Class> klass(
1999 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
2000 if (klass.Get() == nullptr) {
2001 CHECK(soa.Self()->IsExceptionPending());
2002 soa.Self()->ClearException();
2003 } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
2004 return;
2005 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07002006 }
2007 ClassReference ref(&dex_file, class_def_index);
2008 // Skip compiling classes with generic verifier failures since they will still fail at runtime
Vladimir Markoc7f83202014-01-24 17:55:18 +00002009 if (manager->GetCompiler()->verification_results_->IsClassRejected(ref)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002010 return;
2011 }
Ian Rogers13735952014-10-08 12:43:28 -07002012 const uint8_t* class_data = dex_file.GetClassData(class_def);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002013 if (class_data == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002014 // empty class, probably a marker interface
2015 return;
2016 }
Anwar Ghuloum67f99412013-08-12 14:19:48 -07002017
Brian Carlstrom7940e442013-07-12 13:46:57 -07002018 // Can we run DEX-to-DEX compiler on this class ?
Sebastien Hertz75021222013-07-16 18:34:50 +02002019 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002020 {
2021 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002022 StackHandleScope<1> hs(soa.Self());
2023 Handle<mirror::ClassLoader> class_loader(
2024 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
Ian Rogers98379392014-02-24 16:53:16 -08002025 dex_to_dex_compilation_level = GetDexToDexCompilationlevel(soa.Self(), class_loader, dex_file,
2026 class_def);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002027 }
2028 ClassDataItemIterator it(dex_file, class_data);
2029 // Skip fields
2030 while (it.HasNextStaticField()) {
2031 it.Next();
2032 }
2033 while (it.HasNextInstanceField()) {
2034 it.Next();
2035 }
Ian Rogersbe7149f2013-08-20 09:29:39 -07002036 CompilerDriver* driver = manager->GetCompiler();
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002037
2038 bool compilation_enabled = driver->IsClassToCompile(
2039 dex_file.StringByTypeIdx(class_def.class_idx_));
2040
Brian Carlstrom7940e442013-07-12 13:46:57 -07002041 // Compile direct methods
2042 int64_t previous_direct_method_idx = -1;
2043 while (it.HasNextDirectMethod()) {
2044 uint32_t method_idx = it.GetMemberIndex();
2045 if (method_idx == previous_direct_method_idx) {
2046 // smali can create dex files with two encoded_methods sharing the same method_idx
2047 // http://code.google.com/p/smali/issues/detail?id=119
2048 it.Next();
2049 continue;
2050 }
2051 previous_direct_method_idx = method_idx;
Andreas Gampe51829322014-08-25 15:05:04 -07002052 driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
Ian Rogersbe7149f2013-08-20 09:29:39 -07002053 it.GetMethodInvokeType(class_def), class_def_index,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002054 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
2055 compilation_enabled);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002056 it.Next();
2057 }
2058 // Compile virtual methods
2059 int64_t previous_virtual_method_idx = -1;
2060 while (it.HasNextVirtualMethod()) {
2061 uint32_t method_idx = it.GetMemberIndex();
2062 if (method_idx == previous_virtual_method_idx) {
2063 // smali can create dex files with two encoded_methods sharing the same method_idx
2064 // http://code.google.com/p/smali/issues/detail?id=119
2065 it.Next();
2066 continue;
2067 }
2068 previous_virtual_method_idx = method_idx;
Andreas Gampe51829322014-08-25 15:05:04 -07002069 driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
Ian Rogersbe7149f2013-08-20 09:29:39 -07002070 it.GetMethodInvokeType(class_def), class_def_index,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002071 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
2072 compilation_enabled);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002073 it.Next();
2074 }
2075 DCHECK(!it.HasNext());
2076}
2077
2078void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07002079 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08002080 ThreadPool* thread_pool, TimingLogger* timings) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -07002081 TimingLogger::ScopedTiming t("Compile Dex File", timings);
Ian Rogersbe7149f2013-08-20 09:29:39 -07002082 ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,
Andreas Gampede7b4362014-07-28 18:38:57 -07002083 &dex_file, dex_files, thread_pool);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002084 context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002085}
2086
Ian Rogersa4a3f402014-10-20 18:10:34 -07002087// Does the runtime for the InstructionSet provide an implementation returned by
2088// GetQuickGenericJniStub allowing down calls that aren't compiled using a JNI compiler?
2089static bool InstructionSetHasGenericJniStub(InstructionSet isa) {
2090 switch (isa) {
2091 case kArm:
2092 case kArm64:
2093 case kThumb2:
Douglas Leung735b8552014-10-31 12:21:40 -07002094 case kMips:
Ian Rogersa4a3f402014-10-20 18:10:34 -07002095 case kX86:
2096 case kX86_64: return true;
2097 default: return false;
2098 }
2099}
2100
Brian Carlstrom7940e442013-07-12 13:46:57 -07002101void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002102 InvokeType invoke_type, uint16_t class_def_idx,
Brian Carlstrom7940e442013-07-12 13:46:57 -07002103 uint32_t method_idx, jobject class_loader,
2104 const DexFile& dex_file,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002105 DexToDexCompilationLevel dex_to_dex_compilation_level,
2106 bool compilation_enabled) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002107 CompiledMethod* compiled_method = nullptr;
Mathieu Chartier8e219ae2014-08-19 14:29:46 -07002108 uint64_t start_ns = kTimeCompileMethod ? NanoTime() : 0;
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002109 MethodReference method_ref(&dex_file, method_idx);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002110
2111 if ((access_flags & kAccNative) != 0) {
Ian Rogers0188ab72014-03-17 16:51:53 -07002112 // Are we interpreting only and have support for generic JNI down calls?
Jeff Hao4a200f52014-04-01 14:58:49 -07002113 if (!compiler_options_->IsCompilationEnabled() &&
Ian Rogersa4a3f402014-10-20 18:10:34 -07002114 InstructionSetHasGenericJniStub(instruction_set_)) {
Ian Rogers5b271492014-03-14 13:20:26 -07002115 // Leaving this empty will trigger the generic JNI version
2116 } else {
Ian Rogers72d32622014-05-06 16:20:11 -07002117 compiled_method = compiler_->JniCompile(access_flags, method_idx, dex_file);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002118 CHECK(compiled_method != nullptr);
Ian Rogers5b271492014-03-14 13:20:26 -07002119 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07002120 } else if ((access_flags & kAccAbstract) != 0) {
Ian Rogersa4a3f402014-10-20 18:10:34 -07002121 // Abstract methods don't have code.
Brian Carlstrom7940e442013-07-12 13:46:57 -07002122 } else {
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002123 bool compile = compilation_enabled &&
2124 verification_results_->IsCandidateForCompilation(method_ref, access_flags);
Sebastien Hertz4d4adb12013-07-24 16:14:19 +02002125 if (compile) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002126 // NOTE: if compiler declines to compile this method, it will return nullptr.
Ian Rogers72d32622014-05-06 16:20:11 -07002127 compiled_method = compiler_->Compile(code_item, access_flags, invoke_type, class_def_idx,
2128 method_idx, class_loader, dex_file);
Sebastien Hertz17965ed2014-04-04 15:59:53 +02002129 }
2130 if (compiled_method == nullptr && dex_to_dex_compilation_level != kDontDexToDexCompile) {
2131 // TODO: add a command-line option to disable DEX-to-DEX compilation ?
Sebastien Hertz75021222013-07-16 18:34:50 +02002132 (*dex_to_dex_compiler_)(*this, code_item, access_flags,
2133 invoke_type, class_def_idx,
2134 method_idx, class_loader, dex_file,
2135 dex_to_dex_compilation_level);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002136 }
2137 }
Mathieu Chartier8e219ae2014-08-19 14:29:46 -07002138 if (kTimeCompileMethod) {
2139 uint64_t duration_ns = NanoTime() - start_ns;
2140 if (duration_ns > MsToNs(compiler_->GetMaximumCompilationTimeBeforeWarning())) {
2141 LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
2142 << " took " << PrettyDuration(duration_ns);
2143 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07002144 }
2145
2146 Thread* self = Thread::Current();
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002147 if (compiled_method != nullptr) {
Vladimir Markof4da6752014-08-01 19:04:18 +01002148 // Count non-relative linker patches.
2149 size_t non_relative_linker_patch_count = 0u;
2150 for (const LinkerPatch& patch : compiled_method->GetPatches()) {
2151 if (patch.Type() != kLinkerPatchCallRelative) {
2152 ++non_relative_linker_patch_count;
2153 }
2154 }
Igor Murashkind6dee672014-10-16 18:36:16 -07002155 bool compile_pic = GetCompilerOptions().GetCompilePic(); // Off by default
2156 // When compiling with PIC, there should be zero non-relative linker patches
2157 CHECK(!compile_pic || non_relative_linker_patch_count == 0u);
2158
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002159 DCHECK(GetCompiledMethod(method_ref) == nullptr) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002160 {
2161 MutexLock mu(self, compiled_methods_lock_);
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002162 compiled_methods_.Put(method_ref, compiled_method);
Vladimir Markof4da6752014-08-01 19:04:18 +01002163 non_relative_linker_patch_count_ += non_relative_linker_patch_count;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002164 }
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002165 DCHECK(GetCompiledMethod(method_ref) != nullptr) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002166 }
2167
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002168 // Done compiling, delete the verified method to reduce native memory usage.
2169 verification_results_->RemoveVerifiedMethod(method_ref);
2170
Brian Carlstrom7940e442013-07-12 13:46:57 -07002171 if (self->IsExceptionPending()) {
2172 ScopedObjectAccess soa(self);
2173 LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002174 << self->GetException(nullptr)->Dump();
Brian Carlstrom7940e442013-07-12 13:46:57 -07002175 }
2176}
2177
2178CompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const {
2179 MutexLock mu(Thread::Current(), compiled_classes_lock_);
2180 ClassTable::const_iterator it = compiled_classes_.find(ref);
2181 if (it == compiled_classes_.end()) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002182 return nullptr;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002183 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002184 CHECK(it->second != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002185 return it->second;
2186}
2187
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002188void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
2189 MutexLock mu(Thread::Current(), compiled_classes_lock_);
2190 auto it = compiled_classes_.find(ref);
2191 if (it == compiled_classes_.end() || it->second->GetStatus() != status) {
2192 // An entry doesn't exist or the status is lower than the new status.
2193 if (it != compiled_classes_.end()) {
2194 CHECK_GT(status, it->second->GetStatus());
2195 delete it->second;
2196 }
2197 switch (status) {
2198 case mirror::Class::kStatusNotReady:
2199 case mirror::Class::kStatusError:
2200 case mirror::Class::kStatusRetryVerificationAtRuntime:
2201 case mirror::Class::kStatusVerified:
2202 case mirror::Class::kStatusInitialized:
2203 break; // Expected states.
2204 default:
2205 LOG(FATAL) << "Unexpected class status for class "
2206 << PrettyDescriptor(ref.first->GetClassDescriptor(ref.first->GetClassDef(ref.second)))
2207 << " of " << status;
2208 }
2209 CompiledClass* compiled_class = new CompiledClass(status);
2210 compiled_classes_.Overwrite(ref, compiled_class);
2211 }
2212}
2213
Brian Carlstrom7940e442013-07-12 13:46:57 -07002214CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const {
2215 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2216 MethodTable::const_iterator it = compiled_methods_.find(ref);
2217 if (it == compiled_methods_.end()) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002218 return nullptr;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002219 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002220 CHECK(it->second != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002221 return it->second;
2222}
2223
Vladimir Markof4da6752014-08-01 19:04:18 +01002224size_t CompilerDriver::GetNonRelativeLinkerPatchCount() const {
2225 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2226 return non_relative_linker_patch_count_;
2227}
2228
Brian Carlstrom7940e442013-07-12 13:46:57 -07002229void CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002230 uint16_t class_def_index) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002231 WriterMutexLock mu(self, freezing_constructor_lock_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002232 freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
2233}
2234
2235bool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002236 uint16_t class_def_index) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002237 ReaderMutexLock mu(self, freezing_constructor_lock_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002238 return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
2239}
2240
2241bool CompilerDriver::WriteElf(const std::string& android_root,
2242 bool is_host,
2243 const std::vector<const art::DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08002244 OatWriter* oat_writer,
Brian Carlstrom7940e442013-07-12 13:46:57 -07002245 art::File* file)
2246 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers72d32622014-05-06 16:20:11 -07002247 return compiler_->WriteElf(file, oat_writer, dex_files, android_root, is_host);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002248}
2249void CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set,
Ian Rogers3d504072014-03-01 09:16:49 -08002250 std::string* target_triple,
2251 std::string* target_cpu,
2252 std::string* target_attr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002253 switch (instruction_set) {
2254 case kThumb2:
Ian Rogers3d504072014-03-01 09:16:49 -08002255 *target_triple = "thumb-none-linux-gnueabi";
2256 *target_cpu = "cortex-a9";
2257 *target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002258 break;
2259
2260 case kArm:
Ian Rogers3d504072014-03-01 09:16:49 -08002261 *target_triple = "armv7-none-linux-gnueabi";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002262 // TODO: Fix for Nexus S.
Ian Rogers3d504072014-03-01 09:16:49 -08002263 *target_cpu = "cortex-a9";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002264 // TODO: Fix for Xoom.
Ian Rogers3d504072014-03-01 09:16:49 -08002265 *target_attr = "+v7,+neon,+neonfp,+vfp3,+db";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002266 break;
2267
2268 case kX86:
Ian Rogers3d504072014-03-01 09:16:49 -08002269 *target_triple = "i386-pc-linux-gnu";
2270 *target_attr = "";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002271 break;
2272
Dmitry Petrochenko6a58cb12014-04-02 17:27:59 +07002273 case kX86_64:
2274 *target_triple = "x86_64-pc-linux-gnu";
2275 *target_attr = "";
2276 break;
2277
Brian Carlstrom7940e442013-07-12 13:46:57 -07002278 case kMips:
Ian Rogers3d504072014-03-01 09:16:49 -08002279 *target_triple = "mipsel-unknown-linux";
2280 *target_attr = "mips32r2";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002281 break;
2282
2283 default:
2284 LOG(FATAL) << "Unknown instruction set: " << instruction_set;
2285 }
2286 }
Dave Allison39c3bfb2014-01-28 18:33:52 -08002287
Dave Allison39c3bfb2014-01-28 18:33:52 -08002288bool CompilerDriver::SkipCompilation(const std::string& method_name) {
Calin Juravlec1b643c2014-05-30 23:44:11 +01002289 if (!profile_present_) {
Dave Allison644789f2014-04-10 13:06:10 -07002290 return false;
Dave Allison39c3bfb2014-01-28 18:33:52 -08002291 }
Calin Juravlebb0b53f2014-05-23 17:33:29 +01002292 // First find the method in the profile file.
2293 ProfileFile::ProfileData data;
2294 if (!profile_file_.GetProfileData(&data, method_name)) {
Dave Allison39c3bfb2014-01-28 18:33:52 -08002295 // Not in profile, no information can be determined.
Calin Juravle08f7a2d2014-06-23 15:22:29 +01002296 if (kIsDebugBuild) {
2297 VLOG(compiler) << "not compiling " << method_name << " because it's not in the profile";
2298 }
Dave Allison39c3bfb2014-01-28 18:33:52 -08002299 return true;
2300 }
Calin Juravlebb0b53f2014-05-23 17:33:29 +01002301
2302 // Methods that comprise top_k_threshold % of the total samples will be compiled.
Calin Juravlef6a4cee2014-04-02 17:03:08 +01002303 // Compare against the start of the topK percentage bucket just in case the threshold
Calin Juravle04ff2262014-04-02 19:08:47 +01002304 // falls inside a bucket.
Calin Juravlec1b643c2014-05-30 23:44:11 +01002305 bool compile = data.GetTopKUsedPercentage() - data.GetUsedPercent()
2306 <= compiler_options_->GetTopKProfileThreshold();
Calin Juravle08f7a2d2014-06-23 15:22:29 +01002307 if (kIsDebugBuild) {
2308 if (compile) {
2309 LOG(INFO) << "compiling method " << method_name << " because its usage is part of top "
2310 << data.GetTopKUsedPercentage() << "% with a percent of " << data.GetUsedPercent() << "%"
2311 << " (topKThreshold=" << compiler_options_->GetTopKProfileThreshold() << ")";
2312 } else {
2313 VLOG(compiler) << "not compiling method " << method_name
2314 << " because it's not part of leading " << compiler_options_->GetTopKProfileThreshold()
2315 << "% samples)";
2316 }
Dave Allison39c3bfb2014-01-28 18:33:52 -08002317 }
2318 return !compile;
2319}
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002320
2321std::string CompilerDriver::GetMemoryUsageString() const {
2322 std::ostringstream oss;
2323 const ArenaPool* arena_pool = GetArenaPool();
2324 gc::Heap* heap = Runtime::Current()->GetHeap();
2325 oss << "arena alloc=" << PrettySize(arena_pool->GetBytesAllocated());
2326 oss << " java alloc=" << PrettySize(heap->GetBytesAllocated());
2327#ifdef HAVE_MALLOC_H
2328 struct mallinfo info = mallinfo();
2329 const size_t allocated_space = static_cast<size_t>(info.uordblks);
2330 const size_t free_space = static_cast<size_t>(info.fordblks);
2331 oss << " native alloc=" << PrettySize(allocated_space) << " free="
2332 << PrettySize(free_space);
2333#endif
2334 return oss.str();
2335}
2336
Brian Carlstrom7940e442013-07-12 13:46:57 -07002337} // namespace art