compiler_driver.cc revision 39ebcb800aabedd0ffa6aa4aeac8aa4194c66e61
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 171212a022fa5f8ef9585d765b1809521812af882cIan Rogers#include "compiler_driver.h" 189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 19d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <vector> 20d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 21b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include <dlfcn.h> 22d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <unistd.h> 2327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 241aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 25a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal#include "base/timing_logger.h" 269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 2789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers#include "dex_compilation_unit.h" 284f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 299baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 321f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "gc/card_table-inl.h" 347469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h" 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 3739ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers#include "mirror/dex_cache-inl.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h" 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h" 4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 4400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h" 4550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#include "thread.h" 460e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier#include "thread_pool.h" 47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/method_verifier.h" 489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 49059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 50059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#include <mach-o/dyld.h> 51059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 52059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 55996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic double Percentage(size_t x, size_t y) { 56398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y)); 57996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 58996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 59996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic void DumpStat(size_t x, size_t y, const char* str) { 60996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (x == 0 && y == 0) { 61996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return; 62996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 63996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases"; 64996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 65996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 66c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersclass AOTCompilationStats { 67c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers public: 68ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers AOTCompilationStats() 69ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers : stats_lock_("AOT compilation statistics lock"), 70ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers types_in_dex_cache_(0), types_not_in_dex_cache_(0), 71ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers strings_in_dex_cache_(0), strings_not_in_dex_cache_(0), 72ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers resolved_types_(0), unresolved_types_(0), 73ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers resolved_instance_fields_(0), unresolved_instance_fields_(0), 7402c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0), 7502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal type_based_devirtualization_(0) { 762ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 77c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[i] = 0; 78c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[i] = 0; 792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[i] = 0; 802ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[i] = 0; 812ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[i] = 0; 82b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes } 83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void Dump() { 86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache"); 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache"); 88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_types_, unresolved_types_, "types resolved"); 89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); 90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, 91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields resolved"); 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_, 93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields local to a class"); 9402c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal DumpStat(type_based_devirtualization_,virtual_made_direct_[kInterface] + virtual_made_direct_[kVirtual] 9502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal - type_based_devirtualization_, "sharpened calls based on type information"); 96c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 98c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers std::ostringstream oss; 992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss << static_cast<InvokeType>(i) << " methods were AOT resolved"; 100c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str()); 1012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (virtual_made_direct_[i] > 0) { 1022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " methods made direct"; 1042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(virtual_made_direct_[i], 1052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i], 1062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_calls_to_boot_[i] > 0) { 1092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot"; 1112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_calls_to_boot_[i], 1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i], 1132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_methods_to_boot_[i] > 0) { 1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot"; 1182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_methods_to_boot_[i], 1192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i], 1202ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 122c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 123c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 124996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 12550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers// Allow lossy statistics in non-debug builds. 126996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG 12750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_) 128996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else 129996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() 130996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif 131996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 132c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeInDexCache() { 133c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_++; 135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 136996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 137c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNotInDexCache() { 138c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_not_in_dex_cache_++; 140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 141996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 142c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringInDexCache() { 143c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_++; 145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 146996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 147c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringNotInDexCache() { 148c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_not_in_dex_cache_++; 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 151996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 152c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeDoesntNeedAccessCheck() { 153c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_++; 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 156996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 157c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNeedsAccessCheck() { 158c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_types_++; 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 161996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 162c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedInstanceField() { 163c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_++; 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 166996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 167b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes void UnresolvedInstanceField() { 168c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_instance_fields_++; 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 171996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 172c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedLocalStaticField() { 173c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_local_static_fields_++; 175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 176996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 177c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedStaticField() { 178c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_static_fields_++; 180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 181996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 182c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedStaticField() { 183c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_static_fields_++; 185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 186996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 187e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Indicate that type information from the verifier led to devirtualization. 18802c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal void PreciseTypeDevirtualization() { 18902c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal STATS_LOCK(); 19002c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal type_based_devirtualization_++; 19102c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal } 192e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers 193e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Indicate that a method of the given type was resolved at compile time. 194c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedMethod(InvokeType type) { 195c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 196c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 197c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[type]++; 198996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 199996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 200e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Indicate that a method of the given type was unresolved at compile time as it was in an 201e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // unknown dex file. 202c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedMethod(InvokeType type) { 203c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 204c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 205c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[type]++; 206996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 207c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 208e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Indicate that a type of virtual method dispatch has been converted into a direct method 209e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // dispatch. 2102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void VirtualMadeDirect(InvokeType type) { 211e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers DCHECK(type == kVirtual || type == kInterface || type == kSuper); 2122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 2132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[type]++; 2142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 216e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Indicate that a method of the given type was able to call directly into boot. 2172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectCallsToBoot(InvokeType type) { 2182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 2192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 2202ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[type]++; 2212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2222ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 223e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Indicate that a method of the given type was able to be resolved directly from boot. 2242ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectMethodsToBoot(InvokeType type) { 2252ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 226fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers STATS_LOCK(); 2272ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[type]++; 228fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } 2292ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private: 231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Mutex stats_lock_; 232c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_in_dex_cache_; 234c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_not_in_dex_cache_; 235c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 236c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_in_dex_cache_; 237c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_not_in_dex_cache_; 238c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 239c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_types_; 240c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_types_; 241c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 242c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_instance_fields_; 243c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_instance_fields_; 244c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 245c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_local_static_fields_; 246c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_static_fields_; 247c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_static_fields_; 24802c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal // Type based devirtualization for invoke interface and virtual. 24902c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal size_t type_based_devirtualization_; 250c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 251c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_methods_[kMaxInvokeType + 1]; 252c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_methods_[kMaxInvokeType + 1]; 2532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t virtual_made_direct_[kMaxInvokeType + 1]; 2542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_calls_to_boot_[kMaxInvokeType + 1]; 2552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_methods_to_boot_[kMaxInvokeType + 1]; 256c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 257b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats); 258c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}; 259996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 2608c4bbb55d0d801e492d849ee636771c8b2840429buzbeestatic std::string MakeCompilerSoName(CompilerBackend compiler_backend) { 261059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 262059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Bad things happen if we pull in the libartd-compiler to a libart dex2oat or vice versa, 263059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // because we end up with both libart and libartd in the same address space! 26467d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes const char* suffix = (kIsDebugBuild ? "d" : ""); 265059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Work out the filename for the compiler library. 26700bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom std::string library_name(StringPrintf("art%s-compiler", suffix)); 268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str())); 269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find 272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the 273059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // same work. 274059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes uint32_t executable_path_length = 0; 275448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes _NSGetExecutablePath(NULL, &executable_path_length); 276448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes std::string path(executable_path_length, static_cast<char>(0)); 277448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0); 278059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 279059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/dex2oat". 280059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes size_t last_slash = path.find_last_of('/'); 281059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes CHECK_NE(last_slash, std::string::npos) << path; 282059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 283059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 284059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/bin". 285059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes last_slash = path.find_last_of('/'); 286059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 287059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 288059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes filename = path + "/lib/" + filename; 289059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 290059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes return filename; 291b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 292b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 29346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn> 29446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) { 29546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes Fn fn = reinterpret_cast<Fn>(dlsym(library, name)); 29646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes if (fn == NULL) { 29746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror(); 29846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes } 299059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn); 30046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes return fn; 30146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes} 30246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes 3031212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set, 3048447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum bool image, size_t thread_count, bool support_debugging, 305bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom const std::set<std::string>* image_classes, 306c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum bool dump_stats, bool dump_timings) 307c531cefbfb5394413122e9f57d211ba436cff012buzbee : compiler_backend_(compiler_backend), 308c531cefbfb5394413122e9f57d211ba436cff012buzbee instruction_set_(instruction_set), 309fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers freezing_constructor_lock_("freezing constructor lock"), 310c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 311c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 312aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 3135523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 314de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 31500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers start_ns_(0), 316c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 317ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_stats_(dump_stats), 318ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_timings_(dump_timings), 319b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes image_classes_(image_classes), 320b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_(NULL), 32146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes compiler_(NULL), 3226f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes compiler_context_(NULL), 32346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_(NULL), 324e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers compiler_enable_auto_elf_loading_(NULL), 32574180cad94848107cf297d37e72437c5a6eecf1bJeff Hao compiler_get_method_code_addr_(NULL) 326971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien{ 3278c4bbb55d0d801e492d849ee636771c8b2840429buzbee std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); 328b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY); 329b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ == NULL) { 330b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror(); 331b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 332b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_; 333b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 3344df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key"); 3354df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee 336c531cefbfb5394413122e9f57d211ba436cff012buzbee // TODO: more work needed to combine initializations and allow per-method backend selection 3371212a022fa5f8ef9585d765b1809521812af882cIan Rogers typedef void (*InitCompilerContextFn)(CompilerDriver&); 338c531cefbfb5394413122e9f57d211ba436cff012buzbee InitCompilerContextFn init_compiler_context; 339c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable){ 340c531cefbfb5394413122e9f57d211ba436cff012buzbee // Initialize compiler_context_ 3411212a022fa5f8ef9585d765b1809521812af882cIan Rogers init_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 342c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtInitCompilerContext"); 343c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod"); 344c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 3451212a022fa5f8ef9585d765b1809521812af882cIan Rogers init_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 346c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtInitQuickCompilerContext"); 347c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtQuickCompileMethod"); 348c531cefbfb5394413122e9f57d211ba436cff012buzbee } 349692be80cb2278ae585a776a163bc4b3ef60cae88buzbee 350692be80cb2278ae585a776a163bc4b3ef60cae88buzbee init_compiler_context(*this); 351106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 352c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 35300bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtLLVMJniCompileMethod"); 35400bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom } else { 35500bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtQuickJniCompileMethod"); 35600bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom } 35700bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom 35825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 359ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 360ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 361ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 362c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 363c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 3641212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerDriver::~CompilerDriver() { 36550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 366c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 36750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_classes_lock_); 368c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 369c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 370c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 37150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 372c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 373c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 374c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 37550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 376f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&code_to_patch_); 377f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 378f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 37950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 380f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&methods_to_patch_); 381f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 382ed6d5ed3494648780b9e91422c90d6bc22c16b79Mathieu Chartier CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key"); 3831212a022fa5f8ef9585d765b1809521812af882cIan Rogers typedef void (*UninitCompilerContextFn)(CompilerDriver&); 3848c4bbb55d0d801e492d849ee636771c8b2840429buzbee std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); 385c531cefbfb5394413122e9f57d211ba436cff012buzbee UninitCompilerContextFn uninit_compiler_context; 386692be80cb2278ae585a776a163bc4b3ef60cae88buzbee // Uninitialize compiler_context_ 387c531cefbfb5394413122e9f57d211ba436cff012buzbee // TODO: rework to combine initialization/uninitialization 388c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 3891212a022fa5f8ef9585d765b1809521812af882cIan Rogers uninit_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 390c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtUnInitCompilerContext"); 391c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 3921212a022fa5f8ef9585d765b1809521812af882cIan Rogers uninit_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name, 393c531cefbfb5394413122e9f57d211ba436cff012buzbee compiler_library_, "ArtUnInitQuickCompilerContext"); 394c531cefbfb5394413122e9f57d211ba436cff012buzbee } 395692be80cb2278ae585a776a163bc4b3ef60cae88buzbee uninit_compiler_context(*this); 39622c0569fe6816086acdef90798622a6d6e209532Brian Carlstrom#if 0 397b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ != NULL) { 398b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlclose(" << compiler_library_ << ")"; 399ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee /* 400ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * FIXME: Temporary workaround 401ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * Apparently, llvm is adding dctors to atexit, but if we unload 402ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * the library here the code will no longer be around at exit time 403ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * and we die a flaming death in __cxa_finalize(). Apparently, some 404ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * dlclose() implementations will scan the atexit list on unload and 405ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * handle any associated with the soon-to-be-unloaded library. 406ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * However, this is not required by POSIX and we don't do it. 407ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * See: http://b/issue?id=4998315 408ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee * What's the right thing to do here? 40922c0569fe6816086acdef90798622a6d6e209532Brian Carlstrom * 41022c0569fe6816086acdef90798622a6d6e209532Brian Carlstrom * This has now been completely disabled because mclinker was 41122c0569fe6816086acdef90798622a6d6e209532Brian Carlstrom * closing stdout on exit, which was affecting both quick and 41222c0569fe6816086acdef90798622a6d6e209532Brian Carlstrom * portable. 413ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee */ 414b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dlclose(compiler_library_); 415b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 41622c0569fe6816086acdef90798622a6d6e209532Brian Carlstrom#endif 4173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 4183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4191212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerTls* CompilerDriver::GetTls() { 4204df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee // Lazily create thread-local storage 4214df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_)); 4224df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee if (res == NULL) { 4234df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee res = new CompilerTls(); 4244df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls"); 4254df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee } 4264df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee return res; 4274df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee} 4284df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee 4291212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileAll(jobject class_loader, 4301212a022fa5f8ef9585d765b1809521812af882cIan Rogers const std::vector<const DexFile*>& dex_files) { 43125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 432ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 43356edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_)); 434a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal TimingLogger timings("compiler", false); 435601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 43656edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers PreCompile(class_loader, dex_files, *thread_pool.get(), timings); 437601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 43856edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers Compile(class_loader, dex_files, *thread_pool.get(), timings); 439601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 440ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) { 441a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal LOG(INFO) << Dumpable<TimingLogger>(timings); 442601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 443996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 444ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_stats_) { 445ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom stats_->Dump(); 446ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom } 4478a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 4488a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 4491212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileOne(const mirror::AbstractMethod* method) { 45025c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 45100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 45200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject class_loader; 45300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile* dex_file; 454fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers uint32_t class_def_idx; 45500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 45600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccessUnchecked soa(self); 45700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jobject> 45800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers local_class_loader(soa.Env(), 45900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader())); 46000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers class_loader = soa.Env()->NewGlobalRef(local_class_loader.get()); 46100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Find the dex_file 462fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MethodHelper mh(method); 463fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers dex_file = &mh.GetDexFile(); 464fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_idx = mh.GetClassDefIndex(); 46500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 46600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kNative); 467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 468ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 46900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_files.push_back(dex_file); 470ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 47156edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers UniquePtr<ThreadPool> thread_pool(new ThreadPool(1U)); 472a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal TimingLogger timings("CompileOne", false); 47356edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers PreCompile(class_loader, dex_files, *thread_pool.get(), timings); 474ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 47600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); 47708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers CompileMethod(code_item, method->GetAccessFlags(), method->GetInvokeType(), 478fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_idx, method_idx, class_loader, *dex_file); 479ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 48000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->GetJniEnv()->DeleteGlobalRef(class_loader); 48100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 48200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 4839ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 4849ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 4851212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files, 4861212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 487ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 4899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 4902f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ResolveDexFile(class_loader, *dex_file, thread_pool, timings); 4919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 4929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 4939ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 4941212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 4951212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 4962f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom Resolve(class_loader, dex_files, thread_pool, timings); 497601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 4982f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom Verify(class_loader, dex_files, thread_pool, timings); 499ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5002f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom InitializeClasses(class_loader, dex_files, thread_pool, timings); 501ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 502ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5031bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersbool CompilerDriver::IsImageClass(const char* descriptor) const { 504ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 505167436311a08a65dea28dda079a137893821c9c7Jeff Hao return false; 506ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 507ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 508ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 509ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5101212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) { 5111212a022fa5f8ef9585d765b1809521812af882cIan Rogers MutexLock mu(Thread::Current(), CompilerDriver::compiled_classes_lock_); 5123d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers compiled_classes_.Put(ref, compiled_class); 5133d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers} 5143d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers 5151212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, 5161212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t type_idx) { 51700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 5182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 5196d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 520c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 5232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5246d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 525c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5276d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 528996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 529996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 530c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 531996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 532c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 533996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 534996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5356d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 5366d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 5371212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, 5381212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t string_idx) { 5391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 5401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5415f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers bool result = false; 5425f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers if (IsImage()) { 5435f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers // We resolve all const-string strings when building for the image. 54400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 5452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 5465f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache); 5475f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers result = true; 54800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 549996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 550c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 551996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 552c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 553996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 554996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5571212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, 5581212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t type_idx) { 55900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 5602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 5611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 5622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 564c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 5661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 5682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 5691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 570c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 5721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 5741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 575996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 576996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 577c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 578996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 579c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 580996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 581996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5821bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5841212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 5851212a022fa5f8ef9585d765b1809521812af882cIan Rogers const DexFile& dex_file, 5861212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t type_idx) { 58700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 5882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 5891bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 5902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 592c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5931bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 5941bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5951bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 5962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 5971bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 598c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5991bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 6001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 6021bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 603996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 604996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 605c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 606996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 607c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 608996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 609996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 6101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa, 6131bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mirror::DexCache* dex_cache, 61489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexCompilationUnit* mUnit) 615b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 6161bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers // The passed dex_cache is a hint, sanity check before asking the class linker that will take a 6171bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers // lock. 6181bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers if (dex_cache->GetDexFile() != mUnit->GetDexFile()) { 6191bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 6201bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers } 62189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 62289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex()); 62389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return mUnit->GetClassLinker()->ResolveType(*mUnit->GetDexFile(), referrer_method_id.class_idx_, 62489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_cache, class_loader); 6254dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 626a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa, 62889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexCompilationUnit* mUnit, 6292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t field_idx) 630b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 63189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 63289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 63389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return mUnit->GetClassLinker()->ResolveField(*mUnit->GetDexFile(), field_idx, dex_cache, 63489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers class_loader, false); 635a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 636a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa, 63889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const DexCompilationUnit* mUnit, 6392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t method_idx, 6402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers InvokeType type) 641b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 64289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 64389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 64489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return mUnit->GetClassLinker()->ResolveMethod(*mUnit->GetDexFile(), method_idx, dex_cache, 64589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers class_loader, NULL, type); 646a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 647a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 64889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, 6491212a022fa5f8ef9585d765b1809521812af882cIan Rogers int& field_offset, bool& is_volatile, bool is_put) { 65000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 65108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Conservative defaults. 6521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 6531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 65408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Try to resolve field and ignore if an Incompatible Class Change Error (ie is static). 6552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx); 65608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (resolved_field != NULL && !resolved_field->IsStatic()) { 6571bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mirror::Class* referrer_class = 6581bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers ComputeCompilingMethodsClass(soa, resolved_field->GetDeclaringClass()->GetDexCache(), 6591bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mUnit); 660e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (referrer_class != NULL) { 6612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 662e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 663e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 664e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 665e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 666e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 667e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 668e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. 6694445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 67089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::Class* dex_fields_class = mUnit->GetClassLinker()->ResolveType(dex_file, 671e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 672e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class); 673e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 674e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 675e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 676e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 677e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 678e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers fields_class != referrer_class; 679e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 680e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 681e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers is_volatile = resolved_field->IsVolatile(); 682e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers stats_->ResolvedInstanceField(); 683e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers return true; // Fast path. 684e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 6851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6861bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 68800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 68900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 6901bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 691c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 6921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 6931bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6941bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 69589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, 6961212a022fa5f8ef9585d765b1809521812af882cIan Rogers int& field_offset, int& ssb_index, 6971212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool& is_referrers_class, bool& is_volatile, 6981212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool is_put) { 69900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 70008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Conservative defaults. 7011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 7021bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 7031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 7041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 70508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static). 7062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx); 70708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (resolved_field != NULL && resolved_field->IsStatic()) { 7081bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mirror::Class* referrer_class = 7091bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers ComputeCompilingMethodsClass(soa, resolved_field->GetDeclaringClass()->GetDexCache(), 7101bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mUnit); 7111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 7122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 7138cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 7141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 7151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 717c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 7181bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 7191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 720e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 721e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 723e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 724e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 725e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 726e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. Don't change the field's class as that is 727e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // used to identify the SSB. 7284445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); 7292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* dex_fields_class = 73089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetClassLinker()->ResolveType(dex_file, 73189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 73289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers referrer_class); 733e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 734e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 735e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 736e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 7378cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 738e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 7391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 7401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 7414103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 7424103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 74389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()); 74400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (fields_class->GetDexCache() == dex_cache) { 7454103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 7464103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 7474103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 7484103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7494103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 750c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 7514103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 7524103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 753e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // Search dex file for localized ssb index, may fail if field's class is a parent 754e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // of the class mentioned in the dex file and there is no dex cache entry. 7551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 7561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 75789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetDexFile()->FindStringId(descriptor); 7581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 7591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 76089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers mUnit->GetDexFile()->FindTypeId(mUnit->GetDexFile()->GetIndexForStringId(*string_id)); 761b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes if (type_id != NULL) { 7621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 76389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers ssb_index = mUnit->GetDexFile()->GetIndexForTypeId(*type_id); 7641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 766c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 7671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 7681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 77500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 77600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 7771bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 778c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 7791bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 7801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 7811bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 7821212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, 7834f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers mirror::Class* referrer_class, 7841212a022fa5f8ef9585d765b1809521812af882cIan Rogers mirror::AbstractMethod* method, 7851212a022fa5f8ef9585d765b1809521812af882cIan Rogers uintptr_t& direct_code, 786e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers uintptr_t& direct_method, 787e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool update_stats) { 788137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // For direct and static methods compute possible direct_code and direct_method values, ie 789137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // an address for the Method* being invoked and an address of the code for that Method*. 790137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // For interface calls compute a value for direct_method that is the interface method being 791137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers // invoked, so this can be passed to the out-of-line runtime support code. 7922ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 7932ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 794c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers if (compiler_backend_ == kPortable) { 795c531cefbfb5394413122e9f57d211ba436cff012buzbee if (sharp_type != kStatic && sharp_type != kDirect) { 796c531cefbfb5394413122e9f57d211ba436cff012buzbee return; 797c531cefbfb5394413122e9f57d211ba436cff012buzbee } 798c531cefbfb5394413122e9f57d211ba436cff012buzbee } else { 799c531cefbfb5394413122e9f57d211ba436cff012buzbee if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) { 800c531cefbfb5394413122e9f57d211ba436cff012buzbee return; 801c531cefbfb5394413122e9f57d211ba436cff012buzbee } 802b8404a7de94c109e3c17b4205b5f8aaae996eb33TDYa } 8032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL; 8042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (!method_code_in_boot) { 8052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 8062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 8072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized(); 8084f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers if (has_clinit_trampoline && (method->GetDeclaringClass() != referrer_class)) { 8094f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers // Ensure we run the clinit trampoline unless we are invoking a static method in the same class. 8102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 8112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 812e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (update_stats) { 813e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (sharp_type != kInterface) { // Interfaces always go via a trampoline. 814e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->DirectCallsToBoot(type); 815e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 816e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->DirectMethodsToBoot(type); 817c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers } 8183fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 8193fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (compiling_boot) { 8200637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom const bool kSupportBootImageFixup = true; 8213fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (kSupportBootImageFixup) { 8223fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MethodHelper mh(method); 8233fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (IsImageClass(mh.GetDeclaringClassDescriptor())) { 8240637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // We can only branch directly to Methods that are resolved in the DexCache. 8250637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // Otherwise we won't invoke the resolution trampoline. 8263fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = -1; 8270637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom direct_code = -1; 8283fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8293fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 8303fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } else { 831b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method)->IsImageSpace()) { 8323fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = reinterpret_cast<uintptr_t>(method); 8333fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 834aa4a793d7175ceeb1efa215c2af5e52e42b22f0aJeff Hao direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromCompiledCode()); 8352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 8362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers} 8372ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 838e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogersbool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc, 839e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers InvokeType& invoke_type, 840e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers MethodReference& target_method, 841e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers int& vtable_idx, 842e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers uintptr_t& direct_code, uintptr_t& direct_method, 843e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool update_stats) { 84400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 845a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 8462ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 8472ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 8482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* resolved_method = 849e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers ComputeMethodReferencedFromCompilingMethod(soa, mUnit, target_method.dex_method_index, 850e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers invoke_type); 851a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 85208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Don't try to fast-path if we don't understand the caller's class or this appears to be an 85308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Incompatible Class Change Error. 8541bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mirror::Class* referrer_class = 8551bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers ComputeCompilingMethodsClass(soa, resolved_method->GetDeclaringClass()->GetDexCache(), 8561bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers mUnit); 857e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool icce = resolved_method->CheckIncompatibleClassChange(invoke_type); 85808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers if (referrer_class != NULL && !icce) { 8592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* methods_class = resolved_method->GetDeclaringClass(); 860a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 861a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 862996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 863a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 864a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 86508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // method public. Resort to the dex file to determine the correct class for the access 86608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // check. 867e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers uint16_t class_idx = 868e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers target_method.dex_file->GetMethodId(target_method.dex_method_index).class_idx_; 869e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers methods_class = mUnit->GetClassLinker()->ResolveType(*target_method.dex_file, 870e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers class_idx, referrer_class); 871a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 872a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 873137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers referrer_class->CanAccessMember(methods_class, resolved_method->GetAccessFlags())) { 874e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const bool kEnableFinalBasedSharpening = true; 875e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Sharpen a virtual call into a direct call when the target is known not to have been 876e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // overridden (ie is final). 877e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool can_sharpen_virtual_based_on_type = 878e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers (invoke_type == kVirtual) && (resolved_method->IsFinal() || methods_class->IsFinal()); 879e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // For invoke-super, ensure the vtable index will be correct to dispatch in the vtable of 880e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // the super class. 881e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool can_sharpen_super_based_on_type = (invoke_type == kSuper) && 882e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers (referrer_class != methods_class) && referrer_class->IsSubClass(methods_class) && 883e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers resolved_method->GetMethodIndex() < methods_class->GetVTable()->GetLength() && 884e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers (methods_class->GetVTable()->Get(resolved_method->GetMethodIndex()) == resolved_method); 885e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers 886e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (kEnableFinalBasedSharpening && (can_sharpen_virtual_based_on_type || 887e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers can_sharpen_super_based_on_type)) { 888fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 889fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 890e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(target_method.dex_method_index) == 891e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers resolved_method) << PrettyMethod(resolved_method); 892e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (update_stats) { 893e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->ResolvedMethod(invoke_type); 894e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->VirtualMadeDirect(invoke_type); 895e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 896e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers GetCodeAndMethodForDirectCall(invoke_type, kDirect, referrer_class, resolved_method, 897e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers direct_code, direct_method, update_stats); 898e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers invoke_type = kDirect; 899fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 900e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 901e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const bool kEnableVerifierBasedSharpening = true; 902e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (kEnableVerifierBasedSharpening && (invoke_type == kVirtual || 903e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers invoke_type == kInterface)) { 904e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Did the verifier record a more precise invoke target based on its type information? 905e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const CompilerDriver::MethodReference caller_method(mUnit->GetDexFile(), 906e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers mUnit->GetDexMethodIndex()); 907e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const CompilerDriver::MethodReference* devirt_map_target = 908e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers verifier::MethodVerifier::GetDevirtMap(caller_method, dex_pc); 909e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (devirt_map_target != NULL) { 910e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers mirror::DexCache* target_dex_cache = 911e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers mUnit->GetClassLinker()->FindDexCache(*devirt_map_target->dex_file); 912e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers mirror::ClassLoader* class_loader = 913e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); 914e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers mirror::AbstractMethod* called_method = 915e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers mUnit->GetClassLinker()->ResolveMethod(*devirt_map_target->dex_file, 916e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers devirt_map_target->dex_method_index, 917e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers target_dex_cache, class_loader, NULL, 918e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers kVirtual); 919e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers CHECK(called_method != NULL); 920e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers CHECK(!called_method->IsAbstract()); 921e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers GetCodeAndMethodForDirectCall(invoke_type, kDirect, referrer_class, called_method, 922e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers direct_code, direct_method, update_stats); 923e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool compiler_needs_dex_cache = 924f8582c3b87efa0245d176f768fd373e5b4289da4Ian Rogers (GetCompilerBackend() == kPortable) || 925e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers (GetCompilerBackend() == kQuick && instruction_set_ != kThumb2) || 926e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers (direct_code == 0) || (direct_code == static_cast<unsigned int>(-1)) || 927e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers (direct_method == 0) || (direct_method == static_cast<unsigned int>(-1)); 928e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if ((devirt_map_target->dex_file != target_method.dex_file) && 929e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers compiler_needs_dex_cache) { 930e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // We need to use the dex cache to find either the method or code, and the dex file 931e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // containing the method isn't the one expected for the target method. Try to find 932e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // the method within the expected target dex file. 933e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // TODO: the -1 could be handled as direct code if the patching new the target dex 934e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // file. 935e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // TODO: quick only supports direct pointers with Thumb2. 936e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // TODO: the following should be factored into a common helper routine to find 937e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // one dex file's method within another. 938e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile* dexfile = target_method.dex_file; 939e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile* cm_dexfile = 940e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers called_method->GetDeclaringClass()->GetDexCache()->GetDexFile(); 941e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile::MethodId& cm_method_id = 942e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers cm_dexfile->GetMethodId(called_method->GetDexMethodIndex()); 943e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const char* cm_descriptor = cm_dexfile->StringByTypeIdx(cm_method_id.class_idx_); 944e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile::StringId* descriptor = dexfile->FindStringId(cm_descriptor); 945e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (descriptor != NULL) { 946e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile::TypeId* type_id = 947e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers dexfile->FindTypeId(dexfile->GetIndexForStringId(*descriptor)); 948e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (type_id != NULL) { 949e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const char* cm_name = cm_dexfile->GetMethodName(cm_method_id); 950e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile::StringId* name = dexfile->FindStringId(cm_name); 951e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (name != NULL) { 952e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers uint16_t return_type_idx; 953e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers std::vector<uint16_t> param_type_idxs; 954e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool success = dexfile->CreateTypeList(&return_type_idx, ¶m_type_idxs, 955e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers cm_dexfile->GetMethodSignature(cm_method_id)); 956e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (success) { 957e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile::ProtoId* sig = 958e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers dexfile->FindProtoId(return_type_idx, param_type_idxs); 959e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (sig != NULL) { 960e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers const DexFile::MethodId* method_id = dexfile->FindMethodId(*type_id, 961e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers *name, *sig); 962e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (method_id != NULL) { 963e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (update_stats) { 964e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->ResolvedMethod(invoke_type); 965e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->VirtualMadeDirect(invoke_type); 966e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->PreciseTypeDevirtualization(); 967e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 968e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers target_method.dex_method_index = dexfile->GetIndexForMethodId(*method_id); 969e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers invoke_type = kDirect; 970e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers return true; 971e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 972e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 973e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 974e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 975e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 976e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 977e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } else { 978e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (update_stats) { 979e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->ResolvedMethod(invoke_type); 980e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->VirtualMadeDirect(invoke_type); 981e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->PreciseTypeDevirtualization(); 982e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 983e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers target_method = *devirt_map_target; 984e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers invoke_type = kDirect; 985e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers return true; 98602c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal } 987e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 98802c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal } 989e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (invoke_type == kSuper) { 99008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers // Unsharpened super calls are suspicious so go slow-path. 9912ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else { 992e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Sharpening failed so generate a regular resolved method dispatch. 993e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (update_stats) { 994e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->ResolvedMethod(invoke_type); 995e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 996e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (invoke_type == kVirtual || invoke_type == kSuper) { 997e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 998e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 999e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers GetCodeAndMethodForDirectCall(invoke_type, invoke_type, referrer_class, resolved_method, 1000e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers direct_code, direct_method, update_stats); 1001a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 1002a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 1003a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 1004a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 1005a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 1006e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers // Clean up any exception left by method/invoke_type resolution 100700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 100800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 1009a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 1010e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers if (update_stats) { 1011e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers stats_->UnresolvedMethod(invoke_type); 1012e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers } 1013a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 1014a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 1015a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 10161212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddCodePatch(const DexFile* dex_file, 1017f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 101808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType referrer_invoke_type, 1019f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 102008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType target_invoke_type, 10213fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 102250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 102300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers code_to_patch_.push_back(new PatchInformation(dex_file, 1024f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 102508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_invoke_type, 1026f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 102708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers target_invoke_type, 1028f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 10293fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 10301212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddMethodPatch(const DexFile* dex_file, 1031f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 103208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType referrer_invoke_type, 1033f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 103408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers InvokeType target_invoke_type, 10353fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 103650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 103700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers methods_to_patch_.push_back(new PatchInformation(dex_file, 1038f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 103908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers referrer_invoke_type, 1040f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 104108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers target_invoke_type, 1042f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 10433fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 10443fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers 1045219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersclass ParallelCompilationManager { 1046731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public: 1047219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers typedef void Callback(const ParallelCompilationManager* manager, size_t index); 10480e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier 1049219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager(ClassLinker* class_linker, 1050219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers jobject class_loader, 1051219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers CompilerDriver* compiler, 1052219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile* dex_file, 1053219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ThreadPool& thread_pool) 1054731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom : class_linker_(class_linker), 1055731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom class_loader_(class_loader), 1056731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom compiler_(compiler), 10570e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier dex_file_(dex_file), 10582f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom thread_pool_(&thread_pool) {} 1059731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 106000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* GetClassLinker() const { 1061731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(class_linker_ != NULL); 1062731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_linker_; 1063731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 106400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 106500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject GetClassLoader() const { 1066731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_loader_; 1067731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 106800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 10691212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompilerDriver* GetCompiler() const { 1070731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(compiler_ != NULL); 1071731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return compiler_; 1072731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 107400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile* GetDexFile() const { 1075731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_file_ != NULL); 1076731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_file_; 1077731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 1078731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 10790e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) { 10800e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier Thread* self = Thread::Current(); 10810e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier self->AssertNoPendingException(); 10820e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CHECK_GT(work_units, 0U); 10839ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 108402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier std::vector<ForAllClosure*> closures(work_units); 10850e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier for (size_t i = 0; i < work_units; ++i) { 10860e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier closures[i] = new ForAllClosure(this, begin + i, end, callback, work_units); 10870e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->AddTask(self, closures[i]); 10880e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 10890e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->StartWorkers(self); 109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 10910e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker 10920e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // thread destructor's called below perform join). 10930e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier CHECK_NE(self->GetState(), kRunnable); 1094d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 10950e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier // Wait for all the worker threads to finish. 10960e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier thread_pool_->Wait(self); 1097d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1098d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1099d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 1100d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 110102b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier class ForAllClosure : public Task { 11020e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier public: 1103219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ForAllClosure(ParallelCompilationManager* manager, size_t begin, size_t end, Callback* callback, 11040e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier size_t stripe) 1105219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers : manager_(manager), 11060e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier begin_(begin), 11070e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier end_(end), 11080e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier callback_(callback), 11090e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier stripe_(stripe) 11100e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier { 11111e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 1112aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 11139ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 11140e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier virtual void Run(Thread* self) { 11150e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier for (size_t i = begin_; i < end_; i += stripe_) { 1116219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers callback_(manager_, i); 11170e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier self->AssertNoPendingException(); 11180e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 11190e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier } 112002b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier 112102b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier virtual void Finalize() { 112202b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier delete this; 112302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier } 11240e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier private: 1125219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const ParallelCompilationManager* const manager_; 11260e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t begin_; 11270e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t end_; 1128219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const Callback* const callback_; 11290e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const size_t stripe_; 11300e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier }; 11311e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 11320e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier ClassLinker* const class_linker_; 11330e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const jobject class_loader_; 11341212a022fa5f8ef9585d765b1809521812af882cIan Rogers CompilerDriver* const compiler_; 11350e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier const DexFile* const dex_file_; 1136219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ThreadPool* const thread_pool_; 1137d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 1138d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 113900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Return true if the class should be skipped during compilation. We 114000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// never skip classes in the boot class loader. However, if we have a 114100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// non-boot class loader and we can resolve the class in the boot 114200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// class loader, we do skip the class. This happens if an app bundles 114300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// classes found in the boot classpath. Since at runtime we will 114400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// select the class from the boot classpath, do not attempt to resolve 114500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// or compile it now. 11462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool SkipClass(mirror::ClassLoader* class_loader, 114700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile& dex_file, 114800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const DexFile::ClassDef& class_def) 1149b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 115000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (class_loader == NULL) { 115100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return false; 115200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 115300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* descriptor = dex_file.GetClassDescriptor(class_def); 115400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 11552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker->FindClass(descriptor, NULL); 115600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (klass == NULL) { 115700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 115800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK(self->IsExceptionPending()); 115900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->ClearException(); 116000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return false; 116100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 116200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return true; 116300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 116400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 1165219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager, size_t class_def_index) 1166b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 116700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1168219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 1169219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile& dex_file = *manager->GetDexFile(); 1170d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1171845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 1172845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 1173845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 1174845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 1175845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 1176845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 1177845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 1178d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 117900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (SkipClass(class_loader, dex_file, class_def)) { 1180d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1181d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1182845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 1183d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 1184d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 1185d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 1186d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 1187d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 1188d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 1189d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1190d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1191d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1192219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ClassLinker* class_linker = manager->GetClassLinker(); 11932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1194d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 1195d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 11962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 11972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers class_loader, true); 1198d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1199d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1200d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 12010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1202d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1203d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1204fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers // If an instance field is final then we need to have a barrier on the return, static final 1205fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers // fields are assigned within the lock held for class initialization. 1206fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers bool requires_constructor_barrier = false; 1207d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 1208fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers if ((it.GetMemberAccessFlags() & kAccFinal) != 0) { 1209fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers requires_constructor_barrier = true; 1210fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers } 1211fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 12122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 12132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers class_loader, false); 1214d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1215d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1216d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 121720cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1218d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1219d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1220fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers if (requires_constructor_barrier) { 1221219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->AddRequiresConstructorBarrier(soa.Self(), manager->GetDexFile(), 1222fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers class_def_index); 1223fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers } 1224d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 12252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), 12262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers dex_cache, class_loader, NULL, 12272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers it.GetMethodInvokeType(class_def)); 1228d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1229d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1230d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1231845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1232d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1233d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1234d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 12352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), 12362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers dex_cache, class_loader, NULL, 12372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers it.GetMethodInvokeType(class_def)); 1238d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1239d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1240d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1241845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1242d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1243d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1244d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 1245d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1246d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1247219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void ResolveType(const ParallelCompilationManager* manager, size_t type_idx) 1248b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 1249d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 125000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1251219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ClassLinker* class_linker = manager->GetClassLinker(); 1252219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile& dex_file = *manager->GetDexFile(); 12532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1254219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 12552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 125600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 1257d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 125800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK(soa.Self()->IsExceptionPending()); 1259d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1260d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1261d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1262d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12631212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file, 12641212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1265d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1266d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 126700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: we could resolve strings here, although the string table is largely filled with class 126800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // and method names. 1269d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1270219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool); 12710e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_); 1272ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 1273d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 12740e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 1275ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 12769ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 12779ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 12781212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files, 12791212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1280ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1281ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 128298eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 12832f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom VerifyDexFile(class_loader, *dex_file, thread_pool, timings); 128498eacac683b78e60799323e8c7d59e7214808639jeffhao } 128598eacac683b78e60799323e8c7d59e7214808639jeffhao} 128698eacac683b78e60799323e8c7d59e7214808639jeffhao 1287219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index) 1288b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 128900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1290219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index); 1291219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def); 12922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = 1293219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->FindClass(descriptor, 1294219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader())); 1295d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 129662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK(soa.Self()->IsExceptionPending()); 129762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 1298f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao 1299f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao /* 1300f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * At compile time, we can still structurally verify the class even if FindClass fails. 1301f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * This is to ensure the class is structurally sound for compilation. An unsound class 1302f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * will be rejected by the verifier and later skipped during compilation in the compiler. 1303f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao */ 1304219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::DexCache* dex_cache = manager->GetClassLinker()->FindDexCache(*manager->GetDexFile()); 1305f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao std::string error_msg; 1306219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers if (verifier::MethodVerifier::VerifyClass(manager->GetDexFile(), 130700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_cache, 1308219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()), 1309ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao class_def_index, error_msg, true) == 131000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers verifier::MethodVerifier::kHardFailure) { 1311219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index); 1312f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao LOG(ERROR) << "Verification failed on class " 1313219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers << PrettyDescriptor(manager->GetDexFile()->GetClassDescriptor(class_def)) 1314f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << " because: " << error_msg; 1315f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao } 1316d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1317d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1318d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 1319219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->VerifyClass(klass); 1320d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1321d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 1322d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 132362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK(soa.Self()->IsExceptionPending()); 132462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 1325d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1326d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 13279ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous()) 13289ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers << PrettyDescriptor(klass) << ": state=" << klass->GetStatus(); 132962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->AssertNoPendingException(); 1330d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1331d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 13321212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file, 13331212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1334731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1335219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool); 13360e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 13373d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("Verify " + dex_file.GetLocation()); 1338a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1339a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 134064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic const char* class_initializer_black_list[] = { 134164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/app/ActivityThread;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 134264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/bluetooth/BluetoothAudioGateway;", // Calls android.bluetooth.BluetoothAudioGateway.classInitNative(). 134364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/bluetooth/HeadsetBase;", // Calls android.bluetooth.HeadsetBase.classInitNative(). 134464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/res/CompatibilityInfo;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 134564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/res/CompatibilityInfo$1;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 134664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/content/UriMatcher;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 134764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/CursorWindow;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 134864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteConnection;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 134964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteConnection$Operation;", // Requires SimpleDateFormat -> java.util.Locale. 135064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteDatabaseConfiguration;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 135164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteDebug;", // Calls android.util.Log.isLoggable. 135264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteOpenHelper;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 135364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/database/sqlite/SQLiteQueryBuilder;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 135464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/drm/DrmManagerClient;", // Calls System.loadLibrary. 135564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/AnimatedRotateDrawable;", // Sub-class of Drawable. 135664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/AnimationDrawable;", // Sub-class of Drawable. 135764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/BitmapDrawable;", // Sub-class of Drawable. 135864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ClipDrawable;", // Sub-class of Drawable. 135964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ColorDrawable;", // Sub-class of Drawable. 136064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/Drawable;", // Requires android.graphics.Rect. 136164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/DrawableContainer;", // Sub-class of Drawable. 136264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/GradientDrawable;", // Sub-class of Drawable. 136364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/LayerDrawable;", // Sub-class of Drawable. 136464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/NinePatchDrawable;", // Sub-class of Drawable. 136564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/RotateDrawable;", // Sub-class of Drawable. 136664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ScaleDrawable;", // Sub-class of Drawable. 136764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/ShapeDrawable;", // Sub-class of Drawable. 136864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/StateListDrawable;", // Sub-class of Drawable. 136964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/drawable/TransitionDrawable;", // Sub-class of Drawable. 137064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Matrix;", // Calls android.graphics.Matrix.native_create. 137164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Matrix$1;", // Requires Matrix. 137264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/PixelFormat;", // Calls android.graphics.PixelFormat.nativeClassInit(). 137364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Rect;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 137464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/SurfaceTexture;", // Calls android.graphics.SurfaceTexture.nativeClassInit(). 137564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/graphics/Typeface;", // Calls android.graphics.Typeface.nativeCreate. 137664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/inputmethodservice/ExtractEditText;", // Requires android.widget.TextView. 1377bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/AmrInputStream;", // Calls OsConstants.initConstants. 1378bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/CamcorderProfile;", // Calls OsConstants.initConstants. 137964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/CameraProfile;", // Calls System.loadLibrary. 138064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/DecoderCapabilities;", // Calls System.loadLibrary. 1381bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/EncoderCapabilities;", // Calls OsConstants.initConstants. 1382bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/ExifInterface;", // Calls OsConstants.initConstants. 1383bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaCodec;", // Calls OsConstants.initConstants. 1384bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaCodecList;", // Calls OsConstants.initConstants. 1385bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaCrypto;", // Calls OsConstants.initConstants. 1386bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaDrm;", // Calls OsConstants.initConstants. 1387bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaExtractor;", // Calls OsConstants.initConstants. 138864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaFile;", // Requires DecoderCapabilities. 1389bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaMetadataRetriever;", // Calls OsConstants.initConstants. 1390bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/MediaMuxer;", // Calls OsConstants.initConstants. 139164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaPlayer;", // Calls System.loadLibrary. 139264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaRecorder;", // Calls System.loadLibrary. 139364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/media/MediaScanner;", // Calls System.loadLibrary. 1394bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/ResampleInputStream;", // Calls OsConstants.initConstants. 1395bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/SoundPool;", // Calls OsConstants.initConstants. 1396bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/videoeditor/MediaArtistNativeHelper;", // Calls OsConstants.initConstants. 1397bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/media/videoeditor/VideoEditorProfile;", // Calls OsConstants.initConstants. 1398bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/mtp/MtpDatabase;", // Calls OsConstants.initConstants. 1399bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/mtp/MtpDevice;", // Calls OsConstants.initConstants. 1400bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/mtp/MtpServer;", // Calls OsConstants.initConstants. 140164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/NetworkInfo;", // Calls java.util.EnumMap.<init> -> java.lang.Enum.getSharedConstants -> System.identityHashCode. 140264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Proxy;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 140364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/SSLCertificateSocketFactory;", // Requires javax.net.ssl.HttpsURLConnection. 140464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 140564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$AbstractHierarchicalUri;", // Requires Uri. 140664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$HierarchicalUri;", // Requires Uri. 140764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$OpaqueUri;", // Requires Uri. 140864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/Uri$StringUri;", // Requires Uri. 140964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/net/WebAddress;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 141064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/nfc/NdefRecord;", // Calls String.getBytes -> java.nio.charset.Charset. 1411bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom "Landroid/opengl/EGL14;", // Calls android.opengl.EGL14._nativeClassInit. 141264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES10;", // Calls android.opengl.GLES10._nativeClassInit. 141364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES10Ext;", // Calls android.opengl.GLES10Ext._nativeClassInit. 141464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES11;", // Requires GLES10. 141564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES11Ext;", // Calls android.opengl.GLES11Ext._nativeClassInit. 141664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLES20;", // Calls android.opengl.GLES20._nativeClassInit. 141764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/opengl/GLUtils;", // Calls android.opengl.GLUtils.nativeClassInit. 141864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Build;", // Calls -..-> android.os.SystemProperties.native_get. 141964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Build$VERSION;", // Requires Build. 142064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Debug;", // Requires android.os.Environment. 142164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Environment;", // Calls System.getenv. 142264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/FileUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 142364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/StrictMode;", // Calls android.util.Log.isLoggable. 142464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/StrictMode$VmPolicy;", // Requires StrictMode. 142564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/Trace;", // Calls android.os.Trace.nativeGetEnabledTags. 142664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/os/UEventObserver;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex. 1427bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/provider/ContactsContract;", // Calls OsConstants.initConstants. 1428bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/provider/Settings$Global;", // Calls OsConstants.initConstants. 142964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/provider/Settings$Secure;", // Requires android.net.Uri. 143064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/provider/Settings$System;", // Requires android.net.Uri. 143164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/renderscript/RenderScript;", // Calls System.loadLibrary. 143264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/server/BluetoothService;", // Calls android.server.BluetoothService.classInitNative. 143364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/server/BluetoothEventLoop;", // Calls android.server.BluetoothEventLoop.classInitNative. 143464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/telephony/PhoneNumberUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 1435bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom "Landroid/telephony/TelephonyManager;", // Calls OsConstants.initConstants. 143664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/AutoText;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. 143764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/Layout;", // Calls com.android.internal.util.ArrayUtils.emptyArray -> System.identityHashCode. 143864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/BoringLayout;", // Requires Layout. 143964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/DynamicLayout;", // Requires Layout. 144064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/Html$HtmlParser;", // Calls -..-> String.toLowerCase -> java.util.Locale. 144164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/StaticLayout;", // Requires Layout. 144264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/text/TextUtils;", // Requires android.util.DisplayMetrics. 144364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/util/DisplayMetrics;", // Calls SystemProperties.native_get_int. 144464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/util/Patterns;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 144564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/Choreographer;", // Calls SystemProperties.native_get_boolean. 1446bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/util/Patterns;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 1447bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/GLES20Canvas;", // Calls GLES20Canvas.nIsAvailable(). 144864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/GLES20RecordingCanvas;", // Requires android.view.GLES20Canvas. 1449bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/GestureDetector;", // Calls android.view.GLES20Canvas.nIsAvailable. 145064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/HardwareRenderer$Gl20Renderer;", // Requires SystemProperties.native_get. 1451bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/HardwareRenderer$GlRenderer;", // Requires SystemProperties.native_get. 145264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/InputEventConsistencyVerifier;", // Requires android.os.Build. 145364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/view/Surface;", // Requires SystemProperties.native_get. 1454bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/SurfaceControl;", // Calls OsConstants.initConstants. 1455bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/animation/AlphaAnimation;", // Requires Animation. 1456bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/animation/Animation;", // Calls SystemProperties.native_get_boolean. 1457bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/animation/AnimationSet;", // Calls OsConstants.initConstants. 1458bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/view/textservice/SpellCheckerSubtype;", // Calls Class.getDex(). 145964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/webkit/JniUtil;", // Calls System.loadLibrary. 1460bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/webkit/PluginManager;", // // Calls OsConstants.initConstants. 146164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/webkit/WebViewCore;", // Calls System.loadLibrary. 1462bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/webkit/WebViewInputDispatcher;", // Calls Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 1463bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Landroid/webkit/URLUtil;", // Calls Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 146464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/AutoCompleteTextView;", // Requires TextView. 146564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/Button;", // Requires TextView. 146664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CheckBox;", // Requires TextView. 146764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CheckedTextView;", // Requires TextView. 146864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/CompoundButton;", // Requires TextView. 146964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/EditText;", // Requires TextView. 147064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/NumberPicker;", // Requires java.util.Locale. 147164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/ScrollBarDrawable;", // Sub-class of Drawable. 147264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/SearchView$SearchAutoComplete;", // Requires TextView. 147364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/Switch;", // Requires TextView. 147464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Landroid/widget/TextView;", // Calls Paint.<init> -> Paint.native_init. 147564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 1476bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/i18n/phonenumbers/PhoneNumberMatcher;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 147764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/i18n/phonenumbers/PhoneNumberUtil;", // Requires java.util.logging.LogManager. 147864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/os/SamplingProfilerIntegration;", // Calls SystemProperties.native_get_int. 147964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/policy/impl/PhoneWindow;", // Calls android.os.Binder.init. 148064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/view/menu/ActionMenuItemView;", // Requires TextView. 148164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/internal/widget/DialogTitle;", // Requires TextView. 148264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/asn1/StreamUtil;", // Calls Runtime.getRuntime().maxMemory(). 1483e40f302f539dbca0a4b2cd7ee9eba6d37095b584Kenny Root "Lcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest$SHA1;", // Requires com.android.org.conscrypt.NativeCrypto. 148464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/crypto/engines/RSABlindedEngine;", // Calls native ... -> java.math.NativeBN.BN_new(). 148564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/jce/provider/CertBlacklist;", // Calls System.getenv -> OsConstants.initConstants. 148664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi;", // Calls System.getenv -> OsConstants.initConstants. 1487e40f302f539dbca0a4b2cd7ee9eba6d37095b584Kenny Root "Lcom/android/org/conscrypt/NativeCrypto;", // Calls native NativeCrypto.clinit(). 1488bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLECKeyPairGenerator;", // Calls OsConstants.initConstants. 1489bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLMac$HmacMD5;", // Calls native NativeCrypto.clinit(). 1490bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLMac$HmacSHA1;", // Calls native NativeCrypto.clinit(). 1491bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLMac$HmacSHA256;", // Calls native NativeCrypto.clinit(). 1492bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLMac$HmacSHA384;", // Calls native NativeCrypto.clinit(). 1493bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLMac$HmacSHA512;", // Calls native NativeCrypto.clinit(). 1494e40f302f539dbca0a4b2cd7ee9eba6d37095b584Kenny Root "Lcom/android/org/conscrypt/OpenSSLMessageDigestJDK$MD5;", // Requires com.android.org.conscrypt.NativeCrypto. 1495e40f302f539dbca0a4b2cd7ee9eba6d37095b584Kenny Root "Lcom/android/org/conscrypt/OpenSSLMessageDigestJDK$SHA1;", // Requires com.android.org.conscrypt.NativeCrypto. 1496e40f302f539dbca0a4b2cd7ee9eba6d37095b584Kenny Root "Lcom/android/org/conscrypt/OpenSSLMessageDigestJDK$SHA512;", // Requires com.android.org.conscrypt.NativeCrypto. 1497bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLX509CertPath;", // Calls OsConstants.initConstants. 1498bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Lcom/android/org/conscrypt/OpenSSLX509CertificateFactory;", // Calls OsConstants.initConstants. 1499e40f302f539dbca0a4b2cd7ee9eba6d37095b584Kenny Root "Lcom/android/org/conscrypt/TrustedCertificateStore;", // Calls System.getenv -> OsConstants.initConstants. 150064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/EGLContextImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit. 150164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/EGLImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit. 150264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lcom/google/android/gles_jni/GLImpl;", // Calls com.google.android.gles_jni.GLImpl._nativeClassInit. 150364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/Console;", // Has FileDescriptor(s). 150464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/File;", // Calls to Random.<init> -> System.currentTimeMillis -> OsConstants.initConstants. 150564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/FileDescriptor;", // Requires libcore.io.OsConstants. 150664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectInputStream;", // Requires java.lang.ClassLoader$SystemClassLoader. 150764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectStreamClass;", // Calls to Class.forName -> java.io.FileDescriptor. 150864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/io/ObjectStreamConstants;", // Instance of non-image class SerializablePermission. 150964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/ClassLoader$SystemClassLoader;", // Calls System.getProperty -> OsConstants.initConstants. 151064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/Runtime;", // Calls System.getProperty -> OsConstants.initConstants. 151164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/lang/System;", // Calls OsConstants.initConstants. 151264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/BigDecimal;", // Calls native ... -> java.math.NativeBN.BN_new(). 151364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/BigInteger;", // Calls native ... -> java.math.NativeBN.BN_new(). 151464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/math/Multiplication;", // Calls native ... -> java.math.NativeBN.BN_new(). 151564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/InetAddress;", // Requires libcore.io.OsConstants. 151664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/Inet4Address;", // Sub-class of InetAddress. 151764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/net/Inet6Address;", // Sub-class of InetAddress. 1518bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Ljava/net/InetUnixAddress;", // Sub-class of InetAddress. 151964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/Charset;", // Calls Charset.getDefaultCharset -> System.getProperty -> OsConstants.initConstants. 152064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/CharsetICU;", // Sub-class of Charset. 152164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/nio/charset/Charsets;", // Calls Charset.forName. 1522bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Ljava/security/KeyPairGenerator;", // Calls OsConstants.initConstants. 152364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/security/Security;", // Tries to do disk IO for "security.properties". 1524bf47e5f28b1aa39748dce8ac5abbabca1baee093Brian Carlstrom "Ljava/sql/Date;", // Calls OsConstants.initConstants. 152564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/Date;", // Calls Date.<init> -> System.currentTimeMillis -> OsConstants.initConstants. 152664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/Locale;", // Calls System.getProperty -> OsConstants.initConstants. 152764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/SimpleTimeZone;", // Sub-class of TimeZone. 152864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/TimeZone;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 152964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/concurrent/ConcurrentHashMap$Segment;", // Calls Runtime.getRuntime().availableProcessors(). 153064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljava/util/logging/LogManager;", // Calls System.getProperty -> OsConstants.initConstants. 153164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/microedition/khronos/egl/EGL10;", // Requires EGLContext. 153264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/microedition/khronos/egl/EGLContext;", // Requires com.google.android.gles_jni.EGLImpl. 153364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Ljavax/net/ssl/HttpsURLConnection;", // Calls SSLSocketFactory.getDefault -> java.security.Security.getProperty. 153464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/icu/LocaleData;", // Requires java.util.Locale. 1535333a8ec11113e75552093cf8be6fbda2673a5be3Brian Carlstrom "Llibcore/icu/TimeZoneNames;", // Requires java.util.TimeZone. 1536f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers "Llibcore/io/IoUtils;", // Calls Random.<init> -> System.currentTimeMillis -> FileDescriptor -> OsConstants.initConstants. 153764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/io/OsConstants;", // Platform specific. 153864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/net/MimeUtils;", // Calls libcore.net.MimeUtils.getContentTypesPropertiesStream -> System.getProperty. 153964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/util/ZoneInfo;", // Sub-class of TimeZone. 154064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Llibcore/util/ZoneInfoDB;", // Calls System.getenv -> OsConstants.initConstants. 154164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/commons/logging/LogFactory;", // Calls System.getProperty. 154264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/fortress/Services;", // Calls ClassLoader.getSystemClassLoader -> System.getProperty. 154364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/provider/cert/X509CertFactoryImpl;", // Requires java.nio.charsets.Charsets. 154464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/provider/crypto/RandomBitsSupplier;", // Requires java.io.File. 154564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/utils/AlgNameMapper;", // Requires java.util.Locale. 154664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/AttributeTypeAndValue;", // Calls IntegralToString.convertInt -> Thread.currentThread. 154764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/DirectoryString;", // Requires BigInteger. 154864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x501/Name;", // Requires org.apache.harmony.security.x501.AttributeTypeAndValue. 154964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Certificate;", // Requires org.apache.harmony.security.x509.TBSCertificate. 155064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/TBSCertificate;", // Requires org.apache.harmony.security.x501.Name. 155164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/EDIPartyName;", // Calls native ... -> java.math.NativeBN.BN_new(). 155264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/GeneralName;", // Requires org.apache.harmony.security.x501.Name. 155364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/GeneralNames;", // Requires GeneralName. 155464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Time;", // Calls native ... -> java.math.NativeBN.BN_new(). 155564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/security/x509/Validity;", // Requires x509.Time. 155664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/harmony/xml/ExpatParser;", // Calls native ExpatParser.staticInitialize. 155764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/params/ConnRouteParams;", // Requires java.util.Locale. 155864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/ssl/SSLSocketFactory;", // Calls java.security.Security.getProperty. 155964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers "Lorg/apache/http/conn/util/InetAddressUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. 156064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers}; 156164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 1562219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index) 15633d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 1564219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index); 156500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1566219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 1567219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def); 1568219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor, class_loader); 156964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 157064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool can_init_static_fields = compiling_boot && 1571219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->IsImageClass(descriptor); 15723d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass != NULL) { 157364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't want class initialization occurring on multiple threads due to deadlock problems. 157464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // For example, a parent class is initialized (holding its lock) that refers to a sub-class 157564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // in its static/class initializer causing it to try to acquire the sub-class' lock. While 157664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // on a second thread the sub-class is initialized (holding its lock) after first initializing 157764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent 157864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // lock ordering and consequent potential deadlock. 157964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers static Mutex lock1("Initializer lock", kMonitorLock); 158062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers MutexLock mu(soa.Self(), lock1); 158164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // The lock required to initialize the class. 158262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ObjectLock lock2(soa.Self(), klass); 158364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Only try to initialize classes that were successfully verified. 15843d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass->IsVerified()) { 1585219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields); 158664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!klass->IsInitialized()) { 158764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (can_init_static_fields) { 158864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers bool is_black_listed = false; 158964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) { 159064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (StringPiece(descriptor) == class_initializer_black_list[i]) { 159164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers is_black_listed = true; 159264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers break; 159364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 159464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 159564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!is_black_listed) { 159664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(INFO) << "Initializing: " << descriptor; 159764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (StringPiece(descriptor) == "Ljava/lang/Void;"){ 159864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime. 15992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields(); 160064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK_EQ(fields->GetLength(), 1); 1601219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers fields->Get(0)->SetObj(klass, manager->GetClassLinker()->FindPrimitiveClass('V')); 16022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass->SetStatus(mirror::Class::kStatusInitialized); 160364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 1604219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetClassLinker()->EnsureInitialized(klass, true, can_init_static_fields); 160564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 160662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->AssertNoPendingException(); 160764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 160864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 160964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 16103d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers // If successfully initialized place in SSB array. 16113d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (klass->IsInitialized()) { 16123d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers klass->GetDexCache()->GetInitializedStaticStorage()->Set(klass->GetDexTypeIndex(), klass); 16130755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 161427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 16153d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers // Record the final class status if necessary. 16162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class::Status status = klass->GetStatus(); 1617219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers CompilerDriver::ClassReference ref(manager->GetDexFile(), class_def_index); 1618219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers CompiledClass* compiled_class = manager->GetCompiler()->GetCompiledClass(ref); 16193d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers if (compiled_class == NULL) { 16203d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers compiled_class = new CompiledClass(status); 1621219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->RecordClassStatus(ref, compiled_class); 16223d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers } else { 16233d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers DCHECK_EQ(status, compiled_class->GetStatus()); 1624ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 162598eacac683b78e60799323e8c7d59e7214808639jeffhao } 16261f5393447b9f45be7918042d9ee7b521376de866Ian Rogers // Clear any class not found or verification exceptions. 162762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 162898eacac683b78e60799323e8c7d59e7214808639jeffhao} 162998eacac683b78e60799323e8c7d59e7214808639jeffhao 16301212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file, 16311212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 163264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#ifndef NDEBUG 163364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) { 163464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers const char* descriptor = class_initializer_black_list[i]; 163564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(IsValidDescriptor(descriptor)) << descriptor; 163664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 163764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#endif 16383d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1639219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, thread_pool); 164064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count_); 16413d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("InitializeNoClinit " + dex_file.GetLocation()); 16423d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers} 164390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 16441212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InitializeClasses(jobject class_loader, 16451212a022fa5f8ef9585d765b1809521812af882cIan Rogers const std::vector<const DexFile*>& dex_files, 16461212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 16473d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers for (size_t i = 0; i != dex_files.size(); ++i) { 16483d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers const DexFile* dex_file = dex_files[i]; 164990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(dex_file != NULL); 16502f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom InitializeClasses(class_loader, *dex_file, thread_pool, timings); 165100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 165290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao} 165390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 16541212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 16552f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom ThreadPool& thread_pool, TimingLogger& timings) { 1656ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1657ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 165883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 16592f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom CompileDexFile(class_loader, *dex_file, thread_pool, timings); 166083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 166183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 166283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 1663219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersvoid CompilerDriver::CompileClass(const ParallelCompilationManager* manager, size_t class_def_index) { 1664219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers jobject class_loader = manager->GetClassLoader(); 1665219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers const DexFile& dex_file = *manager->GetDexFile(); 1666c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 166700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 166800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1669219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()); 167000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (SkipClass(class_loader, dex_file, class_def)) { 167100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 167200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 16735ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 1674d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 1675d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 1676776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (verifier::MethodVerifier::IsClassRejected(ref)) { 1677d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 1678d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 16790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 16800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 16810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 16820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 16830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 16840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 16850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 16860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 16870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 16880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 16890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 16900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 16910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 16920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 169368adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom int64_t previous_direct_method_idx = -1; 16940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 16956f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 16966f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom if (method_idx == previous_direct_method_idx) { 16976f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // smali can create dex files with two encoded_methods sharing the same method_idx 16986f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // http://code.google.com/p/smali/issues/detail?id=119 16996f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom it.Next(); 17006f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom continue; 17016f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom } 17026f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom previous_direct_method_idx = method_idx; 1703219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1704fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers it.GetMethodInvokeType(class_def), class_def_index, 1705fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 17060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 17079ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 17080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 170968adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom int64_t previous_virtual_method_idx = -1; 17100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 17116f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 17126f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom if (method_idx == previous_virtual_method_idx) { 17136f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // smali can create dex files with two encoded_methods sharing the same method_idx 17146f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom // http://code.google.com/p/smali/issues/detail?id=119 17156f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom it.Next(); 17166f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom continue; 17176f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom } 17186f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom previous_virtual_method_idx = method_idx; 1719219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1720fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers it.GetMethodInvokeType(class_def), class_def_index, 1721fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers method_idx, class_loader, dex_file); 17220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 17239ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 17240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 17259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 17269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 17271212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file, 17281212a022fa5f8ef9585d765b1809521812af882cIan Rogers ThreadPool& thread_pool, TimingLogger& timings) { 1729219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers ParallelCompilationManager context(NULL, class_loader, this, &dex_file, thread_pool); 17301212a022fa5f8ef9585d765b1809521812af882cIan Rogers context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_); 17313d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers timings.AddSplit("Compile " + dex_file.GetLocation()); 1732c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1733c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 17341212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 17351212a022fa5f8ef9585d765b1809521812af882cIan Rogers InvokeType invoke_type, uint32_t class_def_idx, 17361212a022fa5f8ef9585d765b1809521812af882cIan Rogers uint32_t method_idx, jobject class_loader, 17371212a022fa5f8ef9585d765b1809521812af882cIan Rogers const DexFile& dex_file) { 1738f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1739bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 17404dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1741169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 174257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file); 17433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1744169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 17452cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 17468447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum // In small mode we only compile image classes. 17478447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum bool dont_compile = Runtime::Current()->IsSmallMode() && ((image_classes_ == NULL) || (image_classes_->size() == 0)); 1748c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum 1749c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum // Don't compile class initializers, ever. 17501f55ea0d5cfea943ec11dd1be9ddb163e4e325b2Anwar Ghuloum if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { 1751c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum dont_compile = true; 17528447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum } else if (code_item->insns_size_in_code_units_ < Runtime::Current()->GetSmallModeMethodDexSizeLimit()) { 17538447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum // Do compile small methods. 17548447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum dont_compile = false; 1755c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum } 1756c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum 1757f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers if (!dont_compile) { 1758f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx, 1759c44f68fb6a6d55c0df28dd05b93d8906ec20bd08Anwar Ghuloum method_idx, class_loader, dex_file); 1760f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1761f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 1762bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 17633bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 1764c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#ifdef ART_USE_PORTABLE_COMPILER 17655354ec568ace1e117d5a93dcb802a612356200edIan Rogers const uint64_t kWarnMilliSeconds = 1000; 17665354ec568ace1e117d5a93dcb802a612356200edIan Rogers#else 17675354ec568ace1e117d5a93dcb802a612356200edIan Rogers const uint64_t kWarnMilliSeconds = 100; 17685354ec568ace1e117d5a93dcb802a612356200edIan Rogers#endif 17695354ec568ace1e117d5a93dcb802a612356200edIan Rogers if (duration_ns > MsToNs(kWarnMilliSeconds)) { 1770bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 17713bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1772f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1773f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 177450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 1775f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 17760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 17770755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 177800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 177950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, compiled_methods_lock_); 178000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers compiled_methods_.Put(ref, compiled_method); 178100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 17820755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 17832cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 17849baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 178550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (self->IsExceptionPending()) { 178650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ScopedObjectAccess soa(self); 178700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n" 178862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << self->GetException(NULL)->Dump(); 178900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 17900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 179128ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 17921212a022fa5f8ef9585d765b1809521812af882cIan RogersCompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const { 179350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_classes_lock_); 17940755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 17950755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 17960755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 17970755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 17980755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 17990755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 18000755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 18010755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 18021212a022fa5f8ef9585d765b1809521812af882cIan RogersCompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const { 180350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), compiled_methods_lock_); 18040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 18050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 18063320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 18072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 18083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 18093320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 18109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 18119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 18121212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::SetBitcodeFileName(std::string const& filename) { 18131212a022fa5f8ef9585d765b1809521812af882cIan Rogers typedef void (*SetBitcodeFileNameFn)(CompilerDriver&, std::string const&); 1814106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1815106b2a03be66748a25b9019e4c222cee498d559fLogan Chien SetBitcodeFileNameFn set_bitcode_file_name = 18168c4bbb55d0d801e492d849ee636771c8b2840429buzbee FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, 1817106b2a03be66748a25b9019e4c222cee498d559fLogan Chien "compilerLLVMSetBitcodeFileName"); 1818106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1819106b2a03be66748a25b9019e4c222cee498d559fLogan Chien set_bitcode_file_name(*this, filename); 18208b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 1821f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 1822fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 18231212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1824fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers size_t class_def_index) { 1825fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MutexLock mu(self, freezing_constructor_lock_); 1826fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index)); 1827fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers} 1828fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 18291212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1830fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers size_t class_def_index) { 1831fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers MutexLock mu(self, freezing_constructor_lock_); 1832fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0; 1833fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers} 1834fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers 18353f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrombool CompilerDriver::WriteElf(const std::string& android_root, 1836265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool is_host, 1837265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<const DexFile*>& dex_files, 1838265091e581c9f643b37e7966890911f09e223269Brian Carlstrom std::vector<uint8_t>& oat_contents, 1839265091e581c9f643b37e7966890911f09e223269Brian Carlstrom File* file) { 1840265091e581c9f643b37e7966890911f09e223269Brian Carlstrom typedef bool (*WriteElfFn)(CompilerDriver&, 18413f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom const std::string& android_root, 1842265091e581c9f643b37e7966890911f09e223269Brian Carlstrom bool is_host, 1843265091e581c9f643b37e7966890911f09e223269Brian Carlstrom const std::vector<const DexFile*>& dex_files, 1844265091e581c9f643b37e7966890911f09e223269Brian Carlstrom std::vector<uint8_t>&, 1845265091e581c9f643b37e7966890911f09e223269Brian Carlstrom File*); 1846700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom WriteElfFn WriteElf = 1847700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf"); 1848265091e581c9f643b37e7966890911f09e223269Brian Carlstrom Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); 18493f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom return WriteElf(*this, android_root, is_host, dex_files, oat_contents, file); 1850700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1851700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 18521212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::FixupElf(File* file, uintptr_t oat_data_begin) const { 1853700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*FixupElfFn)(File*, uintptr_t oat_data_begin); 1854700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FixupElfFn FixupElf = 1855700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<FixupElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "FixupElf"); 1856700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return FixupElf(file, oat_data_begin); 1857700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1858700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 18591212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::GetOatElfInformation(File* file, 18601212a022fa5f8ef9585d765b1809521812af882cIan Rogers size_t& oat_loaded_size, 18611212a022fa5f8ef9585d765b1809521812af882cIan Rogers size_t& oat_data_offset) const { 1862700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom typedef bool (*GetOatElfInformationFn)(File*, size_t& oat_loaded_size, size_t& oat_data_offset); 1863700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom GetOatElfInformationFn GetOatElfInformation = 1864700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom FindFunction<GetOatElfInformationFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, 1865700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom "GetOatElfInformation"); 1866700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom GetOatElfInformation(file, oat_loaded_size, oat_data_offset); 1867700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 1868700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1869265091e581c9f643b37e7966890911f09e223269Brian Carlstrombool CompilerDriver::StripElf(File* file) const { 1870265091e581c9f643b37e7966890911f09e223269Brian Carlstrom typedef bool (*StripElfFn)(File*); 1871265091e581c9f643b37e7966890911f09e223269Brian Carlstrom StripElfFn StripElf = 1872265091e581c9f643b37e7966890911f09e223269Brian Carlstrom FindFunction<StripElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "StripElf"); 1873265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return StripElf(file); 1874265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 1875265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 18761212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set, 18771212a022fa5f8ef9585d765b1809521812af882cIan Rogers std::string& target_triple, 18781212a022fa5f8ef9585d765b1809521812af882cIan Rogers std::string& target_cpu, 18791212a022fa5f8ef9585d765b1809521812af882cIan Rogers std::string& target_attr) { 1880265091e581c9f643b37e7966890911f09e223269Brian Carlstrom switch (instruction_set) { 1881700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kThumb2: 1882700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "thumb-none-linux-gnueabi"; 1883700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_cpu = "cortex-a9"; 1884700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db"; 1885700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1886700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1887700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kArm: 1888700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "armv7-none-linux-gnueabi"; 1889700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // TODO: Fix for Nexus S. 1890700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_cpu = "cortex-a9"; 1891700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // TODO: Fix for Xoom. 1892700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "+v7,+neon,+neonfp,+vfp3,+db"; 1893700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1894700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1895700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kX86: 1896700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "i386-pc-linux-gnu"; 1897700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = ""; 1898700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1899700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1900700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom case kMips: 1901700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_triple = "mipsel-unknown-linux"; 1902700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom target_attr = "mips32r2"; 1903700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom break; 1904700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 1905700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom default: 1906700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom LOG(FATAL) << "Unknown instruction set: " << instruction_set; 1907700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 1908700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom } 19099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1910