blob: cd9280c4c4855e666ee815fb48b1c65f9a17f7c8 [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
Vladimir Markof096aad2014-01-23 15:51:58 +00001376 if (enable_devirtualization) {
1377 DCHECK(mUnit->GetVerifiedMethod() != nullptr);
1378 const MethodReference* devirt_target = mUnit->GetVerifiedMethod()->GetDevirtTarget(dex_pc);
1379
1380 stats_flags = IsFastInvoke(
1381 soa, dex_cache, class_loader, mUnit, referrer_class, resolved_method,
1382 invoke_type, target_method, devirt_target, direct_code, direct_method);
1383 result = stats_flags != 0;
1384 } else {
1385 // Devirtualization not enabled. Inline IsFastInvoke(), dropping the devirtualization parts.
1386 if (UNLIKELY(referrer_class == nullptr) ||
1387 UNLIKELY(!referrer_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001388 resolved_method, dex_cache.Get(),
Vladimir Markof096aad2014-01-23 15:51:58 +00001389 target_method->dex_method_index)) ||
1390 *invoke_type == kSuper) {
1391 // Slow path. (Without devirtualization, all super calls go slow path as well.)
1392 } else {
1393 // Sharpening failed so generate a regular resolved method dispatch.
1394 stats_flags = kFlagMethodResolved;
1395 GetCodeAndMethodForDirectCall(invoke_type, *invoke_type, false, referrer_class, resolved_method,
1396 &stats_flags, target_method, direct_code, direct_method);
1397 result = true;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001398 }
1399 }
1400 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001401 if (!result) {
1402 // Conservative defaults.
1403 *vtable_idx = -1;
1404 *direct_code = 0u;
1405 *direct_method = 0u;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001406 }
1407 if (update_stats) {
Vladimir Markof096aad2014-01-23 15:51:58 +00001408 ProcessedInvoke(orig_invoke_type, stats_flags);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001409 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001410 return result;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001411}
1412
Vladimir Marko2730db02014-01-27 11:15:17 +00001413const VerifiedMethod* CompilerDriver::GetVerifiedMethod(const DexFile* dex_file,
1414 uint32_t method_idx) const {
1415 MethodReference ref(dex_file, method_idx);
1416 return verification_results_->GetVerifiedMethod(ref);
1417}
1418
1419bool CompilerDriver::IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001420 if (!compiler_options_->IsVerificationEnabled()) {
1421 // If we didn't verify, every cast has to be treated as non-safe.
1422 return false;
1423 }
Vladimir Marko2730db02014-01-27 11:15:17 +00001424 DCHECK(mUnit->GetVerifiedMethod() != nullptr);
1425 bool result = mUnit->GetVerifiedMethod()->IsSafeCast(dex_pc);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001426 if (result) {
1427 stats_->SafeCast();
1428 } else {
1429 stats_->NotASafeCast();
1430 }
1431 return result;
1432}
1433
Brian Carlstrom7940e442013-07-12 13:46:57 -07001434class ParallelCompilationManager {
1435 public:
1436 typedef void Callback(const ParallelCompilationManager* manager, size_t index);
1437
1438 ParallelCompilationManager(ClassLinker* class_linker,
1439 jobject class_loader,
1440 CompilerDriver* compiler,
1441 const DexFile* dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001442 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001443 ThreadPool* thread_pool)
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001444 : index_(0),
1445 class_linker_(class_linker),
Brian Carlstrom7940e442013-07-12 13:46:57 -07001446 class_loader_(class_loader),
1447 compiler_(compiler),
1448 dex_file_(dex_file),
Andreas Gampede7b4362014-07-28 18:38:57 -07001449 dex_files_(dex_files),
Ian Rogers3d504072014-03-01 09:16:49 -08001450 thread_pool_(thread_pool) {}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001451
1452 ClassLinker* GetClassLinker() const {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001453 CHECK(class_linker_ != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001454 return class_linker_;
1455 }
1456
1457 jobject GetClassLoader() const {
1458 return class_loader_;
1459 }
1460
1461 CompilerDriver* GetCompiler() const {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001462 CHECK(compiler_ != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001463 return compiler_;
1464 }
1465
1466 const DexFile* GetDexFile() const {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001467 CHECK(dex_file_ != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001468 return dex_file_;
1469 }
1470
Andreas Gampede7b4362014-07-28 18:38:57 -07001471 const std::vector<const DexFile*>& GetDexFiles() const {
1472 return dex_files_;
1473 }
1474
Brian Carlstrom7940e442013-07-12 13:46:57 -07001475 void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
1476 Thread* self = Thread::Current();
1477 self->AssertNoPendingException();
1478 CHECK_GT(work_units, 0U);
1479
Ian Rogers3e5cf302014-05-20 16:40:37 -07001480 index_.StoreRelaxed(begin);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001481 for (size_t i = 0; i < work_units; ++i) {
Sebastien Hertz501baec2013-12-13 12:02:36 +01001482 thread_pool_->AddTask(self, new ForAllClosure(this, end, callback));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001483 }
1484 thread_pool_->StartWorkers(self);
1485
1486 // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
1487 // thread destructor's called below perform join).
1488 CHECK_NE(self->GetState(), kRunnable);
1489
1490 // Wait for all the worker threads to finish.
1491 thread_pool_->Wait(self, true, false);
1492 }
1493
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001494 size_t NextIndex() {
Ian Rogers3e5cf302014-05-20 16:40:37 -07001495 return index_.FetchAndAddSequentiallyConsistent(1);
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001496 }
1497
Brian Carlstrom7940e442013-07-12 13:46:57 -07001498 private:
Brian Carlstrom7940e442013-07-12 13:46:57 -07001499 class ForAllClosure : public Task {
1500 public:
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001501 ForAllClosure(ParallelCompilationManager* manager, size_t end, Callback* callback)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001502 : manager_(manager),
Brian Carlstrom7940e442013-07-12 13:46:57 -07001503 end_(end),
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001504 callback_(callback) {}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001505
1506 virtual void Run(Thread* self) {
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001507 while (true) {
1508 const size_t index = manager_->NextIndex();
1509 if (UNLIKELY(index >= end_)) {
1510 break;
1511 }
1512 callback_(manager_, index);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001513 self->AssertNoPendingException();
1514 }
1515 }
1516
1517 virtual void Finalize() {
1518 delete this;
1519 }
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -07001520
Brian Carlstrom7940e442013-07-12 13:46:57 -07001521 private:
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001522 ParallelCompilationManager* const manager_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001523 const size_t end_;
Bernhard Rosenkränzer46053622013-12-12 02:15:52 +01001524 Callback* const callback_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001525 };
1526
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001527 AtomicInteger index_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001528 ClassLinker* const class_linker_;
1529 const jobject class_loader_;
1530 CompilerDriver* const compiler_;
1531 const DexFile* const dex_file_;
Andreas Gampede7b4362014-07-28 18:38:57 -07001532 const std::vector<const DexFile*>& dex_files_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001533 ThreadPool* const thread_pool_;
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001534
1535 DISALLOW_COPY_AND_ASSIGN(ParallelCompilationManager);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001536};
1537
Jeff Hao0e49b422013-11-08 12:16:56 -08001538// A fast version of SkipClass above if the class pointer is available
1539// that avoids the expensive FindInClassPath search.
1540static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Class* klass)
1541 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001542 DCHECK(klass != nullptr);
Jeff Hao0e49b422013-11-08 12:16:56 -08001543 const DexFile& original_dex_file = *klass->GetDexCache()->GetDexFile();
1544 if (&dex_file != &original_dex_file) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001545 if (class_loader == nullptr) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001546 LOG(WARNING) << "Skipping class " << PrettyDescriptor(klass) << " from "
1547 << dex_file.GetLocation() << " previously found in "
1548 << original_dex_file.GetLocation();
1549 }
1550 return true;
1551 }
1552 return false;
1553}
1554
Mathieu Chartier70b63482014-06-27 17:19:04 -07001555static void CheckAndClearResolveException(Thread* self)
1556 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1557 CHECK(self->IsExceptionPending());
1558 mirror::Throwable* exception = self->GetException(nullptr);
Ian Rogers1ff3c982014-08-12 02:30:58 -07001559 std::string temp;
1560 const char* descriptor = exception->GetClass()->GetDescriptor(&temp);
1561 const char* expected_exceptions[] = {
1562 "Ljava/lang/IllegalAccessError;",
1563 "Ljava/lang/IncompatibleClassChangeError;",
1564 "Ljava/lang/InstantiationError;",
Brian Carlstrom898fcb52014-08-25 23:07:30 -07001565 "Ljava/lang/LinkageError;",
Ian Rogers1ff3c982014-08-12 02:30:58 -07001566 "Ljava/lang/NoClassDefFoundError;",
1567 "Ljava/lang/NoSuchFieldError;",
1568 "Ljava/lang/NoSuchMethodError;"
1569 };
1570 bool found = false;
1571 for (size_t i = 0; (found == false) && (i < arraysize(expected_exceptions)); ++i) {
1572 if (strcmp(descriptor, expected_exceptions[i]) == 0) {
1573 found = true;
1574 }
1575 }
1576 if (!found) {
Brian Carlstrom898fcb52014-08-25 23:07:30 -07001577 LOG(FATAL) << "Unexpected exception " << exception->Dump();
Mathieu Chartier70b63482014-06-27 17:19:04 -07001578 }
1579 self->ClearException();
1580}
1581
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001582static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager,
1583 size_t class_def_index)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001584 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001585 ATRACE_CALL();
Ian Rogersbe7149f2013-08-20 09:29:39 -07001586 Thread* self = Thread::Current();
1587 jobject jclass_loader = manager->GetClassLoader();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001588 const DexFile& dex_file = *manager->GetDexFile();
Ian Rogersbe7149f2013-08-20 09:29:39 -07001589 ClassLinker* class_linker = manager->GetClassLinker();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001590
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001591 // If an instance field is final then we need to have a barrier on the return, static final
1592 // fields are assigned within the lock held for class initialization. Conservatively assume
1593 // constructor barriers are always required.
1594 bool requires_constructor_barrier = true;
1595
Brian Carlstrom7940e442013-07-12 13:46:57 -07001596 // Method and Field are the worst. We can't resolve without either
1597 // context from the code use (to disambiguate virtual vs direct
1598 // method and instance vs static field) or from class
1599 // definitions. While the compiler will resolve what it can as it
1600 // needs it, here we try to resolve fields and methods used in class
1601 // definitions, since many of them many never be referenced by
1602 // generated code.
1603 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogers68b56852014-08-29 20:19:11 -07001604 ScopedObjectAccess soa(self);
1605 StackHandleScope<2> hs(soa.Self());
1606 Handle<mirror::ClassLoader> class_loader(
1607 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1608 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1609 // Resolve the class.
1610 mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
1611 class_loader);
1612 bool resolve_fields_and_methods;
1613 if (klass == nullptr) {
1614 // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
1615 // attempt to resolve methods and fields when there is no declaring class.
1616 CheckAndClearResolveException(soa.Self());
1617 resolve_fields_and_methods = false;
1618 } else {
1619 // We successfully resolved a class, should we skip it?
1620 if (SkipClass(jclass_loader, dex_file, klass)) {
1621 return;
Brian Carlstromcb5f5e52013-09-23 17:48:16 -07001622 }
Ian Rogers68b56852014-08-29 20:19:11 -07001623 // We want to resolve the methods and fields eagerly.
1624 resolve_fields_and_methods = true;
1625 }
1626 // Note the class_data pointer advances through the headers,
1627 // static fields, instance fields, direct methods, and virtual
1628 // methods.
Ian Rogers13735952014-10-08 12:43:28 -07001629 const uint8_t* class_data = dex_file.GetClassData(class_def);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001630 if (class_data == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001631 // Empty class such as a marker interface.
1632 requires_constructor_barrier = false;
1633 } else {
1634 ClassDataItemIterator it(dex_file, class_data);
1635 while (it.HasNextStaticField()) {
1636 if (resolve_fields_and_methods) {
1637 mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1638 dex_cache, class_loader, true);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001639 if (field == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001640 CheckAndClearResolveException(soa.Self());
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001641 }
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001642 }
Ian Rogers68b56852014-08-29 20:19:11 -07001643 it.Next();
1644 }
1645 // We require a constructor barrier if there are final instance fields.
1646 requires_constructor_barrier = false;
1647 while (it.HasNextInstanceField()) {
Andreas Gampe51829322014-08-25 15:05:04 -07001648 if (it.MemberIsFinal()) {
Ian Rogers68b56852014-08-29 20:19:11 -07001649 requires_constructor_barrier = true;
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001650 }
1651 if (resolve_fields_and_methods) {
Ian Rogers68b56852014-08-29 20:19:11 -07001652 mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1653 dex_cache, class_loader, false);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001654 if (field == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001655 CheckAndClearResolveException(soa.Self());
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001656 }
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001657 }
Ian Rogers68b56852014-08-29 20:19:11 -07001658 it.Next();
1659 }
1660 if (resolve_fields_and_methods) {
1661 while (it.HasNextDirectMethod()) {
1662 mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
1663 dex_cache, class_loader,
1664 NullHandle<mirror::ArtMethod>(),
1665 it.GetMethodInvokeType(class_def));
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001666 if (method == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001667 CheckAndClearResolveException(soa.Self());
1668 }
1669 it.Next();
1670 }
1671 while (it.HasNextVirtualMethod()) {
1672 mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
1673 dex_cache, class_loader,
1674 NullHandle<mirror::ArtMethod>(),
1675 it.GetMethodInvokeType(class_def));
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001676 if (method == nullptr) {
Ian Rogers68b56852014-08-29 20:19:11 -07001677 CheckAndClearResolveException(soa.Self());
1678 }
1679 it.Next();
1680 }
1681 DCHECK(!it.HasNext());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001682 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001683 }
1684 if (requires_constructor_barrier) {
Ian Rogersbe7149f2013-08-20 09:29:39 -07001685 manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001686 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001687}
1688
1689static void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
1690 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1691 // Class derived values are more complicated, they require the linker and loader.
1692 ScopedObjectAccess soa(Thread::Current());
1693 ClassLinker* class_linker = manager->GetClassLinker();
1694 const DexFile& dex_file = *manager->GetDexFile();
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001695 StackHandleScope<2> hs(soa.Self());
1696 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1697 Handle<mirror::ClassLoader> class_loader(
1698 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader())));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001699 mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
1700
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001701 if (klass == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001702 CHECK(soa.Self()->IsExceptionPending());
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001703 mirror::Throwable* exception = soa.Self()->GetException(nullptr);
Ian Rogersa436fde2013-08-27 23:34:06 -07001704 VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
Mathieu Chartierf8322842014-05-16 10:59:25 -07001705 if (exception->GetClass()->DescriptorEquals("Ljava/lang/OutOfMemoryError;")) {
Ian Rogersa436fde2013-08-27 23:34:06 -07001706 // There's little point continuing compilation if the heap is exhausted.
1707 LOG(FATAL) << "Out of memory during type resolution for compilation";
1708 }
1709 soa.Self()->ClearException();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001710 }
1711}
1712
1713void CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001714 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001715 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001716 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1717
1718 // TODO: we could resolve strings here, although the string table is largely filled with class
1719 // and method names.
1720
Andreas Gampede7b4362014-07-28 18:38:57 -07001721 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1722 thread_pool);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001723 if (IsImage()) {
1724 // For images we resolve all types, such as array, whereas for applications just those with
1725 // classdefs are resolved by ResolveClassFieldsAndMethods.
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001726 TimingLogger::ScopedTiming t("Resolve Types", timings);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001727 context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
1728 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001729
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001730 TimingLogger::ScopedTiming t("Resolve MethodsAndFields", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001731 context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001732}
1733
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001734void CompilerDriver::SetVerified(jobject class_loader, const std::vector<const DexFile*>& dex_files,
1735 ThreadPool* thread_pool, TimingLogger* timings) {
1736 for (size_t i = 0; i != dex_files.size(); ++i) {
1737 const DexFile* dex_file = dex_files[i];
1738 CHECK(dex_file != nullptr);
1739 SetVerifiedDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
1740 }
1741}
1742
Brian Carlstrom7940e442013-07-12 13:46:57 -07001743void CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001744 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001745 for (size_t i = 0; i != dex_files.size(); ++i) {
1746 const DexFile* dex_file = dex_files[i];
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001747 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -07001748 VerifyDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001749 }
1750}
1751
1752static void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index)
1753 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001754 ATRACE_CALL();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001755 ScopedObjectAccess soa(Thread::Current());
Jeff Hao0e49b422013-11-08 12:16:56 -08001756 const DexFile& dex_file = *manager->GetDexFile();
1757 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1758 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1759 ClassLinker* class_linker = manager->GetClassLinker();
1760 jobject jclass_loader = manager->GetClassLoader();
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001761 StackHandleScope<3> hs(soa.Self());
1762 Handle<mirror::ClassLoader> class_loader(
1763 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1764 Handle<mirror::Class> klass(
1765 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1766 if (klass.Get() == nullptr) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001767 CHECK(soa.Self()->IsExceptionPending());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001768 soa.Self()->ClearException();
1769
1770 /*
1771 * At compile time, we can still structurally verify the class even if FindClass fails.
1772 * This is to ensure the class is structurally sound for compilation. An unsound class
1773 * will be rejected by the verifier and later skipped during compilation in the compiler.
1774 */
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001775 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001776 std::string error_msg;
Ian Rogers7b078e82014-09-10 14:44:24 -07001777 if (verifier::MethodVerifier::VerifyClass(soa.Self(), &dex_file, dex_cache, class_loader,
1778 &class_def, true, &error_msg) ==
Brian Carlstrom7940e442013-07-12 13:46:57 -07001779 verifier::MethodVerifier::kHardFailure) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001780 LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001781 << " because: " << error_msg;
1782 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001783 } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
1784 CHECK(klass->IsResolved()) << PrettyClass(klass.Get());
Ian Rogers7b078e82014-09-10 14:44:24 -07001785 class_linker->VerifyClass(soa.Self(), klass);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001786
1787 if (klass->IsErroneous()) {
1788 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1789 CHECK(soa.Self()->IsExceptionPending());
1790 soa.Self()->ClearException();
1791 }
1792
1793 CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001794 << PrettyDescriptor(klass.Get()) << ": state=" << klass->GetStatus();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001795 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001796 soa.Self()->AssertNoPendingException();
1797}
1798
1799void CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001800 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001801 ThreadPool* thread_pool, TimingLogger* timings) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001802 TimingLogger::ScopedTiming t("Verify Dex File", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001803 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Andreas Gampede7b4362014-07-28 18:38:57 -07001804 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1805 thread_pool);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001806 context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001807}
1808
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001809static void SetVerifiedClass(const ParallelCompilationManager* manager, size_t class_def_index)
1810 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1811 ATRACE_CALL();
1812 ScopedObjectAccess soa(Thread::Current());
1813 const DexFile& dex_file = *manager->GetDexFile();
1814 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1815 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1816 ClassLinker* class_linker = manager->GetClassLinker();
1817 jobject jclass_loader = manager->GetClassLoader();
1818 StackHandleScope<3> hs(soa.Self());
1819 Handle<mirror::ClassLoader> class_loader(
1820 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1821 Handle<mirror::Class> klass(
1822 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1823 // Class might have failed resolution. Then don't set it to verified.
1824 if (klass.Get() != nullptr) {
1825 // Only do this if the class is resolved. If even resolution fails, quickening will go very,
1826 // very wrong.
1827 if (klass->IsResolved()) {
1828 if (klass->GetStatus() < mirror::Class::kStatusVerified) {
1829 ObjectLock<mirror::Class> lock(soa.Self(), klass);
1830 klass->SetStatus(mirror::Class::kStatusVerified, soa.Self());
1831 }
1832 // Record the final class status if necessary.
1833 ClassReference ref(manager->GetDexFile(), class_def_index);
1834 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
1835 }
Andreas Gampe61ff0092014-09-16 11:23:23 -07001836 } else {
1837 Thread* self = soa.Self();
1838 DCHECK(self->IsExceptionPending());
1839 self->ClearException();
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001840 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001841}
1842
1843void CompilerDriver::SetVerifiedDexFile(jobject class_loader, const DexFile& dex_file,
1844 const std::vector<const DexFile*>& dex_files,
1845 ThreadPool* thread_pool, TimingLogger* timings) {
1846 TimingLogger::ScopedTiming t("Verify Dex File", timings);
1847 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1848 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1849 thread_pool);
1850 context.ForAll(0, dex_file.NumClassDefs(), SetVerifiedClass, thread_count_);
1851}
1852
Brian Carlstrom7940e442013-07-12 13:46:57 -07001853static void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
1854 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001855 ATRACE_CALL();
Jeff Hao0e49b422013-11-08 12:16:56 -08001856 jobject jclass_loader = manager->GetClassLoader();
1857 const DexFile& dex_file = *manager->GetDexFile();
1858 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Jeff Haobcdbbfe2013-11-08 18:03:22 -08001859 const DexFile::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
1860 const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_);
Ian Rogersfc0e94b2013-09-23 23:51:32 -07001861
Brian Carlstrom7940e442013-07-12 13:46:57 -07001862 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001863 StackHandleScope<3> hs(soa.Self());
1864 Handle<mirror::ClassLoader> class_loader(
1865 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1866 Handle<mirror::Class> klass(
1867 hs.NewHandle(manager->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
Jeff Hao0e49b422013-11-08 12:16:56 -08001868
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001869 if (klass.Get() != nullptr && !SkipClass(jclass_loader, dex_file, klass.Get())) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001870 // Only try to initialize classes that were successfully verified.
1871 if (klass->IsVerified()) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001872 // Attempt to initialize the class but bail if we either need to initialize the super-class
1873 // or static fields.
Ian Rogers7b078e82014-09-10 14:44:24 -07001874 manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001875 if (!klass->IsInitialized()) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001876 // We don't want non-trivial class initialization occurring on multiple threads due to
1877 // deadlock problems. For example, a parent class is initialized (holding its lock) that
1878 // refers to a sub-class in its static/class initializer causing it to try to acquire the
1879 // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
1880 // after first initializing its parents, whose locks are acquired. This leads to a
1881 // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
1882 // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
1883 // than use a special Object for the purpose we use the Class of java.lang.Class.
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001884 Handle<mirror::Class> h_klass(hs.NewHandle(klass->GetClass()));
Mathieu Chartierdb2633c2014-05-16 09:59:29 -07001885 ObjectLock<mirror::Class> lock(soa.Self(), h_klass);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001886 // Attempt to initialize allowing initialization of parent classes but still not static
1887 // fields.
Ian Rogers7b078e82014-09-10 14:44:24 -07001888 manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001889 if (!klass->IsInitialized()) {
1890 // We need to initialize static fields, we only do this for image classes that aren't
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001891 // marked with the $NoPreloadHolder (which implies this should not be initialized early).
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001892 bool can_init_static_fields = manager->GetCompiler()->IsImage() &&
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001893 manager->GetCompiler()->IsImageClass(descriptor) &&
1894 !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001895 if (can_init_static_fields) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001896 VLOG(compiler) << "Initializing: " << descriptor;
Ian Rogersc45b8b52014-05-03 01:39:59 -07001897 // TODO multithreading support. We should ensure the current compilation thread has
1898 // exclusive access to the runtime and the transaction. To achieve this, we could use
1899 // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity
1900 // checks in Thread::AssertThreadSuspensionIsAllowable.
1901 Runtime* const runtime = Runtime::Current();
1902 Transaction transaction;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001903
Ian Rogersc45b8b52014-05-03 01:39:59 -07001904 // Run the class initializer in transaction mode.
1905 runtime->EnterTransactionMode(&transaction);
1906 const mirror::Class::Status old_status = klass->GetStatus();
Ian Rogers7b078e82014-09-10 14:44:24 -07001907 bool success = manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, true,
1908 true);
Ian Rogersc45b8b52014-05-03 01:39:59 -07001909 // TODO we detach transaction from runtime to indicate we quit the transactional
1910 // mode which prevents the GC from visiting objects modified during the transaction.
1911 // Ensure GC is not run so don't access freed objects when aborting transaction.
Mathieu Chartier2d5f39e2014-09-19 17:52:37 -07001912
1913 ScopedAssertNoThreadSuspension ants(soa.Self(), "Transaction end");
Ian Rogersc45b8b52014-05-03 01:39:59 -07001914 runtime->ExitTransactionMode();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001915
Ian Rogersc45b8b52014-05-03 01:39:59 -07001916 if (!success) {
1917 CHECK(soa.Self()->IsExceptionPending());
1918 ThrowLocation throw_location;
1919 mirror::Throwable* exception = soa.Self()->GetException(&throw_location);
1920 VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
1921 << exception->Dump();
Andreas Gampedbfe2542014-11-25 22:21:42 -08001922 std::ostream* file_log = manager->GetCompiler()->
1923 GetCompilerOptions().GetInitFailureOutput();
1924 if (file_log != nullptr) {
1925 *file_log << descriptor << "\n";
1926 *file_log << exception->Dump() << "\n";
1927 }
Ian Rogersc45b8b52014-05-03 01:39:59 -07001928 soa.Self()->ClearException();
1929 transaction.Abort();
1930 CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
Brian Carlstrom7940e442013-07-12 13:46:57 -07001931 }
1932 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001933 }
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001934 soa.Self()->AssertNoPendingException();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001935 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001936 }
1937 // Record the final class status if necessary.
Brian Carlstrom7940e442013-07-12 13:46:57 -07001938 ClassReference ref(manager->GetDexFile(), class_def_index);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001939 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001940 }
1941 // Clear any class not found or verification exceptions.
1942 soa.Self()->ClearException();
1943}
1944
1945void CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07001946 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001947 ThreadPool* thread_pool, TimingLogger* timings) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -07001948 TimingLogger::ScopedTiming t("InitializeNoClinit", timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001949 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Andreas Gampede7b4362014-07-28 18:38:57 -07001950 ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, dex_files,
1951 thread_pool);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001952 size_t thread_count;
1953 if (IsImage()) {
1954 // TODO: remove this when transactional mode supports multithreading.
1955 thread_count = 1U;
1956 } else {
1957 thread_count = thread_count_;
1958 }
1959 context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001960}
1961
1962void CompilerDriver::InitializeClasses(jobject class_loader,
1963 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001964 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001965 for (size_t i = 0; i != dex_files.size(); ++i) {
1966 const DexFile* dex_file = dex_files[i];
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001967 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -07001968 InitializeClasses(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001969 }
Mathieu Chartier093ef212014-08-11 13:52:12 -07001970 if (IsImage()) {
1971 // Prune garbage objects created during aborted transactions.
1972 Runtime::Current()->GetHeap()->CollectGarbage(true);
1973 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001974}
1975
1976void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001977 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001978 for (size_t i = 0; i != dex_files.size(); ++i) {
1979 const DexFile* dex_file = dex_files[i];
Andreas Gampe2ed8def2014-08-28 14:41:02 -07001980 CHECK(dex_file != nullptr);
Andreas Gampede7b4362014-07-28 18:38:57 -07001981 CompileDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001982 }
Mathieu Chartierab972ef2014-12-03 17:38:22 -08001983 VLOG(compiler) << "Compile: " << GetMemoryUsageString();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001984}
1985
1986void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, size_t class_def_index) {
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001987 ATRACE_CALL();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001988 const DexFile& dex_file = *manager->GetDexFile();
1989 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogersbe7149f2013-08-20 09:29:39 -07001990 ClassLinker* class_linker = manager->GetClassLinker();
Ian Rogers1ff3c982014-08-12 02:30:58 -07001991 jobject jclass_loader = manager->GetClassLoader();
1992 {
1993 // Use a scoped object access to perform to the quick SkipClass check.
1994 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1995 ScopedObjectAccess soa(Thread::Current());
1996 StackHandleScope<3> hs(soa.Self());
1997 Handle<mirror::ClassLoader> class_loader(
1998 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1999 Handle<mirror::Class> klass(
2000 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
2001 if (klass.Get() == nullptr) {
2002 CHECK(soa.Self()->IsExceptionPending());
2003 soa.Self()->ClearException();
2004 } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
2005 return;
2006 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07002007 }
2008 ClassReference ref(&dex_file, class_def_index);
2009 // Skip compiling classes with generic verifier failures since they will still fail at runtime
Vladimir Markoc7f83202014-01-24 17:55:18 +00002010 if (manager->GetCompiler()->verification_results_->IsClassRejected(ref)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002011 return;
2012 }
Ian Rogers13735952014-10-08 12:43:28 -07002013 const uint8_t* class_data = dex_file.GetClassData(class_def);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002014 if (class_data == nullptr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002015 // empty class, probably a marker interface
2016 return;
2017 }
Anwar Ghuloum67f99412013-08-12 14:19:48 -07002018
Brian Carlstrom7940e442013-07-12 13:46:57 -07002019 // Can we run DEX-to-DEX compiler on this class ?
Sebastien Hertz75021222013-07-16 18:34:50 +02002020 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002021 {
2022 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002023 StackHandleScope<1> hs(soa.Self());
2024 Handle<mirror::ClassLoader> class_loader(
2025 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
Ian Rogers98379392014-02-24 16:53:16 -08002026 dex_to_dex_compilation_level = GetDexToDexCompilationlevel(soa.Self(), class_loader, dex_file,
2027 class_def);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002028 }
2029 ClassDataItemIterator it(dex_file, class_data);
2030 // Skip fields
2031 while (it.HasNextStaticField()) {
2032 it.Next();
2033 }
2034 while (it.HasNextInstanceField()) {
2035 it.Next();
2036 }
Ian Rogersbe7149f2013-08-20 09:29:39 -07002037 CompilerDriver* driver = manager->GetCompiler();
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002038
2039 bool compilation_enabled = driver->IsClassToCompile(
2040 dex_file.StringByTypeIdx(class_def.class_idx_));
2041
Brian Carlstrom7940e442013-07-12 13:46:57 -07002042 // Compile direct methods
2043 int64_t previous_direct_method_idx = -1;
2044 while (it.HasNextDirectMethod()) {
2045 uint32_t method_idx = it.GetMemberIndex();
2046 if (method_idx == previous_direct_method_idx) {
2047 // smali can create dex files with two encoded_methods sharing the same method_idx
2048 // http://code.google.com/p/smali/issues/detail?id=119
2049 it.Next();
2050 continue;
2051 }
2052 previous_direct_method_idx = method_idx;
Andreas Gampe51829322014-08-25 15:05:04 -07002053 driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
Ian Rogersbe7149f2013-08-20 09:29:39 -07002054 it.GetMethodInvokeType(class_def), class_def_index,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002055 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
2056 compilation_enabled);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002057 it.Next();
2058 }
2059 // Compile virtual methods
2060 int64_t previous_virtual_method_idx = -1;
2061 while (it.HasNextVirtualMethod()) {
2062 uint32_t method_idx = it.GetMemberIndex();
2063 if (method_idx == previous_virtual_method_idx) {
2064 // smali can create dex files with two encoded_methods sharing the same method_idx
2065 // http://code.google.com/p/smali/issues/detail?id=119
2066 it.Next();
2067 continue;
2068 }
2069 previous_virtual_method_idx = method_idx;
Andreas Gampe51829322014-08-25 15:05:04 -07002070 driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
Ian Rogersbe7149f2013-08-20 09:29:39 -07002071 it.GetMethodInvokeType(class_def), class_def_index,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002072 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
2073 compilation_enabled);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002074 it.Next();
2075 }
2076 DCHECK(!it.HasNext());
2077}
2078
2079void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
Andreas Gampede7b4362014-07-28 18:38:57 -07002080 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08002081 ThreadPool* thread_pool, TimingLogger* timings) {
Mathieu Chartierf5997b42014-06-20 10:37:54 -07002082 TimingLogger::ScopedTiming t("Compile Dex File", timings);
Ian Rogersbe7149f2013-08-20 09:29:39 -07002083 ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,
Andreas Gampede7b4362014-07-28 18:38:57 -07002084 &dex_file, dex_files, thread_pool);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002085 context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002086}
2087
Ian Rogersa4a3f402014-10-20 18:10:34 -07002088// Does the runtime for the InstructionSet provide an implementation returned by
2089// GetQuickGenericJniStub allowing down calls that aren't compiled using a JNI compiler?
2090static bool InstructionSetHasGenericJniStub(InstructionSet isa) {
2091 switch (isa) {
2092 case kArm:
2093 case kArm64:
2094 case kThumb2:
Douglas Leung735b8552014-10-31 12:21:40 -07002095 case kMips:
Ian Rogersa4a3f402014-10-20 18:10:34 -07002096 case kX86:
2097 case kX86_64: return true;
2098 default: return false;
2099 }
2100}
2101
Brian Carlstrom7940e442013-07-12 13:46:57 -07002102void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002103 InvokeType invoke_type, uint16_t class_def_idx,
Brian Carlstrom7940e442013-07-12 13:46:57 -07002104 uint32_t method_idx, jobject class_loader,
2105 const DexFile& dex_file,
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002106 DexToDexCompilationLevel dex_to_dex_compilation_level,
2107 bool compilation_enabled) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002108 CompiledMethod* compiled_method = nullptr;
Mathieu Chartier8e219ae2014-08-19 14:29:46 -07002109 uint64_t start_ns = kTimeCompileMethod ? NanoTime() : 0;
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002110 MethodReference method_ref(&dex_file, method_idx);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002111
2112 if ((access_flags & kAccNative) != 0) {
Ian Rogers0188ab72014-03-17 16:51:53 -07002113 // Are we interpreting only and have support for generic JNI down calls?
Jeff Hao4a200f52014-04-01 14:58:49 -07002114 if (!compiler_options_->IsCompilationEnabled() &&
Ian Rogersa4a3f402014-10-20 18:10:34 -07002115 InstructionSetHasGenericJniStub(instruction_set_)) {
Ian Rogers5b271492014-03-14 13:20:26 -07002116 // Leaving this empty will trigger the generic JNI version
2117 } else {
Ian Rogers72d32622014-05-06 16:20:11 -07002118 compiled_method = compiler_->JniCompile(access_flags, method_idx, dex_file);
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002119 CHECK(compiled_method != nullptr);
Ian Rogers5b271492014-03-14 13:20:26 -07002120 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07002121 } else if ((access_flags & kAccAbstract) != 0) {
Ian Rogersa4a3f402014-10-20 18:10:34 -07002122 // Abstract methods don't have code.
Brian Carlstrom7940e442013-07-12 13:46:57 -07002123 } else {
Andreas Gampe4bf3ae92014-11-11 13:28:29 -08002124 bool compile = compilation_enabled &&
2125 verification_results_->IsCandidateForCompilation(method_ref, access_flags);
Sebastien Hertz4d4adb12013-07-24 16:14:19 +02002126 if (compile) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002127 // NOTE: if compiler declines to compile this method, it will return nullptr.
Ian Rogers72d32622014-05-06 16:20:11 -07002128 compiled_method = compiler_->Compile(code_item, access_flags, invoke_type, class_def_idx,
2129 method_idx, class_loader, dex_file);
Sebastien Hertz17965ed2014-04-04 15:59:53 +02002130 }
2131 if (compiled_method == nullptr && dex_to_dex_compilation_level != kDontDexToDexCompile) {
2132 // TODO: add a command-line option to disable DEX-to-DEX compilation ?
Sebastien Hertz75021222013-07-16 18:34:50 +02002133 (*dex_to_dex_compiler_)(*this, code_item, access_flags,
2134 invoke_type, class_def_idx,
2135 method_idx, class_loader, dex_file,
2136 dex_to_dex_compilation_level);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002137 }
2138 }
Mathieu Chartier8e219ae2014-08-19 14:29:46 -07002139 if (kTimeCompileMethod) {
2140 uint64_t duration_ns = NanoTime() - start_ns;
2141 if (duration_ns > MsToNs(compiler_->GetMaximumCompilationTimeBeforeWarning())) {
2142 LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
2143 << " took " << PrettyDuration(duration_ns);
2144 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07002145 }
2146
2147 Thread* self = Thread::Current();
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002148 if (compiled_method != nullptr) {
Vladimir Markof4da6752014-08-01 19:04:18 +01002149 // Count non-relative linker patches.
2150 size_t non_relative_linker_patch_count = 0u;
2151 for (const LinkerPatch& patch : compiled_method->GetPatches()) {
2152 if (patch.Type() != kLinkerPatchCallRelative) {
2153 ++non_relative_linker_patch_count;
2154 }
2155 }
Igor Murashkind6dee672014-10-16 18:36:16 -07002156 bool compile_pic = GetCompilerOptions().GetCompilePic(); // Off by default
2157 // When compiling with PIC, there should be zero non-relative linker patches
2158 CHECK(!compile_pic || non_relative_linker_patch_count == 0u);
2159
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002160 DCHECK(GetCompiledMethod(method_ref) == nullptr) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002161 {
2162 MutexLock mu(self, compiled_methods_lock_);
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002163 compiled_methods_.Put(method_ref, compiled_method);
Vladimir Markof4da6752014-08-01 19:04:18 +01002164 non_relative_linker_patch_count_ += non_relative_linker_patch_count;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002165 }
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002166 DCHECK(GetCompiledMethod(method_ref) != nullptr) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002167 }
2168
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002169 // Done compiling, delete the verified method to reduce native memory usage.
2170 verification_results_->RemoveVerifiedMethod(method_ref);
2171
Brian Carlstrom7940e442013-07-12 13:46:57 -07002172 if (self->IsExceptionPending()) {
2173 ScopedObjectAccess soa(self);
2174 LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002175 << self->GetException(nullptr)->Dump();
Brian Carlstrom7940e442013-07-12 13:46:57 -07002176 }
2177}
2178
2179CompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const {
2180 MutexLock mu(Thread::Current(), compiled_classes_lock_);
2181 ClassTable::const_iterator it = compiled_classes_.find(ref);
2182 if (it == compiled_classes_.end()) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002183 return nullptr;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002184 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002185 CHECK(it->second != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002186 return it->second;
2187}
2188
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002189void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
2190 MutexLock mu(Thread::Current(), compiled_classes_lock_);
2191 auto it = compiled_classes_.find(ref);
2192 if (it == compiled_classes_.end() || it->second->GetStatus() != status) {
2193 // An entry doesn't exist or the status is lower than the new status.
2194 if (it != compiled_classes_.end()) {
2195 CHECK_GT(status, it->second->GetStatus());
2196 delete it->second;
2197 }
2198 switch (status) {
2199 case mirror::Class::kStatusNotReady:
2200 case mirror::Class::kStatusError:
2201 case mirror::Class::kStatusRetryVerificationAtRuntime:
2202 case mirror::Class::kStatusVerified:
2203 case mirror::Class::kStatusInitialized:
2204 break; // Expected states.
2205 default:
2206 LOG(FATAL) << "Unexpected class status for class "
2207 << PrettyDescriptor(ref.first->GetClassDescriptor(ref.first->GetClassDef(ref.second)))
2208 << " of " << status;
2209 }
2210 CompiledClass* compiled_class = new CompiledClass(status);
2211 compiled_classes_.Overwrite(ref, compiled_class);
2212 }
2213}
2214
Brian Carlstrom7940e442013-07-12 13:46:57 -07002215CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const {
2216 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2217 MethodTable::const_iterator it = compiled_methods_.find(ref);
2218 if (it == compiled_methods_.end()) {
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002219 return nullptr;
Brian Carlstrom7940e442013-07-12 13:46:57 -07002220 }
Andreas Gampe2ed8def2014-08-28 14:41:02 -07002221 CHECK(it->second != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002222 return it->second;
2223}
2224
Vladimir Markof4da6752014-08-01 19:04:18 +01002225size_t CompilerDriver::GetNonRelativeLinkerPatchCount() const {
2226 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2227 return non_relative_linker_patch_count_;
2228}
2229
Brian Carlstrom7940e442013-07-12 13:46:57 -07002230void CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002231 uint16_t class_def_index) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002232 WriterMutexLock mu(self, freezing_constructor_lock_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002233 freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
2234}
2235
2236bool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002237 uint16_t class_def_index) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002238 ReaderMutexLock mu(self, freezing_constructor_lock_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002239 return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
2240}
2241
2242bool CompilerDriver::WriteElf(const std::string& android_root,
2243 bool is_host,
2244 const std::vector<const art::DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08002245 OatWriter* oat_writer,
Brian Carlstrom7940e442013-07-12 13:46:57 -07002246 art::File* file)
2247 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers72d32622014-05-06 16:20:11 -07002248 return compiler_->WriteElf(file, oat_writer, dex_files, android_root, is_host);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002249}
2250void CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set,
Ian Rogers3d504072014-03-01 09:16:49 -08002251 std::string* target_triple,
2252 std::string* target_cpu,
2253 std::string* target_attr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002254 switch (instruction_set) {
2255 case kThumb2:
Ian Rogers3d504072014-03-01 09:16:49 -08002256 *target_triple = "thumb-none-linux-gnueabi";
2257 *target_cpu = "cortex-a9";
2258 *target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002259 break;
2260
2261 case kArm:
Ian Rogers3d504072014-03-01 09:16:49 -08002262 *target_triple = "armv7-none-linux-gnueabi";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002263 // TODO: Fix for Nexus S.
Ian Rogers3d504072014-03-01 09:16:49 -08002264 *target_cpu = "cortex-a9";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002265 // TODO: Fix for Xoom.
Ian Rogers3d504072014-03-01 09:16:49 -08002266 *target_attr = "+v7,+neon,+neonfp,+vfp3,+db";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002267 break;
2268
2269 case kX86:
Ian Rogers3d504072014-03-01 09:16:49 -08002270 *target_triple = "i386-pc-linux-gnu";
2271 *target_attr = "";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002272 break;
2273
Dmitry Petrochenko6a58cb12014-04-02 17:27:59 +07002274 case kX86_64:
2275 *target_triple = "x86_64-pc-linux-gnu";
2276 *target_attr = "";
2277 break;
2278
Brian Carlstrom7940e442013-07-12 13:46:57 -07002279 case kMips:
Ian Rogers3d504072014-03-01 09:16:49 -08002280 *target_triple = "mipsel-unknown-linux";
2281 *target_attr = "mips32r2";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002282 break;
2283
2284 default:
2285 LOG(FATAL) << "Unknown instruction set: " << instruction_set;
2286 }
2287 }
Dave Allison39c3bfb2014-01-28 18:33:52 -08002288
Dave Allison39c3bfb2014-01-28 18:33:52 -08002289bool CompilerDriver::SkipCompilation(const std::string& method_name) {
Calin Juravlec1b643c2014-05-30 23:44:11 +01002290 if (!profile_present_) {
Dave Allison644789f2014-04-10 13:06:10 -07002291 return false;
Dave Allison39c3bfb2014-01-28 18:33:52 -08002292 }
Calin Juravlebb0b53f2014-05-23 17:33:29 +01002293 // First find the method in the profile file.
2294 ProfileFile::ProfileData data;
2295 if (!profile_file_.GetProfileData(&data, method_name)) {
Dave Allison39c3bfb2014-01-28 18:33:52 -08002296 // Not in profile, no information can be determined.
Calin Juravle08f7a2d2014-06-23 15:22:29 +01002297 if (kIsDebugBuild) {
2298 VLOG(compiler) << "not compiling " << method_name << " because it's not in the profile";
2299 }
Dave Allison39c3bfb2014-01-28 18:33:52 -08002300 return true;
2301 }
Calin Juravlebb0b53f2014-05-23 17:33:29 +01002302
2303 // Methods that comprise top_k_threshold % of the total samples will be compiled.
Calin Juravlef6a4cee2014-04-02 17:03:08 +01002304 // Compare against the start of the topK percentage bucket just in case the threshold
Calin Juravle04ff2262014-04-02 19:08:47 +01002305 // falls inside a bucket.
Calin Juravlec1b643c2014-05-30 23:44:11 +01002306 bool compile = data.GetTopKUsedPercentage() - data.GetUsedPercent()
2307 <= compiler_options_->GetTopKProfileThreshold();
Calin Juravle08f7a2d2014-06-23 15:22:29 +01002308 if (kIsDebugBuild) {
2309 if (compile) {
2310 LOG(INFO) << "compiling method " << method_name << " because its usage is part of top "
2311 << data.GetTopKUsedPercentage() << "% with a percent of " << data.GetUsedPercent() << "%"
2312 << " (topKThreshold=" << compiler_options_->GetTopKProfileThreshold() << ")";
2313 } else {
2314 VLOG(compiler) << "not compiling method " << method_name
2315 << " because it's not part of leading " << compiler_options_->GetTopKProfileThreshold()
2316 << "% samples)";
2317 }
Dave Allison39c3bfb2014-01-28 18:33:52 -08002318 }
2319 return !compile;
2320}
Mathieu Chartierab972ef2014-12-03 17:38:22 -08002321
2322std::string CompilerDriver::GetMemoryUsageString() const {
2323 std::ostringstream oss;
2324 const ArenaPool* arena_pool = GetArenaPool();
2325 gc::Heap* heap = Runtime::Current()->GetHeap();
2326 oss << "arena alloc=" << PrettySize(arena_pool->GetBytesAllocated());
2327 oss << " java alloc=" << PrettySize(heap->GetBytesAllocated());
2328#ifdef HAVE_MALLOC_H
2329 struct mallinfo info = mallinfo();
2330 const size_t allocated_space = static_cast<size_t>(info.uordblks);
2331 const size_t free_space = static_cast<size_t>(info.fordblks);
2332 oss << " native alloc=" << PrettySize(allocated_space) << " free="
2333 << PrettySize(free_space);
2334#endif
2335 return oss.str();
2336}
2337
Brian Carlstrom7940e442013-07-12 13:46:57 -07002338} // namespace art