compiler_driver.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
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 179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "compiler.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" 259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 269baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 274dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#include "oat_compilation_unit.h" 283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 2900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "oat/runtime/stub.h" 306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 311f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "gc/card_table-inl.h" 337469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h" 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/dex_cache.h" 372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h" 4200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h" 4450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#include "thread.h" 450e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier#include "thread_pool.h" 46601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes#include "timing_logger.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. 249c531cefbfb5394413122e9f57d211ba436cff012buzbee std::string library_name; 250c531cefbfb5394413122e9f57d211ba436cff012buzbee if ((compiler_backend == kPortable) || (compiler_backend == kIceland)) { 251c531cefbfb5394413122e9f57d211ba436cff012buzbee library_name = StringPrintf("art%s-compiler-llvm", suffix); 252c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 2538c4bbb55d0d801e492d849ee636771c8b2840429buzbee library_name = StringPrintf("art%s-compiler", suffix); 254c531cefbfb5394413122e9f57d211ba436cff012buzbee } 255059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str())); 256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 257059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 258059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find 259059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the 260059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // same work. 261059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes uint32_t executable_path_length = 0; 262448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes _NSGetExecutablePath(NULL, &executable_path_length); 263448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes std::string path(executable_path_length, static_cast<char>(0)); 264448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0); 265059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/dex2oat". 267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes size_t last_slash = path.find_last_of('/'); 268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes CHECK_NE(last_slash, std::string::npos) << path; 269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/bin". 272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes last_slash = path.find_last_of('/'); 273059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 274059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 275059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes filename = path + "/lib/" + filename; 276059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 277059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes return filename; 278b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 279b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 28046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn> 28146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) { 28246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes Fn fn = reinterpret_cast<Fn>(dlsym(library, name)); 28346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes if (fn == NULL) { 28446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror(); 28546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes } 286059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn); 28746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes return fn; 28846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes} 28946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes 290c531cefbfb5394413122e9f57d211ba436cff012buzbeeCompiler::Compiler(CompilerBackend compiler_backend, InstructionSet instruction_set, bool image, 291c531cefbfb5394413122e9f57d211ba436cff012buzbee size_t thread_count, bool support_debugging, const std::set<std::string>* image_classes, 292ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom bool dump_stats, bool dump_timings) 293c531cefbfb5394413122e9f57d211ba436cff012buzbee : compiler_backend_(compiler_backend), 294c531cefbfb5394413122e9f57d211ba436cff012buzbee instruction_set_(instruction_set), 295fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers freezing_constructor_lock_("freezing constructor lock"), 296c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 297c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 298c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 2997a2a23a44d27f769718e28327af671f4e486c49aLogan Chien compiled_proxy_stubs_lock_("compiled proxy stubs lock"), 300aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 3015523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 302de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 30300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers start_ns_(0), 304c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 305ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_stats_(dump_stats), 306ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_timings_(dump_timings), 307b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes image_classes_(image_classes), 308b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_(NULL), 30946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes compiler_(NULL), 3106f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes compiler_context_(NULL), 31146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_(NULL), 3122f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom create_invoke_stub_(NULL) 313971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien{ 3148c4bbb55d0d801e492d849ee636771c8b2840429buzbee std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); 315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY); 316b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ == NULL) { 317b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror(); 318b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 319b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_; 320b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 3214df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key"); 3224df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee 323c531cefbfb5394413122e9f57d211ba436cff012buzbee // TODO: more work needed to combine initializations and allow per-method backend selection 324106b2a03be66748a25b9019e4c222cee498d559fLogan Chien typedef void (*InitCompilerContextFn)(Compiler&); 325c531cefbfb5394413122e9f57d211ba436cff012buzbee InitCompilerContextFn init_compiler_context; 326c531cefbfb5394413122e9f57d211ba436cff012buzbee if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){ 327c531cefbfb5394413122e9f57d211ba436cff012buzbee // Initialize compiler_context_ 328c531cefbfb5394413122e9f57d211ba436cff012buzbee init_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name, 329c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtInitCompilerContext"); 330c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod"); 331c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 332c531cefbfb5394413122e9f57d211ba436cff012buzbee init_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name, 333c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtInitQuickCompilerContext"); 334c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtQuickCompileMethod"); 335c531cefbfb5394413122e9f57d211ba436cff012buzbee } 336692be80cb2278ae585a776a163bc4b3ef60cae88buzbee 337692be80cb2278ae585a776a163bc4b3ef60cae88buzbee init_compiler_context(*this); 338106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 33946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtJniCompileMethod"); 34002031b185b4653e6c72e21f7a51238b903f6d638buzbee if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){ 34102031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 34202031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateLLVMInvokeStub"); 34302031b185b4653e6c72e21f7a51238b903f6d638buzbee } else { 34402031b185b4653e6c72e21f7a51238b903f6d638buzbee switch (instruction_set) { 34502031b185b4653e6c72e21f7a51238b903f6d638buzbee case kArm: 34602031b185b4653e6c72e21f7a51238b903f6d638buzbee case kThumb2: 34702031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 34802031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateArmInvokeStub"); 34902031b185b4653e6c72e21f7a51238b903f6d638buzbee break; 35002031b185b4653e6c72e21f7a51238b903f6d638buzbee case kMips: 35102031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 35202031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateMipsInvokeStub"); 35302031b185b4653e6c72e21f7a51238b903f6d638buzbee break; 35402031b185b4653e6c72e21f7a51238b903f6d638buzbee case kX86: 35502031b185b4653e6c72e21f7a51238b903f6d638buzbee create_invoke_stub_ = 35602031b185b4653e6c72e21f7a51238b903f6d638buzbee FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateX86InvokeStub"); 35702031b185b4653e6c72e21f7a51238b903f6d638buzbee break; 35802031b185b4653e6c72e21f7a51238b903f6d638buzbee default: 35902031b185b4653e6c72e21f7a51238b903f6d638buzbee LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 36002031b185b4653e6c72e21f7a51238b903f6d638buzbee } 36102031b185b4653e6c72e21f7a51238b903f6d638buzbee } 362b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 363c531cefbfb5394413122e9f57d211ba436cff012buzbee if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) { 364c531cefbfb5394413122e9f57d211ba436cff012buzbee create_proxy_stub_ = FindFunction<CreateProxyStubFn>( 365c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_so_name, compiler_library_, "ArtCreateProxyStub"); 366c531cefbfb5394413122e9f57d211ba436cff012buzbee } 367f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 36825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 369ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 370ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 371ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 372c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 373c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 3743320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() { 37550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 376c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 37750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_classes_lock_); 378c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 379c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 380c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 38150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 382c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 383c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 384c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 38550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_invoke_stubs_lock_); 386c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 387bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 388f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 38950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_proxy_stubs_lock_); 3907a2a23a44d27f769718e28327af671f4e486c49aLogan Chien STLDeleteValues(&compiled_proxy_stubs_); 3917a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 3927a2a23a44d27f769718e28327af671f4e486c49aLogan Chien { 39350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 394f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&code_to_patch_); 395f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 396f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 39750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 398f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&methods_to_patch_); 399f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 400ed6d5ed3494648780b9e91422c90d6bc22c16b79Mathieu Chartier CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key"); 401971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien typedef void (*UninitCompilerContextFn)(Compiler&); 4028c4bbb55d0d801e492d849ee636771c8b2840429buzbee std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); 403c531cefbfb5394413122e9f57d211ba436cff012buzbee UninitCompilerContextFn uninit_compiler_context; 404692be80cb2278ae585a776a163bc4b3ef60cae88buzbee // Uninitialize compiler_context_ 405c531cefbfb5394413122e9f57d211ba436cff012buzbee // TODO: rework to combine initialization/uninitialization 406c531cefbfb5394413122e9f57d211ba436cff012buzbee if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) { 407c531cefbfb5394413122e9f57d211ba436cff012buzbee uninit_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name, 408c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtUnInitCompilerContext"); 409c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 410c531cefbfb5394413122e9f57d211ba436cff012buzbee uninit_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name, 411c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtUnInitQuickCompilerContext"); 412c531cefbfb5394413122e9f57d211ba436cff012buzbee } 413692be80cb2278ae585a776a163bc4b3ef60cae88buzbee uninit_compiler_context(*this); 414b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ != NULL) { 415b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlclose(" << compiler_library_ << ")"; 416ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee /* 417ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * FIXME: Temporary workaround 418ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * Apparently, llvm is adding dctors to atexit, but if we unload 419ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * the library here the code will no longer be around at exit time 420ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * and we die a flaming death in __cxa_finalize(). Apparently, some 421ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * dlclose() implementations will scan the atexit list on unload and 422ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * handle any associated with the soon-to-be-unloaded library. 423ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * However, this is not required by POSIX and we don't do it. 424ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * See: http://b/issue?id=4998315 425ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * What's the right thing to do here? 426ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee */ 427b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dlclose(compiler_library_); 428b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 4293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 4303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4314df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbeeCompilerTls* Compiler::GetTls() { 4324df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee // Lazily create thread-local storage 4334df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_)); 4344df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee if (res == NULL) { 4354df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee res = new CompilerTls(); 4364df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls"); 4374df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee } 4384df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee return res; 4394df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee} 4404df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee 4412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, 4421cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type) { 4437fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao switch (instruction_set) { 4447fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kArm: 4457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kThumb2: 4467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return arm::ArmCreateResolutionTrampoline(type); 4477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kMips: 4487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return mips::MipsCreateResolutionTrampoline(type); 4497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kX86: 4507fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return x86::X86CreateResolutionTrampoline(type); 4517fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao default: 4527fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 4537fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return NULL; 454ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 455ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 456ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::ByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 458169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 459169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 460169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 4618add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 4627fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kMips: 4637fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return mips::CreateJniDlsymLookupStub(); 464169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 4658add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 466169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 46749c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 468169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 469169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 470169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 471169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 4737fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao switch (instruction_set) { 4747fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kArm: 4757fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kThumb2: 4767fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return arm::CreateAbstractMethodErrorStub(); 4777fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kMips: 4787fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return mips::CreateAbstractMethodErrorStub(); 4797fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao case kX86: 4807fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return x86::CreateAbstractMethodErrorStub(); 4817fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao default: 4827fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 4837fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao return NULL; 484ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 485ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 486ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 48700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::CompileAll(jobject class_loader, 488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 48925c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 49156edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_)); 492601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("compiler"); 493601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 49456edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers PreCompile(class_loader, dex_files, *thread_pool.get(), timings); 495601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 49656edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers Compile(class_loader, dex_files, *thread_pool.get(), timings); 497601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 498ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) { 499601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.Dump(); 500601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 501996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 502ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_stats_) { 503ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom stats_->Dump(); 504ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom } 5058a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 5068a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 5072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Compiler::CompileOne(const mirror::AbstractMethod* method) { 50825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 50900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 51000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader; 51100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile* dex_file; 512fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers uint32_t class_def_idx; 51300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 51400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(self); 51500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jobject> 51600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers local_class_loader(soa.Env(), 51700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader())); 51800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_loader = soa.Env()->NewGlobalRef(local_class_loader.get()); 51900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Find the dex_file 520fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MethodHelper mh(method); 521fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers dex_file = &mh.GetDexFile(); 522fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_idx = mh.GetClassDefIndex(); 52300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 52400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kNative); 525ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 526ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 52700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_files.push_back(dex_file); 528ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 52956edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers UniquePtr<ThreadPool> thread_pool(new ThreadPool(1U)); 530601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("CompileOne"); 53156edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers PreCompile(class_loader, dex_files, *thread_pool.get(), timings); 532ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 53400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); 53508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers CompileMethod(code_item, method->GetAccessFlags(), method->GetInvokeType(), 536fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_idx, method_idx, class_loader, *dex_file); 537ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 53800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->GetJniEnv()->DeleteGlobalRef(class_loader); 53900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 54000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 5419ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 5429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 54300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files, 5442f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 545ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 546ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 5479ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 5482f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ResolveDexFile(class_loader, *dex_file, thread_pool, timings); 5499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 5509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 5519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 55200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 5532f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 5542f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom Resolve(class_loader, dex_files, thread_pool, timings); 555601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 5562f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom Verify(class_loader, dex_files, thread_pool, timings); 557ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5582f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom InitializeClasses(class_loader, dex_files, thread_pool, timings); 559ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 561ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const { 562ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 563ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 564ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 565ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 566ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 567ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5683d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) { 56950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), Compiler::compiled_classes_lock_); 5703d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers compiled_classes_.Put(ref, compiled_class); 5713d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers} 5723d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers 57300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, 574996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 57500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 5762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 5776d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 578c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5796d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5806d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 5812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5826d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 583c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5846d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 586996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 587996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 588c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 589996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 590c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 591996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 592996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5936d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 5946d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 59500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, 596996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t string_idx) { 5971bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 5981bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5995f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers bool result = false; 6005f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers if (IsImage()) { 6015f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers // We resolve all const-string strings when building for the image. 60200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 6032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 6045f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache); 6055f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers result = true; 60600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 607996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 608c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 609996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 610c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 611996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 612996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 61500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, 61600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers uint32_t type_idx) { 61700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 6182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 6191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 6202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 6211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 622c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 6241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 6262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 628c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 6301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 6321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 633996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 634996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 635c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 636996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 637c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 638996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 639996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 6431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile& dex_file, 644996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 64500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 6462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 6471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 6482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 6491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 650c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 6521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 6542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 6551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 656c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 6571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 661996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 662996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 663c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 664996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 665c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 666996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 667996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa, 6712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers OatCompilationUnit* mUnit) 672b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 6732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_); 6742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_); 67500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::MethodId& referrer_method_id = mUnit->dex_file_->GetMethodId(mUnit->method_idx_); 67600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return mUnit->class_linker_->ResolveType(*mUnit->dex_file_, referrer_method_id.class_idx_, 67700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_cache, class_loader); 6784dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 679a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa, 6812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers OatCompilationUnit* mUnit, 6822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t field_idx) 683b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 6842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_); 6852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_); 68600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return mUnit->class_linker_->ResolveField(*mUnit->dex_file_, field_idx, dex_cache, 68700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_loader, false); 688a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 689a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa, 6912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers OatCompilationUnit* mUnit, 6922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t method_idx, 6932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers InvokeType type) 694b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 6952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_); 6962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_); 69700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return mUnit->class_linker_->ResolveMethod(*mUnit->dex_file_, method_idx, dex_cache, 698c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao class_loader, NULL, type); 699a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 700a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 7014dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 7028cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao int& field_offset, bool& is_volatile, bool is_put) { 70300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 70408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Conservative defaults. 7051bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 7061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 70708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Try to resolve field and ignore if an Incompatible Class Change Error (ie is static). 7082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx); 70908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (resolved_field != NULL && !resolved_field->IsStatic()) { 7102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit); 711e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (referrer_class != NULL) { 7122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 713e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 714e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 715e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 716e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 717e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 718e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 719e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. 7204445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 7212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file, 722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 723e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class); 724e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 725e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 726e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 727e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 728e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 729e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers fields_class != referrer_class; 730e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 731e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 732e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers is_volatile = resolved_field->IsVolatile(); 733e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers stats_->ResolvedInstanceField(); 734e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers return true; // Fast path. 735e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 7361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 73900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 74000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 7411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 742c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 7431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 7441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 7451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 7464dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 7471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers int& field_offset, int& ssb_index, 7488cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool& is_referrers_class, bool& is_volatile, bool is_put) { 74900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 75008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Conservative defaults. 7511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 7521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 7531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 7541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 75508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static). 7562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx); 75708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (resolved_field != NULL && resolved_field->IsStatic()) { 7582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit); 7591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 7602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 7618cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 7621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 7631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 765c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 7661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 7671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 768e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 769e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 770e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 771e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 772e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 773e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 774e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. Don't change the field's class as that is 775e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // used to identify the SSB. 7764445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 7772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* dex_fields_class = 778e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers mUnit->class_linker_->ResolveType(dex_file, 779e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 780e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class); 781e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 782e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 783e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 784e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 7858cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 786e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 7871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 7881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 7894103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 7904103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 7912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_); 79200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (fields_class->GetDexCache() == dex_cache) { 7934103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 7944103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 7954103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 7964103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7974103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 798c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 7994103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 8004103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 801e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // Search dex file for localized ssb index, may fail if field's class is a parent 802e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // of the class mentioned in the dex file and there is no dex cache entry. 8031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 8041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 8054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindStringId(descriptor); 8061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 8071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 8084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id)); 809b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes if (type_id != NULL) { 8101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 8114dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id); 8121bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 8131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 814c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 8151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 8161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8181bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 8221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 82300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 82400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 8251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 826c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 8271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 8281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 8291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 8302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, 8312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method, 8322ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers uintptr_t& direct_code, uintptr_t& direct_method) { 833137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // For direct and static methods compute possible direct_code and direct_method values, ie 834137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // an address for the Method* being invoked and an address of the code for that Method*. 835137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // For interface calls compute a value for direct_method that is the interface method being 836137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // invoked, so this can be passed to the out-of-line runtime support code. 8372ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 8382ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 839c531cefbfb5394413122e9f57d211ba436cff012buzbee if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) { 840c531cefbfb5394413122e9f57d211ba436cff012buzbee if (sharp_type != kStatic && sharp_type != kDirect) { 841c531cefbfb5394413122e9f57d211ba436cff012buzbee return; 842c531cefbfb5394413122e9f57d211ba436cff012buzbee } 843c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 844c531cefbfb5394413122e9f57d211ba436cff012buzbee if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) { 845c531cefbfb5394413122e9f57d211ba436cff012buzbee return; 846c531cefbfb5394413122e9f57d211ba436cff012buzbee } 847b8404a7de94c109e3c17b4205b5f8aaae996eb33TDYa } 8482ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL; 8492ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (!method_code_in_boot) { 8502ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 8512ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 8522ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized(); 8532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (has_clinit_trampoline) { 8542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 8552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 856c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers if (sharp_type != kInterface) { // Interfaces always go via a trampoline. 857c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers stats_->DirectCallsToBoot(type); 858c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers } 8592ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->DirectMethodsToBoot(type); 8603fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 8613fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (compiling_boot) { 8620637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom const bool kSupportBootImageFixup = true; 8633fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (kSupportBootImageFixup) { 8643fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MethodHelper mh(method); 8653fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (IsImageClass(mh.GetDeclaringClassDescriptor())) { 8660637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // We can only branch directly to Methods that are resolved in the DexCache. 8670637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // Otherwise we won't invoke the resolution trampoline. 8683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = -1; 8690637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom direct_code = -1; 8703fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8713fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8723fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } else { 873b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method)->IsImageSpace()) { 8743fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = reinterpret_cast<uintptr_t>(method); 8753fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_code = reinterpret_cast<uintptr_t>(method->GetCode()); 8772ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 8782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers} 8792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 880fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type, 8812ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers int& vtable_idx, uintptr_t& direct_code, 8822ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers uintptr_t& direct_method) { 88300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 884a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 8852ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 8862ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 8872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* resolved_method = 88808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers ComputeMethodReferencedFromCompilingMethod(soa, mUnit, method_idx, type); 889a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 89008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Don't try to fast-path if we don't understand the caller's class or this appears to be an 89108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Incompatible Class Change Error. 8922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit); 89308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers bool icce = resolved_method->CheckIncompatibleClassChange(type); 89408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (referrer_class != NULL && !icce) { 8952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* methods_class = resolved_method->GetDeclaringClass(); 896a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 897a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 898996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 899a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 900a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 90108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // method public. Resort to the dex file to determine the correct class for the access 90208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // check. 9034445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 904a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers methods_class = 9054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_linker_->ResolveType(dex_file, 9064dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien dex_file.GetMethodId(method_idx).class_idx_, 9074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien referrer_class); 908a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 909a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 910137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers referrer_class->CanAccessMember(methods_class, resolved_method->GetAccessFlags())) { 911a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 912f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers const bool kEnableSharpening = true; 9132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Sharpen a virtual call into a direct call when the target is known. 9142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() || 91508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers methods_class->IsFinal()); 91608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Ensure the vtable index will be correct to dispatch in the vtable of the super class. 9174155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class && 91808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_class->IsSubClass(methods_class) && 91908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers vtable_idx < methods_class->GetVTable()->GetLength() && 92008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers methods_class->GetVTable()->Get(vtable_idx) == resolved_method); 9212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (kEnableSharpening && can_sharpen) { 9222ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->ResolvedMethod(type); 923fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 924fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 925fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method) 92608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers << PrettyMethod(resolved_method); 9272ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->VirtualMadeDirect(type); 9282ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method); 929fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers type = kDirect; 930fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 9312ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else if (type == kSuper) { 93208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Unsharpened super calls are suspicious so go slow-path. 9332ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else { 934c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 9352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method); 936a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 937a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 938a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 939a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 940a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 941a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Clean up any exception left by method/type resolution 94200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 94300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 944a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 945c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedMethod(type); 946a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 947a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 948a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 94900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::AddCodePatch(const DexFile* dex_file, 950f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 95108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType referrer_invoke_type, 952f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 95308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType target_invoke_type, 9543fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 95550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 95600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers code_to_patch_.push_back(new PatchInformation(dex_file, 957f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 95808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_invoke_type, 959f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 96008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers target_invoke_type, 961f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 9623fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 96300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::AddMethodPatch(const DexFile* dex_file, 964f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 96508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType referrer_invoke_type, 966f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 96708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType target_invoke_type, 9683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 96950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 97000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers methods_to_patch_.push_back(new PatchInformation(dex_file, 971f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 97208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_invoke_type, 973f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 97408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers target_invoke_type, 975f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 9763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 9773fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers 9780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass CompilationContext { 979731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public: 9800e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier typedef void Callback(const CompilationContext* context, size_t index); 9810e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier 9820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CompilationContext(ClassLinker* class_linker, 98300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader, 984731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* compiler, 9850e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const DexFile* dex_file, 9862f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool) 987731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom : class_linker_(class_linker), 988731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom class_loader_(class_loader), 989731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom compiler_(compiler), 9900e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier dex_file_(dex_file), 9912f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom thread_pool_(&thread_pool) {} 992731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 99300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* GetClassLinker() const { 994731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(class_linker_ != NULL); 995731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_linker_; 996731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 99700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 99800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject GetClassLoader() const { 999731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_loader_; 1000731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 100100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 100200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Compiler* GetCompiler() const { 1003731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(compiler_ != NULL); 1004731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return compiler_; 1005731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 100600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 100700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile* GetDexFile() const { 1008731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_file_ != NULL); 1009731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_file_; 1010731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 1011731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 10120e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) { 10130e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier Thread* self = Thread::Current(); 10140e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier self->AssertNoPendingException(); 10150e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CHECK_GT(work_units, 0U); 10169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 101702b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier std::vector<ForAllClosure*> closures(work_units); 10180e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier for (size_t i = 0; i < work_units; ++i) { 10190e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier closures[i] = new ForAllClosure(this, begin + i, end, callback, work_units); 10200e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->AddTask(self, closures[i]); 10210e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 10220e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->StartWorkers(self); 102300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 10240e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker 10250e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // thread destructor's called below perform join). 10260e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CHECK_NE(self->GetState(), kRunnable); 1027d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 10280e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Wait for all the worker threads to finish. 10290e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->Wait(self); 1030d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1031d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1032d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 1033d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 103402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier class ForAllClosure : public Task { 10350e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier public: 10360e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier ForAllClosure(CompilationContext* context, size_t begin, size_t end, Callback* callback, 10370e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier size_t stripe) 10380e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier : context_(context), 10390e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier begin_(begin), 10400e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier end_(end), 10410e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier callback_(callback), 10420e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier stripe_(stripe) 10430e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier { 10441e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 1045aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 10469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 10470e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier virtual void Run(Thread* self) { 10480e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier for (size_t i = begin_; i < end_; i += stripe_) { 10490e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier callback_(context_, i); 10500e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier self->AssertNoPendingException(); 10510e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 10520e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 105302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier 105402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier virtual void Finalize() { 105502b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier delete this; 105602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier } 10570e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier private: 10580e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CompilationContext* const context_; 10590e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t begin_; 10600e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t end_; 10610e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const Callback* callback_; 10620e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t stripe_; 10630e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier }; 10641e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 10650e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier ClassLinker* const class_linker_; 10660e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const jobject class_loader_; 10670e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier Compiler* const compiler_; 10680e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const DexFile* const dex_file_; 10690e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier ThreadPool* thread_pool_; 1070d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 1071d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 107200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Return true if the class should be skipped during compilation. We 107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// never skip classes in the boot class loader. However, if we have a 107400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// non-boot class loader and we can resolve the class in the boot 107500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// class loader, we do skip the class. This happens if an app bundles 107600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// classes found in the boot classpath. Since at runtime we will 107700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// select the class from the boot classpath, do not attempt to resolve 107800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// or compile it now. 10792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool SkipClass(mirror::ClassLoader* class_loader, 108000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile& dex_file, 108100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::ClassDef& class_def) 1082b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 108300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (class_loader == NULL) { 108400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return false; 108500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 108600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* descriptor = dex_file.GetClassDescriptor(class_def); 108700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 10882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker->FindClass(descriptor, NULL); 108900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (klass == NULL) { 109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 109100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK(self->IsExceptionPending()); 109200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->ClearException(); 109300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return false; 109400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 109500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return true; 109600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 109700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ResolveClassFieldsAndMethods(const CompilationContext* context, size_t class_def_index) 1099b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 110000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 11012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()); 1102731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile& dex_file = *context->GetDexFile(); 1103d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1104845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 1105845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 1106845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 1107845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 1108845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 1109845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 1110845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 1111d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 111200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (SkipClass(class_loader, dex_file, class_def)) { 1113d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1114d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1115845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 1116d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 1117d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 1118d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 1119d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 1120d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 1121d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 1122d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1123d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1124d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1125731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = context->GetClassLinker(); 11262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1127d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 1128d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 11292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 11302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers class_loader, true); 1131d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1132d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1133d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 11340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1135d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1136d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1137fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers // If an instance field is final then we need to have a barrier on the return, static final 1138fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers // fields are assigned within the lock held for class initialization. 1139fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers bool requires_constructor_barrier = false; 1140d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 1141fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers if ((it.GetMemberAccessFlags() & kAccFinal) != 0) { 1142fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers requires_constructor_barrier = true; 1143fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers } 1144fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 11452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 11462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers class_loader, false); 1147d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1148d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1149d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 115020cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1151d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1152d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1153fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers if (requires_constructor_barrier) { 1154fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers context->GetCompiler()->AddRequiresConstructorBarrier(soa.Self(), context->GetDexFile(), 1155fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_index); 1156fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers } 1157d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 11582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), 11592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers dex_cache, class_loader, NULL, 11602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers it.GetMethodInvokeType(class_def)); 1161d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1162d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1163d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1164845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1165d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1166d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1167d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 11682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), 11692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers dex_cache, class_loader, NULL, 11702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers it.GetMethodInvokeType(class_def)); 1171d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1172d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1173d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1174845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1175d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1176d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1177d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 1178d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1179d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 118000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ResolveType(const CompilationContext* context, size_t type_idx) 1181b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 1182d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 118300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 118400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* class_linker = context->GetClassLinker(); 118500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile& dex_file = *context->GetDexFile(); 11862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file); 11872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()); 11882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 118900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 1190d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 119100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK(soa.Self()->IsExceptionPending()); 1192d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1193d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1194d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1195d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 119600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::ResolveDexFile(jobject class_loader, const DexFile& dex_file, 11972f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 1198d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1199d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 120000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: we could resolve strings here, although the string table is largely filled with class 120100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // and method names. 1202d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12032f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompilationContext context(class_linker, class_loader, this, &dex_file, thread_pool); 12040e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_); 1205ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 1206d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12070e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 1208ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 12099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 12109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 12113d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files, 12122f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 1213ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1214ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 121598eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 12162f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom VerifyDexFile(class_loader, *dex_file, thread_pool, timings); 121798eacac683b78e60799323e8c7d59e7214808639jeffhao } 121898eacac683b78e60799323e8c7d59e7214808639jeffhao} 121998eacac683b78e60799323e8c7d59e7214808639jeffhao 122000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VerifyClass(const CompilationContext* context, size_t class_def_index) 1221b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 122200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1223731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 1224731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def); 12252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = 122600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers context->GetClassLinker()->FindClass(descriptor, 12272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers soa.Decode<mirror::ClassLoader*>(context->GetClassLoader())); 1228d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 1229d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1230d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1231d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1232f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao 1233f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao /* 1234f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * At compile time, we can still structurally verify the class even if FindClass fails. 1235f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * This is to ensure the class is structurally sound for compilation. An unsound class 1236f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * will be rejected by the verifier and later skipped during compilation in the compiler. 1237f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao */ 12382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = context->GetClassLinker()->FindDexCache(*context->GetDexFile()); 1239f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao std::string error_msg; 124000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (verifier::MethodVerifier::VerifyClass(context->GetDexFile(), 124100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_cache, 12422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()), 124300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_def_index, error_msg) == 124400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers verifier::MethodVerifier::kHardFailure) { 1245731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 1246f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao LOG(ERROR) << "Verification failed on class " 1247731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom << PrettyDescriptor(context->GetDexFile()->GetClassDescriptor(class_def)) 1248f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << " because: " << error_msg; 1249f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao } 1250d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1251d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1252d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 1253731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLinker()->VerifyClass(klass); 1254d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1255d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 1256d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 1257d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 1258d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1259d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1260d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12619ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous()) 12629ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers << PrettyDescriptor(klass) << ": state=" << klass->GetStatus(); 1263d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 1264d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1265d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12662f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstromvoid Compiler::VerifyDexFile(jobject class_loader, const DexFile& dex_file, 12672f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 1268731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 12692f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompilationContext context(class_linker, class_loader, this, &dex_file, thread_pool); 12700e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 12713d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("Verify " + dex_file.GetLocation()); 1272a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1273a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 127464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic const char* class_initializer_black_list[] = { 127564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/app/ActivityThread;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 127664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/bluetooth/BluetoothAudioGateway;", // Calls android.bluetooth.BluetoothAudioGateway.classInitNative(). 127764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/bluetooth/HeadsetBase;", // Calls android.bluetooth.HeadsetBase.classInitNative(). 127864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/res/CompatibilityInfo;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 127964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/res/CompatibilityInfo$1;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 128064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/UriMatcher;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/CursorWindow;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 128264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteConnection;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteConnection$Operation;", // Requires SimpleDateFormat -> java.util.Locale. 128464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteDatabaseConfiguration;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteDebug;", // Calls android.util.Log.isLoggable. 128664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteOpenHelper;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 128764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteQueryBuilder;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 128864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/drm/DrmManagerClient;", // Calls System.loadLibrary. 128964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/AnimatedRotateDrawable;", // Sub-class of Drawable. 129064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/AnimationDrawable;", // Sub-class of Drawable. 129164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/BitmapDrawable;", // Sub-class of Drawable. 129264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ClipDrawable;", // Sub-class of Drawable. 129364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ColorDrawable;", // Sub-class of Drawable. 129464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/Drawable;", // Requires android.graphics.Rect. 129564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/DrawableContainer;", // Sub-class of Drawable. 129664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/GradientDrawable;", // Sub-class of Drawable. 129764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/LayerDrawable;", // Sub-class of Drawable. 129864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/NinePatchDrawable;", // Sub-class of Drawable. 129964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/RotateDrawable;", // Sub-class of Drawable. 130064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ScaleDrawable;", // Sub-class of Drawable. 130164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ShapeDrawable;", // Sub-class of Drawable. 130264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/StateListDrawable;", // Sub-class of Drawable. 130364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/TransitionDrawable;", // Sub-class of Drawable. 130464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Matrix;", // Calls android.graphics.Matrix.native_create. 130564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Matrix$1;", // Requires Matrix. 130664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/PixelFormat;", // Calls android.graphics.PixelFormat.nativeClassInit(). 130764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Rect;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 130864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/SurfaceTexture;", // Calls android.graphics.SurfaceTexture.nativeClassInit(). 130964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Typeface;", // Calls android.graphics.Typeface.nativeCreate. 131064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/inputmethodservice/ExtractEditText;", // Requires android.widget.TextView. 131164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/CameraProfile;", // Calls System.loadLibrary. 131264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/DecoderCapabilities;", // Calls System.loadLibrary. 131364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaFile;", // Requires DecoderCapabilities. 131464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaPlayer;", // Calls System.loadLibrary. 131564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaRecorder;", // Calls System.loadLibrary. 131664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaScanner;", // Calls System.loadLibrary. 131764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/NetworkInfo;", // Calls java.util.EnumMap.<init> -> java.lang.Enum.getSharedConstants -> System.identityHashCode. 131864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Proxy;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 131964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/SSLCertificateSocketFactory;", // Requires javax.net.ssl.HttpsURLConnection. 132064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 132164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$AbstractHierarchicalUri;", // Requires Uri. 132264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$HierarchicalUri;", // Requires Uri. 132364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$OpaqueUri;", // Requires Uri. 132464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$StringUri;", // Requires Uri. 132564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/WebAddress;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 132664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/nfc/NdefRecord;", // Calls String.getBytes -> java.nio.charset.Charset. 132764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES10;", // Calls android.opengl.GLES10._nativeClassInit. 132864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES10Ext;", // Calls android.opengl.GLES10Ext._nativeClassInit. 132964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES11;", // Requires GLES10. 133064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES11Ext;", // Calls android.opengl.GLES11Ext._nativeClassInit. 133164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES20;", // Calls android.opengl.GLES20._nativeClassInit. 133264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLUtils;", // Calls android.opengl.GLUtils.nativeClassInit. 133364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Build;", // Calls -..-> android.os.SystemProperties.native_get. 133464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Build$VERSION;", // Requires Build. 133564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Debug;", // Requires android.os.Environment. 133664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Environment;", // Calls System.getenv. 133764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/FileUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 133864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/StrictMode;", // Calls android.util.Log.isLoggable. 133964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/StrictMode$VmPolicy;", // Requires StrictMode. 134064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Trace;", // Calls android.os.Trace.nativeGetEnabledTags. 134164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/UEventObserver;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 134264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/provider/Settings$Secure;", // Requires android.net.Uri. 134364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/provider/Settings$System;", // Requires android.net.Uri. 134464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/renderscript/RenderScript;", // Calls System.loadLibrary. 134564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/server/BluetoothService;", // Calls android.server.BluetoothService.classInitNative. 134664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/server/BluetoothEventLoop;", // Calls android.server.BluetoothEventLoop.classInitNative. 134764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/telephony/PhoneNumberUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 134864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/AutoText;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 134964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/Layout;", // Calls com.android.internal.util.ArrayUtils.emptyArray -> System.identityHashCode. 135064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/BoringLayout;", // Requires Layout. 135164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/DynamicLayout;", // Requires Layout. 135264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/Html$HtmlParser;", // Calls -..-> String.toLowerCase -> java.util.Locale. 135364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/StaticLayout;", // Requires Layout. 135464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/TextUtils;", // Requires android.util.DisplayMetrics. 135564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/util/DisplayMetrics;", // Calls SystemProperties.native_get_int. 135664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/util/Patterns;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 135764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/animation/Animation;", // Calls SystemProperties.native_get_boolean. 135864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/animation/AlphaAnimation;", // Requires Animation. 135964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/Choreographer;", // Calls SystemProperties.native_get_boolean. 136064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/GLES20Canvas;", // Calls android.view.GLES20Canvas.nIsAvailable. 136164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/GLES20RecordingCanvas;", // Requires android.view.GLES20Canvas. 136264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/HardwareRenderer$GlRenderer;", // Requires SystemProperties.native_get. 136364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/HardwareRenderer$Gl20Renderer;", // Requires SystemProperties.native_get. 136464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/InputEventConsistencyVerifier;", // Requires android.os.Build. 136564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/Surface;", // Requires SystemProperties.native_get. 136664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/webkit/JniUtil;", // Calls System.loadLibrary. 136764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/webkit/WebViewCore;", // Calls System.loadLibrary. 136864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/AutoCompleteTextView;", // Requires TextView. 136964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/Button;", // Requires TextView. 137064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CheckBox;", // Requires TextView. 137164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CheckedTextView;", // Requires TextView. 137264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CompoundButton;", // Requires TextView. 137364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/EditText;", // Requires TextView. 137464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/NumberPicker;", // Requires java.util.Locale. 137564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/ScrollBarDrawable;", // Sub-class of Drawable. 137664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/SearchView$SearchAutoComplete;", // Requires TextView. 137764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/Switch;", // Requires TextView. 137864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/TextView;", // Calls Paint.<init> -> Paint.native_init. 137964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 138064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/i18n/phonenumbers/PhoneNumberUtil;", // Requires java.util.logging.LogManager. 138164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/os/SamplingProfilerIntegration;", // Calls SystemProperties.native_get_int. 138264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/policy/impl/PhoneWindow;", // Calls android.os.Binder.init. 138364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/view/menu/ActionMenuItemView;", // Requires TextView. 138464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/widget/DialogTitle;", // Requires TextView. 138564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/asn1/StreamUtil;", // Calls Runtime.getRuntime().maxMemory(). 138664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 138764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/crypto/engines/RSABlindedEngine;", // Calls native ... -> java.math.NativeBN.BN_new(). 138864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/jce/provider/CertBlacklist;", // Calls System.getenv -> OsConstants.initConstants. 138964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi;", // Calls System.getenv -> OsConstants.initConstants. 139064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/EGLContextImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit. 139164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/EGLImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit. 139264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/GLImpl;", // Calls com.google.android.gles_jni.GLImpl._nativeClassInit. 139364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/Console;", // Has FileDescriptor(s). 139464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/File;", // Calls to Random.<init> -> System.currentTimeMillis -> OsConstants.initConstants. 139564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/FileDescriptor;", // Requires libcore.io.OsConstants. 139664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectInputStream;", // Requires java.lang.ClassLoader$SystemClassLoader. 139764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectStreamClass;", // Calls to Class.forName -> java.io.FileDescriptor. 139864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectStreamConstants;", // Instance of non-image class SerializablePermission. 139964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/ClassLoader$SystemClassLoader;", // Calls System.getProperty -> OsConstants.initConstants. 140064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/Runtime;", // Calls System.getProperty -> OsConstants.initConstants. 140164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/System;", // Calls OsConstants.initConstants. 140264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/BigDecimal;", // Calls native ... -> java.math.NativeBN.BN_new(). 140364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/BigInteger;", // Calls native ... -> java.math.NativeBN.BN_new(). 140464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/Multiplication;", // Calls native ... -> java.math.NativeBN.BN_new(). 140564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/InetAddress;", // Requires libcore.io.OsConstants. 140664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/Inet4Address;", // Sub-class of InetAddress. 140764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/Inet6Address;", // Sub-class of InetAddress. 140864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/Charset;", // Calls Charset.getDefaultCharset -> System.getProperty -> OsConstants.initConstants. 140964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/CharsetICU;", // Sub-class of Charset. 141064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/Charsets;", // Calls Charset.forName. 141164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/security/Security;", // Tries to do disk IO for "security.properties". 141264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/Date;", // Calls Date.<init> -> System.currentTimeMillis -> OsConstants.initConstants. 141364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/Locale;", // Calls System.getProperty -> OsConstants.initConstants. 141464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/SimpleTimeZone;", // Sub-class of TimeZone. 141564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/TimeZone;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 141664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/concurrent/ConcurrentHashMap$Segment;", // Calls Runtime.getRuntime().availableProcessors(). 141764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/logging/LogManager;", // Calls System.getProperty -> OsConstants.initConstants. 141864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/microedition/khronos/egl/EGL10;", // Requires EGLContext. 141964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/microedition/khronos/egl/EGLContext;", // Requires com.google.android.gles_jni.EGLImpl. 142064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/net/ssl/HttpsURLConnection;", // Calls SSLSocketFactory.getDefault -> java.security.Security.getProperty. 142164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/icu/LocaleData;", // Requires java.util.Locale. 142264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/icu/TimeZones;", // Requires java.util.TimeZone. 142364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/io/OsConstants;", // Platform specific. 142464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/net/MimeUtils;", // Calls libcore.net.MimeUtils.getContentTypesPropertiesStream -> System.getProperty. 142564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/util/ZoneInfo;", // Sub-class of TimeZone. 142664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/util/ZoneInfoDB;", // Calls System.getenv -> OsConstants.initConstants. 142764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/commons/logging/LogFactory;", // Calls System.getProperty. 142864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/fortress/Services;", // Calls ClassLoader.getSystemClassLoader -> System.getProperty. 142964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/provider/cert/X509CertFactoryImpl;", // Requires java.nio.charsets.Charsets. 143064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/provider/crypto/RandomBitsSupplier;", // Requires java.io.File. 143164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/utils/AlgNameMapper;", // Requires java.util.Locale. 143264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/AttributeTypeAndValue;", // Calls IntegralToString.convertInt -> Thread.currentThread. 143364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/DirectoryString;", // Requires BigInteger. 143464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/Name;", // Requires org.apache.harmony.security.x501.AttributeTypeAndValue. 143564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Certificate;", // Requires org.apache.harmony.security.x509.TBSCertificate. 143664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/TBSCertificate;", // Requires org.apache.harmony.security.x501.Name. 143764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/EDIPartyName;", // Calls native ... -> java.math.NativeBN.BN_new(). 143864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/GeneralName;", // Requires org.apache.harmony.security.x501.Name. 143964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/GeneralNames;", // Requires GeneralName. 144064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Time;", // Calls native ... -> java.math.NativeBN.BN_new(). 144164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Validity;", // Requires x509.Time. 144264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xml/ExpatParser;", // Calls native ExpatParser.staticInitialize. 144364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto;", // Calls native NativeCrypto.clinit(). 144464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$MD5;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 144564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 144664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA512;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto. 144764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xnet/provider/jsse/TrustedCertificateStore;", // Calls System.getenv -> OsConstants.initConstants. 144864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/params/ConnRouteParams;", // Requires java.util.Locale. 144964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/ssl/SSLSocketFactory;", // Calls java.security.Security.getProperty. 145064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/util/InetAddressUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 145164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers}; 145264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 145364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic void InitializeClass(const CompilationContext* context, size_t class_def_index) 14543d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 14553d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 145600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 14572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()); 14583d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def); 14592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = context->GetClassLinker()->FindClass(descriptor, class_loader); 14601f5393447b9f45be7918042d9ee7b521376de866Ian Rogers Thread* self = Thread::Current(); 146164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 146264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool can_init_static_fields = compiling_boot && 146364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers context->GetCompiler()->IsImageClass(descriptor); 14643d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass != NULL) { 146564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't want class initialization occurring on multiple threads due to deadlock problems. 146664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // For example, a parent class is initialized (holding its lock) that refers to a sub-class 146764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // in its static/class initializer causing it to try to acquire the sub-class' lock. While 146864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // on a second thread the sub-class is initialized (holding its lock) after first initializing 146964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent 147064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // lock ordering and consequent potential deadlock. 147164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers static Mutex lock1("Initializer lock", kMonitorLock); 147264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers MutexLock mu(self, lock1); 147364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // The lock required to initialize the class. 147464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ObjectLock lock2(self, klass); 147564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Only try to initialize classes that were successfully verified. 14763d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass->IsVerified()) { 14773d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers context->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields); 147864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!klass->IsInitialized()) { 147964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (can_init_static_fields) { 148064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool is_black_listed = false; 148164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) { 148264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (StringPiece(descriptor) == class_initializer_black_list[i]) { 148364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers is_black_listed = true; 148464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers break; 148564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 148664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 148764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!is_black_listed) { 148864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(INFO) << "Initializing: " << descriptor; 148964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (StringPiece(descriptor) == "Ljava/lang/Void;"){ 149064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime. 14912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields(); 149264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK_EQ(fields->GetLength(), 1); 149364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fields->Get(0)->SetObj(klass, context->GetClassLinker()->FindPrimitiveClass('V')); 14942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass->SetStatus(mirror::Class::kStatusInitialized); 149564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 149664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers context->GetClassLinker()->EnsureInitialized(klass, true, can_init_static_fields); 149764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 149864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(!self->IsExceptionPending()) << self->GetException()->Dump(); 149964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 150064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 150164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 15023d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers // If successfully initialized place in SSB array. 15033d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass->IsInitialized()) { 15043d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers klass->GetDexCache()->GetInitializedStaticStorage()->Set(klass->GetDexTypeIndex(), klass); 15050755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 150627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 15073d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers // Record the final class status if necessary. 15082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class::Status status = klass->GetStatus(); 15093d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers Compiler::ClassReference ref(context->GetDexFile(), class_def_index); 15103d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers CompiledClass* compiled_class = context->GetCompiler()->GetCompiledClass(ref); 15113d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (compiled_class == NULL) { 15123d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers compiled_class = new CompiledClass(status); 15133d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers context->GetCompiler()->RecordClassStatus(ref, compiled_class); 15143d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers } else { 15153d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers DCHECK_EQ(status, compiled_class->GetStatus()); 1516ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 151798eacac683b78e60799323e8c7d59e7214808639jeffhao } 15181f5393447b9f45be7918042d9ee7b521376de866Ian Rogers // Clear any class not found or verification exceptions. 15191f5393447b9f45be7918042d9ee7b521376de866Ian Rogers self->ClearException(); 152098eacac683b78e60799323e8c7d59e7214808639jeffhao} 152198eacac683b78e60799323e8c7d59e7214808639jeffhao 152264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersvoid Compiler::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file, 15232f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 152464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#ifndef NDEBUG 152564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) { 152664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers const char* descriptor = class_initializer_black_list[i]; 152764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(IsValidDescriptor(descriptor)) << descriptor; 152864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 152964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#endif 15303d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 15312f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompilationContext context(class_linker, jni_class_loader, this, &dex_file, thread_pool); 153264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count_); 15333d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("InitializeNoClinit " + dex_file.GetLocation()); 15343d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers} 153590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 153664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersvoid Compiler::InitializeClasses(jobject class_loader, 153764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers const std::vector<const DexFile*>& dex_files, 15382f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 15393d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers for (size_t i = 0; i != dex_files.size(); ++i) { 15403d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers const DexFile* dex_file = dex_files[i]; 154190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(dex_file != NULL); 15422f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom InitializeClasses(class_loader, *dex_file, thread_pool, timings); 154300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 154490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao} 154590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 15463d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 15472f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 1548ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1549ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 155083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 15512f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompileDexFile(class_loader, *dex_file, thread_pool, timings); 155283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 155383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 155483db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 155500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::CompileClass(const CompilationContext* context, size_t class_def_index) { 155600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader = context->GetClassLoader(); 1557731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile& dex_file = *context->GetDexFile(); 1558c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 155900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 156000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 15612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()); 156200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (SkipClass(class_loader, dex_file, class_def)) { 156300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 156400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 15655ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 1566d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 1567d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 1568776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (verifier::MethodVerifier::IsClassRejected(ref)) { 1569d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 1570d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 15710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 15720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 15730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 15740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 15750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 15760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 15770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 15780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 15790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 15800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 15810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 15820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 15830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 15840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 158568adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom int64_t previous_direct_method_idx = -1; 15860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 15876f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 15886f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom if (method_idx == previous_direct_method_idx) { 15896f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // smali can create dex files with two encoded_methods sharing the same method_idx 15906f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // http://code.google.com/p/smali/issues/detail?id=119 15916f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom it.Next(); 15926f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom continue; 15936f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom } 15946f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom previous_direct_method_idx = method_idx; 1595731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1596fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers it.GetMethodInvokeType(class_def), class_def_index, 1597fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 15980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 15999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 16000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 160168adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom int64_t previous_virtual_method_idx = -1; 16020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 16036f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 16046f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom if (method_idx == previous_virtual_method_idx) { 16056f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // smali can create dex files with two encoded_methods sharing the same method_idx 16066f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // http://code.google.com/p/smali/issues/detail?id=119 16076f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom it.Next(); 16086f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom continue; 16096f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom } 16106f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom previous_virtual_method_idx = method_idx; 1611731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1612fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers it.GetMethodInvokeType(class_def), class_def_index, 1613fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 16140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 16159ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 16160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 16179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 16189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 16193d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::CompileDexFile(jobject class_loader, const DexFile& dex_file, 16202f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 16212f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompilationContext context(NULL, class_loader, this, &dex_file, thread_pool); 16220e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_); 16233d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("Compile " + dex_file.GetLocation()); 1624c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1625c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 1626a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 1627a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes std::string key(shorty); 1628a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes if (is_static) { 1629a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes key += "$"; // Must not be a shorty type character. 1630a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 1631a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes return key; 1632a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes} 1633a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes 1634a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 1635fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers InvokeType invoke_type, uint32_t class_def_idx, uint32_t method_idx, 1636fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers jobject class_loader, const DexFile& dex_file) { 1637f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1638bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 16394dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1640169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 164157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file); 16423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1643169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 16442cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 1645fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx, 1646fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 1647bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1648bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 16493bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 16505354ec568ace1e117d5a93dcb802a612356200edIan Rogers#ifdef ART_USE_LLVM_COMPILER 16515354ec568ace1e117d5a93dcb802a612356200edIan Rogers const uint64_t kWarnMilliSeconds = 1000; 16525354ec568ace1e117d5a93dcb802a612356200edIan Rogers#else 16535354ec568ace1e117d5a93dcb802a612356200edIan Rogers const uint64_t kWarnMilliSeconds = 100; 16545354ec568ace1e117d5a93dcb802a612356200edIan Rogers#endif 16555354ec568ace1e117d5a93dcb802a612356200edIan Rogers if (duration_ns > MsToNs(kWarnMilliSeconds)) { 1656bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 16573bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1658f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1659f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 166050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 1661f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 16620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 16630755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 166400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 166550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 166600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers compiled_methods_.Put(ref, compiled_method); 166700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 16680755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 16692cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 16709baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 167145619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers uint32_t shorty_len; 167245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); 1673169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 1674a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 1675a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key); 16760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 1677c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len); 16780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 1679a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes InsertInvokeStub(key, compiled_invoke_stub); 16803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 16817a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 1682c531cefbfb5394413122e9f57d211ba436cff012buzbee if (((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) && !is_static) { 16837a2a23a44d27f769718e28327af671f4e486c49aLogan Chien const CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty); 16847a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (compiled_proxy_stub == NULL) { 16857a2a23a44d27f769718e28327af671f4e486c49aLogan Chien compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len); 16867a2a23a44d27f769718e28327af671f4e486c49aLogan Chien CHECK(compiled_proxy_stub != NULL); 16877a2a23a44d27f769718e28327af671f4e486c49aLogan Chien InsertProxyStub(shorty, compiled_proxy_stub); 16887a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 16897a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 16907a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 169150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (self->IsExceptionPending()) { 169250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ScopedObjectAccess soa(self); 169300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n" 169450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers << self->GetException()->Dump(); 169500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 16960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 169728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 1698a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const { 1699a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 1700a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes return FindInvokeStub(key); 17013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 17023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1703a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(const std::string& key) const { 170450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_); 17050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 17060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 17073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 17080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 17090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 17100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 17113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 17123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 17133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1714a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesvoid Compiler::InsertInvokeStub(const std::string& key, 17150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub) { 171650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_); 1717a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key); 1718a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes if (it != compiled_invoke_stubs_.end()) { 1719a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes // Someone else won the race. 1720a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes delete compiled_invoke_stub; 1721a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } else { 1722a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes compiled_invoke_stubs_.Put(key, compiled_invoke_stub); 1723a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 17240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 17250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 17267a2a23a44d27f769718e28327af671f4e486c49aLogan Chienconst CompiledInvokeStub* Compiler::FindProxyStub(const char* shorty) const { 172750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_); 17287a2a23a44d27f769718e28327af671f4e486c49aLogan Chien ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty); 17297a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (it == compiled_proxy_stubs_.end()) { 17307a2a23a44d27f769718e28327af671f4e486c49aLogan Chien return NULL; 17317a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } else { 17327a2a23a44d27f769718e28327af671f4e486c49aLogan Chien DCHECK(it->second != NULL); 17337a2a23a44d27f769718e28327af671f4e486c49aLogan Chien return it->second; 17347a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 17357a2a23a44d27f769718e28327af671f4e486c49aLogan Chien} 17367a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 17377a2a23a44d27f769718e28327af671f4e486c49aLogan Chienvoid Compiler::InsertProxyStub(const char* shorty, 17387a2a23a44d27f769718e28327af671f4e486c49aLogan Chien const CompiledInvokeStub* compiled_proxy_stub) { 173950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_); 17407a2a23a44d27f769718e28327af671f4e486c49aLogan Chien InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty); 17417a2a23a44d27f769718e28327af671f4e486c49aLogan Chien if (it != compiled_proxy_stubs_.end()) { 17427a2a23a44d27f769718e28327af671f4e486c49aLogan Chien // Someone else won the race. 17437a2a23a44d27f769718e28327af671f4e486c49aLogan Chien delete compiled_proxy_stub; 17447a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } else { 17457a2a23a44d27f769718e28327af671f4e486c49aLogan Chien compiled_proxy_stubs_.Put(shorty, compiled_proxy_stub); 17467a2a23a44d27f769718e28327af671f4e486c49aLogan Chien } 17477a2a23a44d27f769718e28327af671f4e486c49aLogan Chien} 17487a2a23a44d27f769718e28327af671f4e486c49aLogan Chien 17490755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const { 175050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_classes_lock_); 17510755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 17520755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 17530755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 17540755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 17550755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 17560755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 17570755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 17580755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 17590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const { 176050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 17610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 17620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 17633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 17642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 17653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 17663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 17679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 17689ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 17698b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) { 1770106b2a03be66748a25b9019e4c222cee498d559fLogan Chien typedef void (*SetBitcodeFileNameFn)(Compiler&, std::string const&); 1771106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1772106b2a03be66748a25b9019e4c222cee498d559fLogan Chien SetBitcodeFileNameFn set_bitcode_file_name = 17738c4bbb55d0d801e492d849ee636771c8b2840429buzbee FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, 1774106b2a03be66748a25b9019e4c222cee498d559fLogan Chien "compilerLLVMSetBitcodeFileName"); 1775106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1776106b2a03be66748a25b9019e4c222cee498d559fLogan Chien set_bitcode_file_name(*this, filename); 17778b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 1778f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 1779fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 1780fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogersvoid Compiler::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1781fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers size_t class_def_index) { 1782fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MutexLock mu(self, freezing_constructor_lock_); 1783fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index)); 1784fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers} 1785fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 1786fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogersbool Compiler::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1787fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers size_t class_def_index) { 1788fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MutexLock mu(self, freezing_constructor_lock_); 1789fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0; 1790fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers} 1791fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 1792700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrombool Compiler::WriteElf(std::vector<uint8_t>& oat_contents, File* file) { 1793700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*WriteElfFn)(Compiler&, std::vector<uint8_t>&, File*); 1794700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom WriteElfFn WriteElf = 1795700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf"); 1796700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return WriteElf(*this, oat_contents, file); 1797700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1798700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1799700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrombool Compiler::FixupElf(File* file, uintptr_t oat_data_begin) const { 1800700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*FixupElfFn)(File*, uintptr_t oat_data_begin); 1801700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FixupElfFn FixupElf = 1802700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<FixupElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "FixupElf"); 1803700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return FixupElf(file, oat_data_begin); 1804700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1805700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1806700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromvoid Compiler::GetOatElfInformation(File* file, 1807700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom size_t& oat_loaded_size, 1808700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom size_t& oat_data_offset) const { 1809700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*GetOatElfInformationFn)(File*, size_t& oat_loaded_size, size_t& oat_data_offset); 1810700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom GetOatElfInformationFn GetOatElfInformation = 1811700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<GetOatElfInformationFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, 1812700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom "GetOatElfInformation"); 1813700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom GetOatElfInformation(file, oat_loaded_size, oat_data_offset); 1814700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1815700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1816700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromvoid Compiler::InstructionSetToLLVMTarget(InstructionSet instruction_set, 1817700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom std::string& target_triple, 1818700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom std::string& target_cpu, 1819700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom std::string& target_attr) { 1820700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom switch (instruction_set) { 1821700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kThumb2: 1822700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "thumb-none-linux-gnueabi"; 1823700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_cpu = "cortex-a9"; 1824700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db"; 1825700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1826700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1827700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kArm: 1828700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "armv7-none-linux-gnueabi"; 1829700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // TODO: Fix for Nexus S. 1830700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_cpu = "cortex-a9"; 1831700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // TODO: Fix for Xoom. 1832700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "+v7,+neon,+neonfp,+vfp3,+db"; 1833700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1834700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1835700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kX86: 1836700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "i386-pc-linux-gnu"; 1837700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = ""; 1838700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1839700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1840700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kMips: 1841700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "mipsel-unknown-linux"; 1842700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "mips32r2"; 1843700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1844700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1845700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom default: 1846700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom LOG(FATAL) << "Unknown instruction set: " << instruction_set; 1847700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 1848700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 18499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1850