compiler_driver.cc revision 265091e581c9f643b37e7966890911f09e223269
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 171212a022fa5f8ef9585d765b1809521812af882cIan Rogers#include "compiler_driver.h" 189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 19d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <vector> 20d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 21b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include <dlfcn.h> 22d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <unistd.h> 2327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 241aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 25a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal#include "base/timing_logger.h" 269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 2789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers#include "dex_compilation_unit.h" 289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 3000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "oat/runtime/stub.h" 316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 321f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "gc/card_table-inl.h" 347469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h" 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/dex_cache.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h" 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h" 4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 4400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h" 4550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#include "thread.h" 460e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier#include "thread_pool.h" 47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/method_verifier.h" 489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 49059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 50059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#include <mach-o/dyld.h> 51059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 52059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 55996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic double Percentage(size_t x, size_t y) { 56398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y)); 57996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 58996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 59996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic void DumpStat(size_t x, size_t y, const char* str) { 60996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (x == 0 && y == 0) { 61996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return; 62996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 63996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases"; 64996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 65996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 66c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersclass AOTCompilationStats { 67c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers public: 68ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers AOTCompilationStats() 69ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers : stats_lock_("AOT compilation statistics lock"), 70ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers types_in_dex_cache_(0), types_not_in_dex_cache_(0), 71ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers strings_in_dex_cache_(0), strings_not_in_dex_cache_(0), 72ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers resolved_types_(0), unresolved_types_(0), 73ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers resolved_instance_fields_(0), unresolved_instance_fields_(0), 74ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0) { 752ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 76c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[i] = 0; 77c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[i] = 0; 782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[i] = 0; 792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[i] = 0; 802ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[i] = 0; 81b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes } 82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void Dump() { 85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache"); 86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache"); 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_types_, unresolved_types_, "types resolved"); 88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); 89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, 90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields resolved"); 91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_, 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields local to a class"); 93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 942ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 95c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers std::ostringstream oss; 962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss << static_cast<InvokeType>(i) << " methods were AOT resolved"; 97c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str()); 982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (virtual_made_direct_[i] > 0) { 992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " methods made direct"; 1012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(virtual_made_direct_[i], 1022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i], 1032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_calls_to_boot_[i] > 0) { 1062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot"; 1082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_calls_to_boot_[i], 1092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i], 1102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_methods_to_boot_[i] > 0) { 1132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot"; 1152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_methods_to_boot_[i], 1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i], 1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 119c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 120c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 121996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 12250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers// Allow lossy statistics in non-debug builds. 123996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG 12450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_) 125996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else 126996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() 127996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif 128996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeInDexCache() { 130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_++; 132c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 133996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNotInDexCache() { 135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_not_in_dex_cache_++; 137c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 138996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringInDexCache() { 140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_++; 142c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 143996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringNotInDexCache() { 145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_not_in_dex_cache_++; 147c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 148996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeDoesntNeedAccessCheck() { 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_++; 152c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 153996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNeedsAccessCheck() { 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_types_++; 157c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 158996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedInstanceField() { 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_++; 162c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 163996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 164b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes void UnresolvedInstanceField() { 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_instance_fields_++; 167c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 168996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedLocalStaticField() { 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_local_static_fields_++; 172c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 173996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedStaticField() { 175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_static_fields_++; 177c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 178996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedStaticField() { 180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_static_fields_++; 182c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 183996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedMethod(InvokeType type) { 185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 186c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 187c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[type]++; 188996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 189996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 190c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedMethod(InvokeType type) { 191c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 192c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 193c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[type]++; 194996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 195c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 1962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void VirtualMadeDirect(InvokeType type) { 1972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 1982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 1992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[type]++; 2002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 2022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectCallsToBoot(InvokeType type) { 2032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 2042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 2052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[type]++; 2062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 2082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectMethodsToBoot(InvokeType type) { 2092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 210fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers STATS_LOCK(); 2112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[type]++; 212fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } 2132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private: 215c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Mutex stats_lock_; 216c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 217c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_in_dex_cache_; 218c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_not_in_dex_cache_; 219c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 220c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_in_dex_cache_; 221c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_not_in_dex_cache_; 222c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 223c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_types_; 224c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_types_; 225c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 226c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_instance_fields_; 227c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_instance_fields_; 228c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 229c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_local_static_fields_; 230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_static_fields_; 231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_static_fields_; 232c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_methods_[kMaxInvokeType + 1]; 234c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_methods_[kMaxInvokeType + 1]; 2352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t virtual_made_direct_[kMaxInvokeType + 1]; 2362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_calls_to_boot_[kMaxInvokeType + 1]; 2372ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_methods_to_boot_[kMaxInvokeType + 1]; 238c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 239b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats); 240c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}; 241996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 2428c4bbb55d0d801e492d849ee636771c8b2840429buzbeestatic std::string MakeCompilerSoName(CompilerBackend compiler_backend) { 243059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 244059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Bad things happen if we pull in the libartd-compiler to a libart dex2oat or vice versa, 245059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // because we end up with both libart and libartd in the same address space! 24667d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes const char* suffix = (kIsDebugBuild ? "d" : ""); 247059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 248059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Work out the filename for the compiler library. 24900bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom std::string library_name(StringPrintf("art%s-compiler", suffix)); 250059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str())); 251059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 252059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 253059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find 254059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the 255059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // same work. 256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes uint32_t executable_path_length = 0; 257448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes _NSGetExecutablePath(NULL, &executable_path_length); 258448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes std::string path(executable_path_length, static_cast<char>(0)); 259448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0); 260059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 261059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/dex2oat". 262059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes size_t last_slash = path.find_last_of('/'); 263059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes CHECK_NE(last_slash, std::string::npos) << path; 264059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 265059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/bin". 267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes last_slash = path.find_last_of('/'); 268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes filename = path + "/lib/" + filename; 271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes return filename; 273b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 274b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 27546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn> 27646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) { 27746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes Fn fn = reinterpret_cast<Fn>(dlsym(library, name)); 27846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes if (fn == NULL) { 27946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror(); 28046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes } 281059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn); 28246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes return fn; 28346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes} 28446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes 2851212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set, 2861212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool image, size_t thread_count, bool support_debugging, 2871212a022fa5f8ef9585d765b1809521812af882cIan Rogers const std::set<std::string>* image_classes, bool dump_stats, 2881212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool dump_timings) 289c531cefbfb5394413122e9f57d211ba436cff012buzbee : compiler_backend_(compiler_backend), 290c531cefbfb5394413122e9f57d211ba436cff012buzbee instruction_set_(instruction_set), 291fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers freezing_constructor_lock_("freezing constructor lock"), 292c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 293c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 294c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 2957a2a23a44d27f769718e28327af671f4e486c49aLogan Chien compiled_proxy_stubs_lock_("compiled proxy stubs lock"), 296aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 2975523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 298de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 29900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers start_ns_(0), 300c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 301ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_stats_(dump_stats), 302ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_timings_(dump_timings), 303b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes image_classes_(image_classes), 304b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_(NULL), 30546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes compiler_(NULL), 3066f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes compiler_context_(NULL), 30746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_(NULL), 3081212a022fa5f8ef9585d765b1809521812af882cIan Rogers create_invoke_stub_(NULL), 3091212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_get_method_code_addr_(NULL), 3101212a022fa5f8ef9585d765b1809521812af882cIan Rogers compiler_get_method_invoke_stub_addr_(NULL) 311971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien{ 3128c4bbb55d0d801e492d849ee636771c8b2840429buzbee std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); 313b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY); 314b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ == NULL) { 315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror(); 316b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 317b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_; 318b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 3194df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key"); 3204df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee 321c531cefbfb5394413122e9f57d211ba436cff012buzbee // TODO: more work needed to combine initializations and allow per-method backend selection 3221212a022fa5f8ef9585d765b1809521812af882cIan Rogers typedef void (*InitCompilerContextFn)(CompilerDriver&); 323c531cefbfb5394413122e9f57d211ba436cff012buzbee InitCompilerContextFn init_compiler_context; 324c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable){ 325c531cefbfb5394413122e9f57d211ba436cff012buzbee // Initialize compiler_context_ 3261212a022fa5f8ef9585d765b1809521812af882cIan Rogers init_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 327c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtInitCompilerContext"); 328c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod"); 329c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 3301212a022fa5f8ef9585d765b1809521812af882cIan Rogers init_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 331c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtInitQuickCompilerContext"); 332c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtQuickCompileMethod"); 333c531cefbfb5394413122e9f57d211ba436cff012buzbee } 334692be80cb2278ae585a776a163bc4b3ef60cae88buzbee 335692be80cb2278ae585a776a163bc4b3ef60cae88buzbee init_compiler_context(*this); 336106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 337c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 33800bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtLLVMJniCompileMethod"); 33900bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom } else { 34000bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtQuickJniCompileMethod"); 34100bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom } 34200bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom 343c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 34402031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 34502031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateLLVMInvokeStub"); 34602031b185b4653e6c72e21f7a51238b903f6d638buzbee } else { 34702031b185b4653e6c72e21f7a51238b903f6d638buzbee switch (instruction_set) { 34802031b185b4653e6c72e21f7a51238b903f6d638buzbee case kArm: 34902031b185b4653e6c72e21f7a51238b903f6d638buzbee case kThumb2: 35002031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 35102031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateArmInvokeStub"); 35202031b185b4653e6c72e21f7a51238b903f6d638buzbee break; 35302031b185b4653e6c72e21f7a51238b903f6d638buzbee case kMips: 35402031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 35502031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateMipsInvokeStub"); 35602031b185b4653e6c72e21f7a51238b903f6d638buzbee break; 35702031b185b4653e6c72e21f7a51238b903f6d638buzbee case kX86: 35802031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 35902031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateX86InvokeStub"); 36002031b185b4653e6c72e21f7a51238b903f6d638buzbee break; 36102031b185b4653e6c72e21f7a51238b903f6d638buzbee default: 36202031b185b4653e6c72e21f7a51238b903f6d638buzbee LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 36302031b185b4653e6c72e21f7a51238b903f6d638buzbee } 36402031b185b4653e6c72e21f7a51238b903f6d638buzbee } 365b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 366c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 367c531cefbfb5394413122e9f57d211ba436cff012buzbee create_proxy_stub_ = FindFunction<CreateProxyStubFn>( 368c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_so_name, compiler_library_, "ArtCreateProxyStub"); 369c531cefbfb5394413122e9f57d211ba436cff012buzbee } 370f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 37125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 372ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 373ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 374ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 375c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 376c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 3771212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerDriver::~CompilerDriver() { 37850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 379c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 38050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_classes_lock_); 381c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 382c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 383c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 38450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 385c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 386c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 387c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 38850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_invoke_stubs_lock_); 389c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 390bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 391f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 39250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_proxy_stubs_lock_); 3937a2a23a44d27f769718e28327af671f4e486c49aLogan Chien STLDeleteValues(&compiled_proxy_stubs_); 3947a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3957a2a23a44d27f769718e28327af671f4e486c49aLogan Chien { 39650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 397f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&code_to_patch_); 398f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 399f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 40050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 401f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&methods_to_patch_); 402f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 403ed6d5ed3494648780b9e91422c90d6bc22c16b79Mathieu Chartier CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key"); 4041212a022fa5f8ef9585d765b1809521812af882cIan Rogers typedef void (*UninitCompilerContextFn)(CompilerDriver&); 4058c4bbb55d0d801e492d849ee636771c8b2840429buzbee std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); 406c531cefbfb5394413122e9f57d211ba436cff012buzbee UninitCompilerContextFn uninit_compiler_context; 407692be80cb2278ae585a776a163bc4b3ef60cae88buzbee // Uninitialize compiler_context_ 408c531cefbfb5394413122e9f57d211ba436cff012buzbee // TODO: rework to combine initialization/uninitialization 409c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 4101212a022fa5f8ef9585d765b1809521812af882cIan Rogers uninit_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 411c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtUnInitCompilerContext"); 412c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 4131212a022fa5f8ef9585d765b1809521812af882cIan Rogers uninit_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 414c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtUnInitQuickCompilerContext"); 415c531cefbfb5394413122e9f57d211ba436cff012buzbee } 416692be80cb2278ae585a776a163bc4b3ef60cae88buzbee uninit_compiler_context(*this); 417b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ != NULL) { 418b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlclose(" << compiler_library_ << ")"; 419ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee /* 420ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * FIXME: Temporary workaround 421ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * Apparently, llvm is adding dctors to atexit, but if we unload 422ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * the library here the code will no longer be around at exit time 423ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * and we die a flaming death in __cxa_finalize(). Apparently, some 424ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * dlclose() implementations will scan the atexit list on unload and 425ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * handle any associated with the soon-to-be-unloaded library. 426ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * However, this is not required by POSIX and we don't do it. 427ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * See: http://b/issue?id=4998315 428ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * What's the right thing to do here? 429ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee */ 430b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dlclose(compiler_library_); 431b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 4323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 4333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4341212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerTls* CompilerDriver::GetTls() { 4354df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee // Lazily create thread-local storage 4364df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_)); 4374df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee if (res == NULL) { 4384df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee res = new CompilerTls(); 4394df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls"); 4404df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee } 4414df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee return res; 4424df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee} 4434df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee 4441212a022fa5f8ef9585d765b1809521812af882cIan Rogersmirror::ByteArray* CompilerDriver::CreateResolutionStub(InstructionSet instruction_set, 4451212a022fa5f8ef9585d765b1809521812af882cIan Rogers Runtime::TrampolineType type) { 4467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao switch (instruction_set) { 4477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kArm: 4487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kThumb2: 4497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return arm::ArmCreateResolutionTrampoline(type); 4507fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kMips: 4517fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return mips::MipsCreateResolutionTrampoline(type); 4527fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kX86: 4537fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return x86::X86CreateResolutionTrampoline(type); 4547fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao default: 4557fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 4567fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return NULL; 457ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 458ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 459ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 4601212a022fa5f8ef9585d765b1809521812af882cIan Rogersmirror::ByteArray* CompilerDriver::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 461169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 462169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 463169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 4648add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 4657fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kMips: 4667fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return mips::CreateJniDlsymLookupStub(); 467169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 4688add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 469169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 47049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 471169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 472169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 473169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 474169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 4751212a022fa5f8ef9585d765b1809521812af882cIan Rogersmirror::ByteArray* CompilerDriver::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 4767fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao switch (instruction_set) { 4777fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kArm: 4787fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kThumb2: 4797fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return arm::CreateAbstractMethodErrorStub(); 4807fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kMips: 4817fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return mips::CreateAbstractMethodErrorStub(); 4827fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kX86: 4837fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return x86::CreateAbstractMethodErrorStub(); 4847fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao default: 4857fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 4867fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return NULL; 487ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 488ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 489ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 4901212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileAll(jobject class_loader, 4911212a022fa5f8ef9585d765b1809521812af882cIan Rogers const std::vector<const DexFile*>& dex_files) { 49225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 493ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 49456edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_)); 495a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal TimingLogger timings("compiler", false); 496601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 49756edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers PreCompile(class_loader, dex_files, *thread_pool.get(), timings); 498601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 49956edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers Compile(class_loader, dex_files, *thread_pool.get(), timings); 500601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 501ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) { 502a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal LOG(INFO) << Dumpable<TimingLogger>(timings); 503601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 504996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 505ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_stats_) { 506ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom stats_->Dump(); 507ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom } 5088a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 5098a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 5101212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileOne(const mirror::AbstractMethod* method) { 51125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 51200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 51300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader; 51400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile* dex_file; 515fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers uint32_t class_def_idx; 51600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 51700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(self); 51800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jobject> 51900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers local_class_loader(soa.Env(), 52000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader())); 52100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_loader = soa.Env()->NewGlobalRef(local_class_loader.get()); 52200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Find the dex_file 523fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MethodHelper mh(method); 524fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers dex_file = &mh.GetDexFile(); 525fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_idx = mh.GetClassDefIndex(); 52600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 52700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kNative); 528ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 529ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 53000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_files.push_back(dex_file); 531ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 53256edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers UniquePtr<ThreadPool> thread_pool(new ThreadPool(1U)); 533a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal TimingLogger timings("CompileOne", false); 53456edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers PreCompile(class_loader, dex_files, *thread_pool.get(), timings); 535ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 53700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); 53808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers CompileMethod(code_item, method->GetAccessFlags(), method->GetInvokeType(), 539fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_idx, method_idx, class_loader, *dex_file); 540ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 54100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->GetJniEnv()->DeleteGlobalRef(class_loader); 54200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 54300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 5449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 5459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 5461212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files, 5471212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 548ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 549ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 5509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 5512f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ResolveDexFile(class_loader, *dex_file, thread_pool, timings); 5529ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 5539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 5549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 5551212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 5561212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 5572f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom Resolve(class_loader, dex_files, thread_pool, timings); 558601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 5592f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom Verify(class_loader, dex_files, thread_pool, timings); 560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5612f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom InitializeClasses(class_loader, dex_files, thread_pool, timings); 562ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 563ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5641212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::IsImageClass(const std::string& descriptor) const { 565ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 566ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 567ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 568ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 569ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 570ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5711212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) { 5721212a022fa5f8ef9585d765b1809521812af882cIan Rogers MutexLock mu(Thread::Current(), CompilerDriver::compiled_classes_lock_); 5733d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers compiled_classes_.Put(ref, compiled_class); 5743d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers} 5753d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers 5761212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, 5771212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t type_idx) { 57800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 5792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 5806d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 581c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5826d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5836d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 5842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 586c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5876d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5886d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 589996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 590996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 591c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 592996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 593c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 594996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 595996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5966d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 5976d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 5981212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, 5991212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t string_idx) { 6001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 6011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6025f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers bool result = false; 6035f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers if (IsImage()) { 6045f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers // We resolve all const-string strings when building for the image. 60500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 6062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 6075f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache); 6085f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers result = true; 60900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 610996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 611c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 612996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 613c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 614996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 615996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6181212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, 6191212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t type_idx) { 62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 6212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 6221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 6232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 6241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 625c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 6292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 6301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 631c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 6331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6341bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 6351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 636996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 637996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 638c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 639996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 640c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 641996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 642996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6451212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 6461212a022fa5f8ef9585d765b1809521812af882cIan Rogers const DexFile& dex_file, 6471212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t type_idx) { 64800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 6492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 6501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 6512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 6521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 653c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 6551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 6572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 659c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 6611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 6631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 664996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 665996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 666c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 667996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 668c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 669996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 670996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa, 67489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexCompilationUnit* mUnit) 675b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 67689756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 67789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 67889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex()); 67989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return mUnit->GetClassLinker()->ResolveType(*mUnit->GetDexFile(), referrer_method_id.class_idx_, 68089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_cache, class_loader); 6814dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 682a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa, 68489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexCompilationUnit* mUnit, 6852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t field_idx) 686b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 68789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 68889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 68989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return mUnit->GetClassLinker()->ResolveField(*mUnit->GetDexFile(), field_idx, dex_cache, 69089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers class_loader, false); 691a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 692a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa, 69489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexCompilationUnit* mUnit, 6952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t method_idx, 6962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers InvokeType type) 697b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 69889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 69989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 70089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return mUnit->GetClassLinker()->ResolveMethod(*mUnit->GetDexFile(), method_idx, dex_cache, 70189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers class_loader, NULL, type); 702a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 703a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 70489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, 7051212a022fa5f8ef9585d765b1809521812af882cIan Rogers int& field_offset, bool& is_volatile, bool is_put) { 70600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 70708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Conservative defaults. 7081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 7091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 71008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Try to resolve field and ignore if an Incompatible Class Change Error (ie is static). 7112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx); 71208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (resolved_field != NULL && !resolved_field->IsStatic()) { 7132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit); 714e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (referrer_class != NULL) { 7152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 716e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 717e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 718e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 719e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 720e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 721e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. 7234445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 72489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::Class* dex_fields_class = mUnit->GetClassLinker()->ResolveType(dex_file, 725e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 726e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class); 727e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 728e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 729e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 730e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 731e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 732e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers fields_class != referrer_class; 733e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 734e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 735e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers is_volatile = resolved_field->IsVolatile(); 736e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers stats_->ResolvedInstanceField(); 737e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers return true; // Fast path. 738e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 7391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 74200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 74300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 7441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 745c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 7461bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 7471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 7481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 74989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, 7501212a022fa5f8ef9585d765b1809521812af882cIan Rogers int& field_offset, int& ssb_index, 7511212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool& is_referrers_class, bool& is_volatile, 7521212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool is_put) { 75300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 75408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Conservative defaults. 7551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 7561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 7571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 7581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 75908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static). 7602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx); 76108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (resolved_field != NULL && resolved_field->IsStatic()) { 7622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit); 7631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 7642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 7658cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 7661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 7671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 769c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 7701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 7711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 772e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 773e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 774e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 775e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 776e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 777e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 778e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. Don't change the field's class as that is 779e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // used to identify the SSB. 7804445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 7812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* dex_fields_class = 78289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetClassLinker()->ResolveType(dex_file, 78389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 78489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers referrer_class); 785e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 786e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 787e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 788e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 7898cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 790e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 7911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 7921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 7934103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 7944103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 79589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 79600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (fields_class->GetDexCache() == dex_cache) { 7974103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 7984103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 7994103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 8004103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 8014103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 802c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 8034103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 8044103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 805e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // Search dex file for localized ssb index, may fail if field's class is a parent 806e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // of the class mentioned in the dex file and there is no dex cache entry. 8071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 8081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 80989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetDexFile()->FindStringId(descriptor); 8101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 8111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 81289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetDexFile()->FindTypeId(mUnit->GetDexFile()->GetIndexForStringId(*string_id)); 813b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes if (type_id != NULL) { 8141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 81589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers ssb_index = mUnit->GetDexFile()->GetIndexForTypeId(*type_id); 8161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 8171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 818c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 8191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 8201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 82700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 82800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 8291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 830c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 8311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 8321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 8331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 8341212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, 8351212a022fa5f8ef9585d765b1809521812af882cIan Rogers mirror::AbstractMethod* method, 8361212a022fa5f8ef9585d765b1809521812af882cIan Rogers uintptr_t& direct_code, 8371212a022fa5f8ef9585d765b1809521812af882cIan Rogers uintptr_t& direct_method) { 838137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // For direct and static methods compute possible direct_code and direct_method values, ie 839137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // an address for the Method* being invoked and an address of the code for that Method*. 840137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // For interface calls compute a value for direct_method that is the interface method being 841137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // invoked, so this can be passed to the out-of-line runtime support code. 8422ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 8432ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 844c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 845c531cefbfb5394413122e9f57d211ba436cff012buzbee if (sharp_type != kStatic && sharp_type != kDirect) { 846c531cefbfb5394413122e9f57d211ba436cff012buzbee return; 847c531cefbfb5394413122e9f57d211ba436cff012buzbee } 848c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 849c531cefbfb5394413122e9f57d211ba436cff012buzbee if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) { 850c531cefbfb5394413122e9f57d211ba436cff012buzbee return; 851c531cefbfb5394413122e9f57d211ba436cff012buzbee } 852b8404a7de94c109e3c17b4205b5f8aaae996eb33TDYa } 8532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL; 8542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (!method_code_in_boot) { 8552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 8562ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 8572ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized(); 8582ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (has_clinit_trampoline) { 8592ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 8602ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 861c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers if (sharp_type != kInterface) { // Interfaces always go via a trampoline. 862c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers stats_->DirectCallsToBoot(type); 863c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers } 8642ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->DirectMethodsToBoot(type); 8653fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 8663fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (compiling_boot) { 8670637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom const bool kSupportBootImageFixup = true; 8683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (kSupportBootImageFixup) { 8693fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MethodHelper mh(method); 8703fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (IsImageClass(mh.GetDeclaringClassDescriptor())) { 8710637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // We can only branch directly to Methods that are resolved in the DexCache. 8720637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // Otherwise we won't invoke the resolution trampoline. 8733fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = -1; 8740637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom direct_code = -1; 8753fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8773fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } else { 878b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method)->IsImageSpace()) { 8793fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = reinterpret_cast<uintptr_t>(method); 8803fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8813fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_code = reinterpret_cast<uintptr_t>(method->GetCode()); 8822ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 8832ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers} 8842ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 88589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeInvokeInfo(uint32_t method_idx, const DexCompilationUnit* mUnit, 8861212a022fa5f8ef9585d765b1809521812af882cIan Rogers InvokeType& type, int& vtable_idx, uintptr_t& direct_code, 8871212a022fa5f8ef9585d765b1809521812af882cIan Rogers uintptr_t& direct_method) { 88800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 889a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 8902ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 8912ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 8922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* resolved_method = 89308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers ComputeMethodReferencedFromCompilingMethod(soa, mUnit, method_idx, type); 894a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 89508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Don't try to fast-path if we don't understand the caller's class or this appears to be an 89608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Incompatible Class Change Error. 8972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit); 89808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers bool icce = resolved_method->CheckIncompatibleClassChange(type); 89908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (referrer_class != NULL && !icce) { 9002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* methods_class = resolved_method->GetDeclaringClass(); 901a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 902a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 903996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 904a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 905a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 90608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // method public. Resort to the dex file to determine the correct class for the access 90708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // check. 9084445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 909a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers methods_class = 91089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetClassLinker()->ResolveType(dex_file, 91189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_file.GetMethodId(method_idx).class_idx_, 91289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers referrer_class); 913a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 914a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 915137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers referrer_class->CanAccessMember(methods_class, resolved_method->GetAccessFlags())) { 916a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 917f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers const bool kEnableSharpening = true; 9182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Sharpen a virtual call into a direct call when the target is known. 9192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() || 92008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers methods_class->IsFinal()); 92108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Ensure the vtable index will be correct to dispatch in the vtable of the super class. 9224155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class && 92308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_class->IsSubClass(methods_class) && 92408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers vtable_idx < methods_class->GetVTable()->GetLength() && 92508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers methods_class->GetVTable()->Get(vtable_idx) == resolved_method); 9262ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (kEnableSharpening && can_sharpen) { 9272ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->ResolvedMethod(type); 928fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 929fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 930fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method) 93108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers << PrettyMethod(resolved_method); 9322ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->VirtualMadeDirect(type); 9332ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method); 934fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers type = kDirect; 935fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 9362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else if (type == kSuper) { 93708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Unsharpened super calls are suspicious so go slow-path. 9382ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else { 939c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 9402ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method); 941a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 942a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 943a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 944a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 945a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 946a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Clean up any exception left by method/type resolution 94700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 94800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 949a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 950c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedMethod(type); 951a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 952a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 953a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 9541212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddCodePatch(const DexFile* dex_file, 955f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 95608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType referrer_invoke_type, 957f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 95808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType target_invoke_type, 9593fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 96050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 96100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers code_to_patch_.push_back(new PatchInformation(dex_file, 962f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 96308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_invoke_type, 964f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 96508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers target_invoke_type, 966f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 9673fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 9681212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddMethodPatch(const DexFile* dex_file, 969f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 97008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType referrer_invoke_type, 971f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 97208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType target_invoke_type, 9733fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 97450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 97500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers methods_to_patch_.push_back(new PatchInformation(dex_file, 976f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 97708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_invoke_type, 978f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 97908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers target_invoke_type, 980f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 9813fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 9823fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers 983219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersclass ParallelCompilationManager { 984731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public: 985219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers typedef void Callback(const ParallelCompilationManager* manager, size_t index); 9860e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier 987219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager(ClassLinker* class_linker, 988219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers jobject class_loader, 989219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers CompilerDriver* compiler, 990219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile* dex_file, 991219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ThreadPool& thread_pool) 992731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom : class_linker_(class_linker), 993731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom class_loader_(class_loader), 994731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom compiler_(compiler), 9950e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier dex_file_(dex_file), 9962f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom thread_pool_(&thread_pool) {} 997731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 99800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* GetClassLinker() const { 999731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(class_linker_ != NULL); 1000731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_linker_; 1001731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 100200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 100300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject GetClassLoader() const { 1004731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_loader_; 1005731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 100600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 10071212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompilerDriver* GetCompiler() const { 1008731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(compiler_ != NULL); 1009731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return compiler_; 1010731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 101100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 101200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile* GetDexFile() const { 1013731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_file_ != NULL); 1014731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_file_; 1015731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 1016731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 10170e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) { 10180e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier Thread* self = Thread::Current(); 10190e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier self->AssertNoPendingException(); 10200e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CHECK_GT(work_units, 0U); 10219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 102202b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier std::vector<ForAllClosure*> closures(work_units); 10230e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier for (size_t i = 0; i < work_units; ++i) { 10240e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier closures[i] = new ForAllClosure(this, begin + i, end, callback, work_units); 10250e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->AddTask(self, closures[i]); 10260e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 10270e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->StartWorkers(self); 102800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 10290e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker 10300e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // thread destructor's called below perform join). 10310e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CHECK_NE(self->GetState(), kRunnable); 1032d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 10330e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Wait for all the worker threads to finish. 10340e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->Wait(self); 1035d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1036d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1037d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 1038d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 103902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier class ForAllClosure : public Task { 10400e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier public: 1041219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ForAllClosure(ParallelCompilationManager* manager, size_t begin, size_t end, Callback* callback, 10420e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier size_t stripe) 1043219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers : manager_(manager), 10440e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier begin_(begin), 10450e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier end_(end), 10460e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier callback_(callback), 10470e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier stripe_(stripe) 10480e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier { 10491e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 1050aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 10519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 10520e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier virtual void Run(Thread* self) { 10530e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier for (size_t i = begin_; i < end_; i += stripe_) { 1054219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers callback_(manager_, i); 10550e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier self->AssertNoPendingException(); 10560e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 10570e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 105802b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier 105902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier virtual void Finalize() { 106002b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier delete this; 106102b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier } 10620e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier private: 1063219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const ParallelCompilationManager* const manager_; 10640e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t begin_; 10650e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t end_; 1066219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const Callback* const callback_; 10670e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t stripe_; 10680e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier }; 10691e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 10700e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier ClassLinker* const class_linker_; 10710e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const jobject class_loader_; 10721212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompilerDriver* const compiler_; 10730e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const DexFile* const dex_file_; 1074219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ThreadPool* const thread_pool_; 1075d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 1076d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 107700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Return true if the class should be skipped during compilation. We 107800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// never skip classes in the boot class loader. However, if we have a 107900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// non-boot class loader and we can resolve the class in the boot 108000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// class loader, we do skip the class. This happens if an app bundles 108100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// classes found in the boot classpath. Since at runtime we will 108200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// select the class from the boot classpath, do not attempt to resolve 108300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// or compile it now. 10842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool SkipClass(mirror::ClassLoader* class_loader, 108500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile& dex_file, 108600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::ClassDef& class_def) 1087b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 108800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (class_loader == NULL) { 108900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return false; 109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 109100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* descriptor = dex_file.GetClassDescriptor(class_def); 109200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 10932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker->FindClass(descriptor, NULL); 109400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (klass == NULL) { 109500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 109600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK(self->IsExceptionPending()); 109700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->ClearException(); 109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return false; 109900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 110000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return true; 110100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 110200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 1103219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager, size_t class_def_index) 1104b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 110500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1106219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 1107219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile& dex_file = *manager->GetDexFile(); 1108d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1109845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 1110845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 1111845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 1112845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 1113845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 1114845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 1115845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 1116d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 111700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (SkipClass(class_loader, dex_file, class_def)) { 1118d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1119d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1120845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 1121d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 1122d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 1123d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 1124d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 1125d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 1126d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 1127d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1128d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1129d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1130219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ClassLinker* class_linker = manager->GetClassLinker(); 11312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1132d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 1133d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 11342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 11352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers class_loader, true); 1136d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1137d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1138d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 11390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1140d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1141d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1142fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers // If an instance field is final then we need to have a barrier on the return, static final 1143fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers // fields are assigned within the lock held for class initialization. 1144fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers bool requires_constructor_barrier = false; 1145d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 1146fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers if ((it.GetMemberAccessFlags() & kAccFinal) != 0) { 1147fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers requires_constructor_barrier = true; 1148fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers } 1149fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 11502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 11512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers class_loader, false); 1152d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1153d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1154d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 115520cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1156d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1157d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1158fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers if (requires_constructor_barrier) { 1159219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->AddRequiresConstructorBarrier(soa.Self(), manager->GetDexFile(), 1160fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_index); 1161fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers } 1162d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 11632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), 11642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers dex_cache, class_loader, NULL, 11652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers it.GetMethodInvokeType(class_def)); 1166d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1167d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1168d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1169845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1170d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1171d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1172d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 11732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), 11742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers dex_cache, class_loader, NULL, 11752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers it.GetMethodInvokeType(class_def)); 1176d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1177d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1178d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1179845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1180d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1181d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1182d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 1183d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1184d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1185219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void ResolveType(const ParallelCompilationManager* manager, size_t type_idx) 1186b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 1187d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 118800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1189219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ClassLinker* class_linker = manager->GetClassLinker(); 1190219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile& dex_file = *manager->GetDexFile(); 11912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1192219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 11932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 119400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 1195d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 119600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK(soa.Self()->IsExceptionPending()); 1197d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1198d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1199d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1200d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12011212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file, 12021212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1203d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1204d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 120500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: we could resolve strings here, although the string table is largely filled with class 120600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // and method names. 1207d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1208219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool); 12090e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_); 1210ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 1211d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12120e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 1213ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 12149ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 12159ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 12161212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files, 12171212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1218ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1219ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 122098eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 12212f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom VerifyDexFile(class_loader, *dex_file, thread_pool, timings); 122298eacac683b78e60799323e8c7d59e7214808639jeffhao } 122398eacac683b78e60799323e8c7d59e7214808639jeffhao} 122498eacac683b78e60799323e8c7d59e7214808639jeffhao 1225219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index) 1226b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 122700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1228219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index); 1229219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def); 12302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = 1231219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->FindClass(descriptor, 1232219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader())); 1233d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 1234d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1235d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1236d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1237f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao 1238f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao /* 1239f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * At compile time, we can still structurally verify the class even if FindClass fails. 1240f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * This is to ensure the class is structurally sound for compilation. An unsound class 1241f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * will be rejected by the verifier and later skipped during compilation in the compiler. 1242f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao */ 1243219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::DexCache* dex_cache = manager->GetClassLinker()->FindDexCache(*manager->GetDexFile()); 1244f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao std::string error_msg; 1245219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers if (verifier::MethodVerifier::VerifyClass(manager->GetDexFile(), 124600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_cache, 1247219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()), 124800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_def_index, error_msg) == 124900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers verifier::MethodVerifier::kHardFailure) { 1250219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index); 1251f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao LOG(ERROR) << "Verification failed on class " 1252219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers << PrettyDescriptor(manager->GetDexFile()->GetClassDescriptor(class_def)) 1253f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << " because: " << error_msg; 1254f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao } 1255d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1256d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1257d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 1258219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->VerifyClass(klass); 1259d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1260d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 1261d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 1262d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 1263d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1264d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1265d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12669ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous()) 12679ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers << PrettyDescriptor(klass) << ": state=" << klass->GetStatus(); 1268d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 1269d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1270d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12711212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file, 12721212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1273731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1274219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool); 12750e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 12763d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("Verify " + dex_file.GetLocation()); 1277a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1278a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 127964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic const char* class_initializer_black_list[] = { 128064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/app/ActivityThread;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/bluetooth/BluetoothAudioGateway;", // Calls android.bluetooth.BluetoothAudioGateway.classInitNative(). 128264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/bluetooth/HeadsetBase;", // Calls android.bluetooth.HeadsetBase.classInitNative(). 128364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/res/CompatibilityInfo;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 128464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/res/CompatibilityInfo$1;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 128564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/UriMatcher;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/CursorWindow;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 128764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteConnection;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteConnection$Operation;", // Requires SimpleDateFormat -> java.util.Locale. 128964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteDatabaseConfiguration;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 129064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteDebug;", // Calls android.util.Log.isLoggable. 129164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteOpenHelper;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 129264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteQueryBuilder;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 129364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/drm/DrmManagerClient;", // Calls System.loadLibrary. 129464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/AnimatedRotateDrawable;", // Sub-class of Drawable. 129564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/AnimationDrawable;", // Sub-class of Drawable. 129664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/BitmapDrawable;", // Sub-class of Drawable. 129764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ClipDrawable;", // Sub-class of Drawable. 129864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ColorDrawable;", // Sub-class of Drawable. 129964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/Drawable;", // Requires android.graphics.Rect. 130064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/DrawableContainer;", // Sub-class of Drawable. 130164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/GradientDrawable;", // Sub-class of Drawable. 130264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/LayerDrawable;", // Sub-class of Drawable. 130364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/NinePatchDrawable;", // Sub-class of Drawable. 130464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/RotateDrawable;", // Sub-class of Drawable. 130564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ScaleDrawable;", // Sub-class of Drawable. 130664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ShapeDrawable;", // Sub-class of Drawable. 130764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/StateListDrawable;", // Sub-class of Drawable. 130864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/TransitionDrawable;", // Sub-class of Drawable. 130964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Matrix;", // Calls android.graphics.Matrix.native_create. 131064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Matrix$1;", // Requires Matrix. 131164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/PixelFormat;", // Calls android.graphics.PixelFormat.nativeClassInit(). 131264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Rect;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 131364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/SurfaceTexture;", // Calls android.graphics.SurfaceTexture.nativeClassInit(). 131464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Typeface;", // Calls android.graphics.Typeface.nativeCreate. 131564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/inputmethodservice/ExtractEditText;", // Requires android.widget.TextView. 131664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/CameraProfile;", // Calls System.loadLibrary. 131764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/DecoderCapabilities;", // Calls System.loadLibrary. 131864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaFile;", // Requires DecoderCapabilities. 131964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaPlayer;", // Calls System.loadLibrary. 132064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaRecorder;", // Calls System.loadLibrary. 132164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaScanner;", // Calls System.loadLibrary. 132264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/NetworkInfo;", // Calls java.util.EnumMap.<init> -> java.lang.Enum.getSharedConstants -> System.identityHashCode. 132364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Proxy;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 132464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/SSLCertificateSocketFactory;", // Requires javax.net.ssl.HttpsURLConnection. 132564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 132664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$AbstractHierarchicalUri;", // Requires Uri. 132764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$HierarchicalUri;", // Requires Uri. 132864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$OpaqueUri;", // Requires Uri. 132964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$StringUri;", // Requires Uri. 133064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/WebAddress;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 133164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/nfc/NdefRecord;", // Calls String.getBytes -> java.nio.charset.Charset. 133264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES10;", // Calls android.opengl.GLES10._nativeClassInit. 133364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES10Ext;", // Calls android.opengl.GLES10Ext._nativeClassInit. 133464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES11;", // Requires GLES10. 133564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES11Ext;", // Calls android.opengl.GLES11Ext._nativeClassInit. 133664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES20;", // Calls android.opengl.GLES20._nativeClassInit. 133764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLUtils;", // Calls android.opengl.GLUtils.nativeClassInit. 133864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Build;", // Calls -..-> android.os.SystemProperties.native_get. 133964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Build$VERSION;", // Requires Build. 134064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Debug;", // Requires android.os.Environment. 134164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Environment;", // Calls System.getenv. 134264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/FileUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 134364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/StrictMode;", // Calls android.util.Log.isLoggable. 134464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/StrictMode$VmPolicy;", // Requires StrictMode. 134564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Trace;", // Calls android.os.Trace.nativeGetEnabledTags. 134664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/UEventObserver;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 134764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/provider/Settings$Secure;", // Requires android.net.Uri. 134864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/provider/Settings$System;", // Requires android.net.Uri. 134964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/renderscript/RenderScript;", // Calls System.loadLibrary. 135064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/server/BluetoothService;", // Calls android.server.BluetoothService.classInitNative. 135164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/server/BluetoothEventLoop;", // Calls android.server.BluetoothEventLoop.classInitNative. 135264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/telephony/PhoneNumberUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 135364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/AutoText;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 135464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/Layout;", // Calls com.android.internal.util.ArrayUtils.emptyArray -> System.identityHashCode. 135564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/BoringLayout;", // Requires Layout. 135664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/DynamicLayout;", // Requires Layout. 135764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/Html$HtmlParser;", // Calls -..-> String.toLowerCase -> java.util.Locale. 135864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/StaticLayout;", // Requires Layout. 135964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/TextUtils;", // Requires android.util.DisplayMetrics. 136064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/util/DisplayMetrics;", // Calls SystemProperties.native_get_int. 136164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/util/Patterns;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 136264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/animation/Animation;", // Calls SystemProperties.native_get_boolean. 136364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/animation/AlphaAnimation;", // Requires Animation. 136464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/Choreographer;", // Calls SystemProperties.native_get_boolean. 136564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/GLES20Canvas;", // Calls android.view.GLES20Canvas.nIsAvailable. 136664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/GLES20RecordingCanvas;", // Requires android.view.GLES20Canvas. 136764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/HardwareRenderer$GlRenderer;", // Requires SystemProperties.native_get. 136864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/HardwareRenderer$Gl20Renderer;", // Requires SystemProperties.native_get. 136964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/InputEventConsistencyVerifier;", // Requires android.os.Build. 137064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/Surface;", // Requires SystemProperties.native_get. 137164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/webkit/JniUtil;", // Calls System.loadLibrary. 137264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/webkit/WebViewCore;", // Calls System.loadLibrary. 137364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/AutoCompleteTextView;", // Requires TextView. 137464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/Button;", // Requires TextView. 137564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CheckBox;", // Requires TextView. 137664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CheckedTextView;", // Requires TextView. 137764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CompoundButton;", // Requires TextView. 137864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/EditText;", // Requires TextView. 137964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/NumberPicker;", // Requires java.util.Locale. 138064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/ScrollBarDrawable;", // Sub-class of Drawable. 138164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/SearchView$SearchAutoComplete;", // Requires TextView. 138264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/Switch;", // Requires TextView. 138364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/TextView;", // Calls Paint.<init> -> Paint.native_init. 138464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 138564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/i18n/phonenumbers/PhoneNumberUtil;", // Requires java.util.logging.LogManager. 138664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/os/SamplingProfilerIntegration;", // Calls SystemProperties.native_get_int. 138764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/policy/impl/PhoneWindow;", // Calls android.os.Binder.init. 138864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/view/menu/ActionMenuItemView;", // Requires TextView. 138964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/widget/DialogTitle;", // Requires TextView. 139064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/asn1/StreamUtil;", // Calls Runtime.getRuntime().maxMemory(). 139164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 139264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/crypto/engines/RSABlindedEngine;", // Calls native ... -> java.math.NativeBN.BN_new(). 139364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/jce/provider/CertBlacklist;", // Calls System.getenv -> OsConstants.initConstants. 139464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi;", // Calls System.getenv -> OsConstants.initConstants. 139564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/EGLContextImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit. 139664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/EGLImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit. 139764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/GLImpl;", // Calls com.google.android.gles_jni.GLImpl._nativeClassInit. 139864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/Console;", // Has FileDescriptor(s). 139964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/File;", // Calls to Random.<init> -> System.currentTimeMillis -> OsConstants.initConstants. 140064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/FileDescriptor;", // Requires libcore.io.OsConstants. 140164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectInputStream;", // Requires java.lang.ClassLoader$SystemClassLoader. 140264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectStreamClass;", // Calls to Class.forName -> java.io.FileDescriptor. 140364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectStreamConstants;", // Instance of non-image class SerializablePermission. 140464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/ClassLoader$SystemClassLoader;", // Calls System.getProperty -> OsConstants.initConstants. 140564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/Runtime;", // Calls System.getProperty -> OsConstants.initConstants. 140664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/System;", // Calls OsConstants.initConstants. 140764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/BigDecimal;", // Calls native ... -> java.math.NativeBN.BN_new(). 140864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/BigInteger;", // Calls native ... -> java.math.NativeBN.BN_new(). 140964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/Multiplication;", // Calls native ... -> java.math.NativeBN.BN_new(). 141064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/InetAddress;", // Requires libcore.io.OsConstants. 141164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/Inet4Address;", // Sub-class of InetAddress. 141264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/Inet6Address;", // Sub-class of InetAddress. 141364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/Charset;", // Calls Charset.getDefaultCharset -> System.getProperty -> OsConstants.initConstants. 141464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/CharsetICU;", // Sub-class of Charset. 141564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/Charsets;", // Calls Charset.forName. 141664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/security/Security;", // Tries to do disk IO for "security.properties". 141764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/Date;", // Calls Date.<init> -> System.currentTimeMillis -> OsConstants.initConstants. 141864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/Locale;", // Calls System.getProperty -> OsConstants.initConstants. 141964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/SimpleTimeZone;", // Sub-class of TimeZone. 142064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/TimeZone;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 142164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/concurrent/ConcurrentHashMap$Segment;", // Calls Runtime.getRuntime().availableProcessors(). 142264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/logging/LogManager;", // Calls System.getProperty -> OsConstants.initConstants. 142364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/microedition/khronos/egl/EGL10;", // Requires EGLContext. 142464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/microedition/khronos/egl/EGLContext;", // Requires com.google.android.gles_jni.EGLImpl. 142564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/net/ssl/HttpsURLConnection;", // Calls SSLSocketFactory.getDefault -> java.security.Security.getProperty. 142664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/icu/LocaleData;", // Requires java.util.Locale. 142764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/icu/TimeZones;", // Requires java.util.TimeZone. 142864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/io/OsConstants;", // Platform specific. 142964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/net/MimeUtils;", // Calls libcore.net.MimeUtils.getContentTypesPropertiesStream -> System.getProperty. 143064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/util/ZoneInfo;", // Sub-class of TimeZone. 143164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/util/ZoneInfoDB;", // Calls System.getenv -> OsConstants.initConstants. 143264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/commons/logging/LogFactory;", // Calls System.getProperty. 143364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/fortress/Services;", // Calls ClassLoader.getSystemClassLoader -> System.getProperty. 143464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/provider/cert/X509CertFactoryImpl;", // Requires java.nio.charsets.Charsets. 143564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/provider/crypto/RandomBitsSupplier;", // Requires java.io.File. 143664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/utils/AlgNameMapper;", // Requires java.util.Locale. 143764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/AttributeTypeAndValue;", // Calls IntegralToString.convertInt -> Thread.currentThread. 143864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/DirectoryString;", // Requires BigInteger. 143964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/Name;", // Requires org.apache.harmony.security.x501.AttributeTypeAndValue. 144064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Certificate;", // Requires org.apache.harmony.security.x509.TBSCertificate. 144164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/TBSCertificate;", // Requires org.apache.harmony.security.x501.Name. 144264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/EDIPartyName;", // Calls native ... -> java.math.NativeBN.BN_new(). 144364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/GeneralName;", // Requires org.apache.harmony.security.x501.Name. 144464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/GeneralNames;", // Requires GeneralName. 144564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Time;", // Calls native ... -> java.math.NativeBN.BN_new(). 144664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Validity;", // Requires x509.Time. 144764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xml/ExpatParser;", // Calls native ExpatParser.staticInitialize. 144864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto;", // Calls native NativeCrypto.clinit(). 144964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$MD5;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 145064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 145164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA512;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 145264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/TrustedCertificateStore;", // Calls System.getenv -> OsConstants.initConstants. 145364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/params/ConnRouteParams;", // Requires java.util.Locale. 145464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/ssl/SSLSocketFactory;", // Calls java.security.Security.getProperty. 145564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/util/InetAddressUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 145664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers}; 145764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 1458219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index) 14593d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 1460219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index); 146100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1462219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 1463219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def); 1464219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor, class_loader); 14651f5393447b9f45be7918042d9ee7b521376de866Ian Rogers Thread* self = Thread::Current(); 146664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 146764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool can_init_static_fields = compiling_boot && 1468219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->IsImageClass(descriptor); 14693d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass != NULL) { 147064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't want class initialization occurring on multiple threads due to deadlock problems. 147164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // For example, a parent class is initialized (holding its lock) that refers to a sub-class 147264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // in its static/class initializer causing it to try to acquire the sub-class' lock. While 147364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // on a second thread the sub-class is initialized (holding its lock) after first initializing 147464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent 147564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // lock ordering and consequent potential deadlock. 147664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers static Mutex lock1("Initializer lock", kMonitorLock); 147764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers MutexLock mu(self, lock1); 147864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // The lock required to initialize the class. 147964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ObjectLock lock2(self, klass); 148064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Only try to initialize classes that were successfully verified. 14813d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass->IsVerified()) { 1482219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields); 148364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!klass->IsInitialized()) { 148464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (can_init_static_fields) { 148564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool is_black_listed = false; 148664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) { 148764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (StringPiece(descriptor) == class_initializer_black_list[i]) { 148864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers is_black_listed = true; 148964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers break; 149064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 149164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 149264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!is_black_listed) { 149364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(INFO) << "Initializing: " << descriptor; 149464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (StringPiece(descriptor) == "Ljava/lang/Void;"){ 149564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime. 14962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields(); 149764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK_EQ(fields->GetLength(), 1); 1498219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers fields->Get(0)->SetObj(klass, manager->GetClassLinker()->FindPrimitiveClass('V')); 14992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass->SetStatus(mirror::Class::kStatusInitialized); 150064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 1501219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->EnsureInitialized(klass, true, can_init_static_fields); 150264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 150364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(!self->IsExceptionPending()) << self->GetException()->Dump(); 150464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 150564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 150664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 15073d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers // If successfully initialized place in SSB array. 15083d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass->IsInitialized()) { 15093d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers klass->GetDexCache()->GetInitializedStaticStorage()->Set(klass->GetDexTypeIndex(), klass); 15100755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 151127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 15123d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers // Record the final class status if necessary. 15132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class::Status status = klass->GetStatus(); 1514219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers CompilerDriver::ClassReference ref(manager->GetDexFile(), class_def_index); 1515219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers CompiledClass* compiled_class = manager->GetCompiler()->GetCompiledClass(ref); 15163d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (compiled_class == NULL) { 15173d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers compiled_class = new CompiledClass(status); 1518219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->RecordClassStatus(ref, compiled_class); 15193d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers } else { 15203d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers DCHECK_EQ(status, compiled_class->GetStatus()); 1521ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 152298eacac683b78e60799323e8c7d59e7214808639jeffhao } 15231f5393447b9f45be7918042d9ee7b521376de866Ian Rogers // Clear any class not found or verification exceptions. 15241f5393447b9f45be7918042d9ee7b521376de866Ian Rogers self->ClearException(); 152598eacac683b78e60799323e8c7d59e7214808639jeffhao} 152698eacac683b78e60799323e8c7d59e7214808639jeffhao 15271212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file, 15281212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 152964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#ifndef NDEBUG 153064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) { 153164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers const char* descriptor = class_initializer_black_list[i]; 153264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(IsValidDescriptor(descriptor)) << descriptor; 153364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 153464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#endif 15353d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1536219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, thread_pool); 153764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count_); 15383d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("InitializeNoClinit " + dex_file.GetLocation()); 15393d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers} 154090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 15411212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InitializeClasses(jobject class_loader, 15421212a022fa5f8ef9585d765b1809521812af882cIan Rogers const std::vector<const DexFile*>& dex_files, 15431212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 15443d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers for (size_t i = 0; i != dex_files.size(); ++i) { 15453d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers const DexFile* dex_file = dex_files[i]; 154690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(dex_file != NULL); 15472f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom InitializeClasses(class_loader, *dex_file, thread_pool, timings); 154800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 154990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao} 155090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 15511212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 15522f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 1553ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1554ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 155583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 15562f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompileDexFile(class_loader, *dex_file, thread_pool, timings); 155783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 155883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 155983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 1560219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersvoid CompilerDriver::CompileClass(const ParallelCompilationManager* manager, size_t class_def_index) { 1561219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers jobject class_loader = manager->GetClassLoader(); 1562219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile& dex_file = *manager->GetDexFile(); 1563c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 156400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 156500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1566219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 156700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (SkipClass(class_loader, dex_file, class_def)) { 156800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 156900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 15705ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 1571d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 1572d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 1573776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (verifier::MethodVerifier::IsClassRejected(ref)) { 1574d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 1575d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 15760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 15770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 15780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 15790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 15800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 15810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 15820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 15830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 15840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 15850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 15860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 15870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 15880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 15890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 159068adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom int64_t previous_direct_method_idx = -1; 15910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 15926f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 15936f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom if (method_idx == previous_direct_method_idx) { 15946f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // smali can create dex files with two encoded_methods sharing the same method_idx 15956f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // http://code.google.com/p/smali/issues/detail?id=119 15966f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom it.Next(); 15976f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom continue; 15986f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom } 15996f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom previous_direct_method_idx = method_idx; 1600219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1601fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers it.GetMethodInvokeType(class_def), class_def_index, 1602fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 16030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 16049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 16050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 160668adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom int64_t previous_virtual_method_idx = -1; 16070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 16086f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 16096f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom if (method_idx == previous_virtual_method_idx) { 16106f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // smali can create dex files with two encoded_methods sharing the same method_idx 16116f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // http://code.google.com/p/smali/issues/detail?id=119 16126f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom it.Next(); 16136f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom continue; 16146f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom } 16156f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom previous_virtual_method_idx = method_idx; 1616219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1617fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers it.GetMethodInvokeType(class_def), class_def_index, 1618fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 16190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 16209ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 16210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 16229ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 16239ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 16241212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file, 16251212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1626219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(NULL, class_loader, this, &dex_file, thread_pool); 16271212a022fa5f8ef9585d765b1809521812af882cIan Rogers context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_); 16283d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("Compile " + dex_file.GetLocation()); 1629c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1630c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 1631a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 1632a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes std::string key(shorty); 1633a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes if (is_static) { 1634a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes key += "$"; // Must not be a shorty type character. 1635a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 1636a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes return key; 1637a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes} 1638a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes 16391212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 16401212a022fa5f8ef9585d765b1809521812af882cIan Rogers InvokeType invoke_type, uint32_t class_def_idx, 16411212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t method_idx, jobject class_loader, 16421212a022fa5f8ef9585d765b1809521812af882cIan Rogers const DexFile& dex_file) { 1643f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1644bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 16454dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1646169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 164757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file); 16483320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1649169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 16502cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 1651fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx, 1652fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 1653bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1654bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 16553bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 1656c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#ifdef ART_USE_PORTABLE_COMPILER 16575354ec568ace1e117d5a93dcb802a612356200edIan Rogers const uint64_t kWarnMilliSeconds = 1000; 16585354ec568ace1e117d5a93dcb802a612356200edIan Rogers#else 16595354ec568ace1e117d5a93dcb802a612356200edIan Rogers const uint64_t kWarnMilliSeconds = 100; 16605354ec568ace1e117d5a93dcb802a612356200edIan Rogers#endif 16615354ec568ace1e117d5a93dcb802a612356200edIan Rogers if (duration_ns > MsToNs(kWarnMilliSeconds)) { 1662bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 16633bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1664f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1665f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 166650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 1667f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 16680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 16690755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 167000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 167150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 167200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers compiled_methods_.Put(ref, compiled_method); 167300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 16740755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 16752cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 16769baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 167745619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers uint32_t shorty_len; 167845619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); 1679169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 1680a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 1681265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key); 16820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 1683c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len); 16840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 1685a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes InsertInvokeStub(key, compiled_invoke_stub); 16863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 16877a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 1688c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if ((compiler_backend_ == kPortable) && !is_static) { 1689265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty); 16907a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub == NULL) { 16917a2a23a44d27f769718e28327af671f4e486c49aLogan Chien compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len); 16927a2a23a44d27f769718e28327af671f4e486c49aLogan Chien CHECK(compiled_proxy_stub != NULL); 16937a2a23a44d27f769718e28327af671f4e486c49aLogan Chien InsertProxyStub(shorty, compiled_proxy_stub); 16947a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 16957a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 16967a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 169750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (self->IsExceptionPending()) { 169850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ScopedObjectAccess soa(self); 169900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n" 170050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers << self->GetException()->Dump(); 170100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 17020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 170328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 1704265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub* CompilerDriver::FindInvokeStub(bool is_static, const char* shorty) const { 1705a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 1706a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes return FindInvokeStub(key); 17073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 17083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1709265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub* CompilerDriver::FindInvokeStub(const std::string& key) const { 171050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_); 17110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 17120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 17133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 17140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 17150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 17160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 17173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 17183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 17193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1720265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompilerDriver::InsertInvokeStub(const std::string& key, CompiledInvokeStub* compiled_invoke_stub) { 172150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_); 1722a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key); 1723a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes if (it != compiled_invoke_stubs_.end()) { 1724a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes // Someone else won the race. 1725a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes delete compiled_invoke_stub; 1726a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } else { 1727a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes compiled_invoke_stubs_.Put(key, compiled_invoke_stub); 1728a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 17290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 17300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 1731265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub* CompilerDriver::FindProxyStub(const char* shorty) const { 173250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_); 17337a2a23a44d27f769718e28327af671f4e486c49aLogan Chien ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty); 17347a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (it == compiled_proxy_stubs_.end()) { 17357a2a23a44d27f769718e28327af671f4e486c49aLogan Chien return NULL; 17367a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } else { 17377a2a23a44d27f769718e28327af671f4e486c49aLogan Chien DCHECK(it->second != NULL); 17387a2a23a44d27f769718e28327af671f4e486c49aLogan Chien return it->second; 17397a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 17407a2a23a44d27f769718e28327af671f4e486c49aLogan Chien} 17417a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 1742265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompilerDriver::InsertProxyStub(const char* shorty, CompiledInvokeStub* compiled_proxy_stub) { 174350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_); 17447a2a23a44d27f769718e28327af671f4e486c49aLogan Chien InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty); 17457a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (it != compiled_proxy_stubs_.end()) { 17467a2a23a44d27f769718e28327af671f4e486c49aLogan Chien // Someone else won the race. 17477a2a23a44d27f769718e28327af671f4e486c49aLogan Chien delete compiled_proxy_stub; 17487a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } else { 17497a2a23a44d27f769718e28327af671f4e486c49aLogan Chien compiled_proxy_stubs_.Put(shorty, compiled_proxy_stub); 17507a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 17517a2a23a44d27f769718e28327af671f4e486c49aLogan Chien} 17527a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 17531212a022fa5f8ef9585d765b1809521812af882cIan RogersCompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const { 175450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_classes_lock_); 17550755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 17560755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 17570755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 17580755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 17590755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 17600755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 17610755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 17620755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 17631212a022fa5f8ef9585d765b1809521812af882cIan RogersCompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const { 176450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 17650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 17660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 17673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 17682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 17693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 17703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 17719ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 17729ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 17731212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::SetBitcodeFileName(std::string const& filename) { 17741212a022fa5f8ef9585d765b1809521812af882cIan Rogers typedef void (*SetBitcodeFileNameFn)(CompilerDriver&, std::string const&); 1775106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1776106b2a03be66748a25b9019e4c222cee498d559fLogan Chien SetBitcodeFileNameFn set_bitcode_file_name = 17778c4bbb55d0d801e492d849ee636771c8b2840429buzbee FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, 1778106b2a03be66748a25b9019e4c222cee498d559fLogan Chien "compilerLLVMSetBitcodeFileName"); 1779106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1780106b2a03be66748a25b9019e4c222cee498d559fLogan Chien set_bitcode_file_name(*this, filename); 17818b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 1782f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 1783fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 17841212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1785fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers size_t class_def_index) { 1786fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MutexLock mu(self, freezing_constructor_lock_); 1787fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index)); 1788fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers} 1789fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 17901212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1791fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers size_t class_def_index) { 1792fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MutexLock mu(self, freezing_constructor_lock_); 1793fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0; 1794fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers} 1795fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 1796265091e581c9f643b37e7966890911f09e223269Brian Carlstrombool CompilerDriver::WriteElf(const std::string* host_prefix, 1797265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool is_host, 1798265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<const DexFile*>& dex_files, 1799265091e581c9f643b37e7966890911f09e223269Brian Carlstrom std::vector<uint8_t>& oat_contents, 1800265091e581c9f643b37e7966890911f09e223269Brian Carlstrom File* file) { 1801265091e581c9f643b37e7966890911f09e223269Brian Carlstrom typedef bool (*WriteElfFn)(CompilerDriver&, 1802265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::string* host_prefix, 1803265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool is_host, 1804265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<const DexFile*>& dex_files, 1805265091e581c9f643b37e7966890911f09e223269Brian Carlstrom std::vector<uint8_t>&, 1806265091e581c9f643b37e7966890911f09e223269Brian Carlstrom File*); 1807700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom WriteElfFn WriteElf = 1808700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf"); 1809265091e581c9f643b37e7966890911f09e223269Brian Carlstrom Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); 1810265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return WriteElf(*this, host_prefix, is_host, dex_files, oat_contents, file); 1811700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1812700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 18131212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::FixupElf(File* file, uintptr_t oat_data_begin) const { 1814700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*FixupElfFn)(File*, uintptr_t oat_data_begin); 1815700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FixupElfFn FixupElf = 1816700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<FixupElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "FixupElf"); 1817700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return FixupElf(file, oat_data_begin); 1818700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1819700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 18201212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::GetOatElfInformation(File* file, 18211212a022fa5f8ef9585d765b1809521812af882cIan Rogers size_t& oat_loaded_size, 18221212a022fa5f8ef9585d765b1809521812af882cIan Rogers size_t& oat_data_offset) const { 1823700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*GetOatElfInformationFn)(File*, size_t& oat_loaded_size, size_t& oat_data_offset); 1824700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom GetOatElfInformationFn GetOatElfInformation = 1825700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<GetOatElfInformationFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, 1826700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom "GetOatElfInformation"); 1827700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom GetOatElfInformation(file, oat_loaded_size, oat_data_offset); 1828700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1829700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1830265091e581c9f643b37e7966890911f09e223269Brian Carlstrombool CompilerDriver::StripElf(File* file) const { 1831265091e581c9f643b37e7966890911f09e223269Brian Carlstrom typedef bool (*StripElfFn)(File*); 1832265091e581c9f643b37e7966890911f09e223269Brian Carlstrom StripElfFn StripElf = 1833265091e581c9f643b37e7966890911f09e223269Brian Carlstrom FindFunction<StripElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "StripElf"); 1834265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return StripElf(file); 1835265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 1836265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 18371212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set, 18381212a022fa5f8ef9585d765b1809521812af882cIan Rogers std::string& target_triple, 18391212a022fa5f8ef9585d765b1809521812af882cIan Rogers std::string& target_cpu, 18401212a022fa5f8ef9585d765b1809521812af882cIan Rogers std::string& target_attr) { 1841265091e581c9f643b37e7966890911f09e223269Brian Carlstrom switch (instruction_set) { 1842700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kThumb2: 1843700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "thumb-none-linux-gnueabi"; 1844700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_cpu = "cortex-a9"; 1845700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db"; 1846700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1847700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1848700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kArm: 1849700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "armv7-none-linux-gnueabi"; 1850700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // TODO: Fix for Nexus S. 1851700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_cpu = "cortex-a9"; 1852700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // TODO: Fix for Xoom. 1853700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "+v7,+neon,+neonfp,+vfp3,+db"; 1854700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1855700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1856700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kX86: 1857700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "i386-pc-linux-gnu"; 1858700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = ""; 1859700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1860700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1861700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kMips: 1862700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "mipsel-unknown-linux"; 1863700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "mips32r2"; 1864700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1865700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1866700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom default: 1867700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom LOG(FATAL) << "Unknown instruction set: " << instruction_set; 1868700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 1869700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 18709ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1871