compiler_driver.cc revision 90dc30f4b9967e850d0594e57dfa8e7cb0369575
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "compiler.h" 189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 19d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <vector> 20d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 21b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include <dlfcn.h> 2227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h> 23d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <unistd.h> 2427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 261f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h" 279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "dex_cache.h" 289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 294dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#include "oat_compilation_unit.h" 303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 321f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 33b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include "space.h" 343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "stl_util.h" 35601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes#include "timing_logger.h" 36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/method_verifier.h" 379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 38059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 39059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#include <mach-o/dyld.h> 40059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 41059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 44c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm { 45bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 461cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type); 478add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 48c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 49c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 { 50bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 511cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type); 528add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 53e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian 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: 68c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"), 69c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_(0), types_not_in_dex_cache_(0), 70c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_(0), strings_not_in_dex_cache_(0), 71c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_(0), unresolved_types_(0), 72c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_(0), unresolved_instance_fields_(0), 732ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0) { 742ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 75c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[i] = 0; 76c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[i] = 0; 772ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[i] = 0; 782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[i] = 0; 792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[i] = 0; 80b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes } 81c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void Dump() { 84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache"); 85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache"); 86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_types_, unresolved_types_, "types resolved"); 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); 88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, 89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields resolved"); 90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_, 91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields local to a class"); 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 932ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 94c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers std::ostringstream oss; 952ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss << static_cast<InvokeType>(i) << " methods were AOT resolved"; 96c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str()); 972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (virtual_made_direct_[i] > 0) { 982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " methods made direct"; 1002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(virtual_made_direct_[i], 1012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i], 1022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_calls_to_boot_[i] > 0) { 1052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot"; 1072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_calls_to_boot_[i], 1082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i], 1092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_methods_to_boot_[i] > 0) { 1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot"; 1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_methods_to_boot_[i], 1152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i], 1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 118c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 119c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 120996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 121996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers// Allow lossy statistics in non-debug builds 122996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG 123996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() MutexLock mu(stats_lock_) 124996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else 125996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() 126996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif 127996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 128c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeInDexCache() { 129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_++; 131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 132996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 133c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNotInDexCache() { 134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_not_in_dex_cache_++; 136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 137996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 138c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringInDexCache() { 139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_++; 141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 142996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 143c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringNotInDexCache() { 144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_not_in_dex_cache_++; 146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 147996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 148c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeDoesntNeedAccessCheck() { 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_++; 151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 152996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 153c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNeedsAccessCheck() { 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_types_++; 156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 157996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 158c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedInstanceField() { 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_++; 161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 162996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 163b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes void UnresolvedInstanceField() { 164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_instance_fields_++; 166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 167996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 168c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedLocalStaticField() { 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_local_static_fields_++; 171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 172996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 173c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedStaticField() { 174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_static_fields_++; 176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 177996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 178c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedStaticField() { 179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_static_fields_++; 181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 182996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 183c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedMethod(InvokeType type) { 184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 186c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[type]++; 187996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 188996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 189c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedMethod(InvokeType type) { 190c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 191c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 192c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[type]++; 193996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 194c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 1952ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void VirtualMadeDirect(InvokeType type) { 1962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 1972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 1982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[type]++; 1992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 2012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectCallsToBoot(InvokeType type) { 2022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 2032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 2042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[type]++; 2052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 2072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectMethodsToBoot(InvokeType type) { 2082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 209fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers STATS_LOCK(); 2102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[type]++; 211fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } 2122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 213c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private: 214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Mutex stats_lock_; 215c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 216c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_in_dex_cache_; 217c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_not_in_dex_cache_; 218c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 219c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_in_dex_cache_; 220c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_not_in_dex_cache_; 221c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 222c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_types_; 223c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_types_; 224c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 225c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_instance_fields_; 226c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_instance_fields_; 227c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 228c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_local_static_fields_; 229c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_static_fields_; 230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_static_fields_; 231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 232c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_methods_[kMaxInvokeType + 1]; 233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_methods_[kMaxInvokeType + 1]; 2342ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t virtual_made_direct_[kMaxInvokeType + 1]; 2352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_calls_to_boot_[kMaxInvokeType + 1]; 2362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_methods_to_boot_[kMaxInvokeType + 1]; 237c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 238b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats); 239c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}; 240996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 241b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughesstatic std::string MakeCompilerSoName(InstructionSet instruction_set) { 242b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes // TODO: is the ARM/Thumb2 instruction set distinction really buying us anything, 243b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes // or just causing hassle like this? 244b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (instruction_set == kThumb2) { 245b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes instruction_set = kArm; 246b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 247b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 248059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Capitalize the instruction set, because that's what we do in the build system. 249b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes std::ostringstream instruction_set_name_os; 250b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes instruction_set_name_os << instruction_set; 251b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes std::string instruction_set_name(instruction_set_name_os.str()); 252b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes for (size_t i = 0; i < instruction_set_name.size(); ++i) { 253b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes instruction_set_name[i] = toupper(instruction_set_name[i]); 254b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 255059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Bad things happen if we pull in the libartd-compiler to a libart dex2oat or vice versa, 257059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // because we end up with both libart and libartd in the same address space! 25867d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes const char* suffix = (kIsDebugBuild ? "d" : ""); 259059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 260059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Work out the filename for the compiler library. 261c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#if !defined(ART_USE_LLVM_COMPILER) 262059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string library_name(StringPrintf("art%s-compiler-%s", suffix, instruction_set_name.c_str())); 263c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#else 264c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao std::string library_name(StringPrintf("art%s-compiler-llvm", suffix)); 265c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#endif 266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str())); 267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find 270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the 271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // same work. 272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes uint32_t executable_path_length = 0; 273448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes _NSGetExecutablePath(NULL, &executable_path_length); 274448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes std::string path(executable_path_length, static_cast<char>(0)); 275448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0); 276059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 277059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/dex2oat". 278059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes size_t last_slash = path.find_last_of('/'); 279059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes CHECK_NE(last_slash, std::string::npos) << path; 280059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 281059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 282059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/bin". 283059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes last_slash = path.find_last_of('/'); 284059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 285059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 286059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes filename = path + "/lib/" + filename; 287059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 288059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes return filename; 289b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 290b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 29146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn> 29246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) { 29346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes Fn fn = reinterpret_cast<Fn>(dlsym(library, name)); 29446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes if (fn == NULL) { 29546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror(); 29646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes } 297059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn); 29846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes return fn; 29946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes} 30046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes 3015523ee070b005576c6f889415205d49ea77cf243Elliott HughesCompiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count, 302ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom bool support_debugging, const std::set<std::string>* image_classes, 303ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom bool dump_stats, bool dump_timings) 304aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom : instruction_set_(instruction_set), 305c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 306c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 307c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 308aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 3095523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 310de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 311c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 312ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_stats_(dump_stats), 313ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_timings_(dump_timings), 314b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes image_classes_(image_classes), 315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_(NULL), 31646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes compiler_(NULL), 3176f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes compiler_context_(NULL), 31846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_(NULL), 319f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien create_invoke_stub_(NULL) 320f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 321f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien , compiler_enable_auto_elf_loading_(NULL), 322f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_get_method_code_addr_(NULL), 323f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_get_method_invoke_stub_addr_(NULL) 324f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#endif 325f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien{ 326c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao std::string compiler_so_name(MakeCompilerSoName(instruction_set_)); 327b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY); 328b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ == NULL) { 329b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror(); 330b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 331b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_; 332b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 333106b2a03be66748a25b9019e4c222cee498d559fLogan Chien#if defined(ART_USE_LLVM_COMPILER) 334106b2a03be66748a25b9019e4c222cee498d559fLogan Chien // Initialize compiler_context_ 335106b2a03be66748a25b9019e4c222cee498d559fLogan Chien typedef void (*InitCompilerContextFn)(Compiler&); 336106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 337106b2a03be66748a25b9019e4c222cee498d559fLogan Chien InitCompilerContextFn init_compiler_context = 338106b2a03be66748a25b9019e4c222cee498d559fLogan Chien FindFunction<void (*)(Compiler&)>(compiler_so_name, 339106b2a03be66748a25b9019e4c222cee498d559fLogan Chien compiler_library_, 340106b2a03be66748a25b9019e4c222cee498d559fLogan Chien "ArtInitCompilerContext"); 341106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 342106b2a03be66748a25b9019e4c222cee498d559fLogan Chien init_compiler_context(*this); 343106b2a03be66748a25b9019e4c222cee498d559fLogan Chien#endif 344106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 3453fa1b7e7a7fc9785ba4e8335d730e5caf6343322Elliott Hughes compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod"); 34646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtJniCompileMethod"); 34746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes create_invoke_stub_ = FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateInvokeStub"); 348b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 349f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 350f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_enable_auto_elf_loading_ = FindFunction<CompilerEnableAutoElfLoadingFn>( 351f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_so_name, compiler_library_, "compilerLLVMEnableAutoElfLoading"); 352f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_get_method_code_addr_ = FindFunction<CompilerGetMethodCodeAddrFn>( 353f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_so_name, compiler_library_, "compilerLLVMGetMethodCodeAddr"); 354f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_get_method_invoke_stub_addr_ = FindFunction<CompilerGetMethodInvokeStubAddrFn>( 355f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_so_name, compiler_library_, "compilerLLVMGetMethodInvokeStubAddr"); 356f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#endif 357f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 35825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 359ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 360ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 361ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 362c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 363c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 3643320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() { 365c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 366c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 367c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 368c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 369c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 370c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 371c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 372c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 373c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 374c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 375c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 376bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 377f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 378f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom MutexLock mu(compiled_methods_lock_); 379f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&code_to_patch_); 380f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 381f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 382f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom MutexLock mu(compiled_methods_lock_); 383f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&methods_to_patch_); 384f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 385c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 386c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_), 387c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiler_library_, 388c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao "compilerLLVMDispose"); 389c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao (*f)(*this); 390c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#endif 391b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ != NULL) { 392b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlclose(" << compiler_library_ << ")"; 393b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dlclose(compiler_library_); 394b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 3953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 3963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3971cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, 3981cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type) { 399ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 4001cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return x86::X86CreateResolutionTrampoline(type); 401ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 402ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 403ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 4041cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return arm::ArmCreateResolutionTrampoline(type); 405ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 406ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 407ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 4088add92dcf59568c72c17e9a979948b1a7a0b1264Elliott HughesByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 409169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 410169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 411169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 4128add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 413169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 4148add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 415169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 41649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 417169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 418169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 419169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 420169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 421ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan RogersByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 422ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 423ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return x86::CreateAbstractMethodErrorStub(); 424ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 425ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 426ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 427ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return arm::CreateAbstractMethodErrorStub(); 428ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 429ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 430ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 431254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilsonvoid Compiler::CompileAll(const ClassLoader* class_loader, 432ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 43325c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 434ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 435601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("compiler"); 436601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 437601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 438601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 439ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Compile(class_loader, dex_files); 440601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("Compile"); 441601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 442ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 443601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PostCompile"); 444601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 445ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) { 446601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.Dump(); 447601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 448996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 449ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_stats_) { 450ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom stats_->Dump(); 451ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom } 4528a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 4538a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 4543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromvoid Compiler::CompileOne(const Method* method) { 45525c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 456ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4578a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 458ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Find the dex_file 4600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 4610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); 462ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 463ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(&dex_file); 464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 465601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("CompileOne"); 466601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 469a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset()); 470a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file); 471ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 472ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 4739ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 4749ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader, 476d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 478ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 4799ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 480d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ResolveDexFile(class_loader, *dex_file, timings); 4819ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 4829ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 4839ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 484ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PreCompile(const ClassLoader* class_loader, 485601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 486d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Resolve(class_loader, dex_files, timings); 487601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Verify(class_loader, dex_files); 489601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.Verify"); 490601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 491ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom InitializeClassesWithoutClinit(class_loader, dex_files); 492601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.InitializeClassesWithoutClinit"); 493ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 494ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 495ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PostCompile(const ClassLoader* class_loader, 496ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 497e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMaps(class_loader, dex_files); 498d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 499c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_), 500c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiler_library_, 501c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao "compilerLLVMMaterializeRemainder"); 502c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao (*f)(*this); 503d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 504ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 505ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 506ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const { 507ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 508ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 509ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 510ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 511ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 512ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5136d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, 514996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 5156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 516c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5176d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 5191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 521c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5236d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 524996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 525996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 526c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 527996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 528c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 529996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 530996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 5326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 5331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache, 534996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t string_idx) { 5351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // TODO: Add support for loading strings referenced by image_classes_ 5361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 5371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // The following is a test saying that if we're building the image without a restricted set of 5391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // image classes then we can assume the string is present in the dex cache if it is there now 540996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL; 541996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 542c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 543996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 544c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 545996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 546996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache, 550996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers const DexFile& dex_file, uint32_t type_idx) { 5511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 5521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 554c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 5561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 5581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 5591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 560c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 5621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 5641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 565996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 566996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 567c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 568996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 569c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 570996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 571996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 5751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexCache* dex_cache, 5761bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile& dex_file, 577996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 5781bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 5791bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 581c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5821bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 5831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5841bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 5851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 5861bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 587c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 5891bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5901bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 5911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 592996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 593996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 594c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 595996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 596c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 597996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 598996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5991bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6014dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Class* ComputeReferrerClass(OatCompilationUnit* mUnit) { 6024dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile::MethodId& referrer_method_id = 6034dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->GetMethodId(mUnit->method_idx_); 604a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveType( 6064dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, referrer_method_id.class_idx_, 6074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_cache_, mUnit->class_loader_); 6084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 609a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6104dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) { 6114dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveField( 6124dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, field_idx, mUnit->dex_cache_, 6134dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, false); 614a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 615a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6164dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) { 6174dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveMethod( 6184dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, method_idx, mUnit->dex_cache_, 6194dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, true); 620a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 621a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6224dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 6238cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao int& field_offset, bool& is_volatile, bool is_put) { 6241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 6251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 6261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 6284dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 6291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 6304dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 631e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (referrer_class != NULL) { 632e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers Class* fields_class = resolved_field->GetDeclaringClass(); 633e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 634e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 635e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 636e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 637e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 638e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 639e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. 640e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); 641e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file, 642e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 643e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class); 644e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 645e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 646e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 647e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 648e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 649e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers fields_class != referrer_class; 650e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 651e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 652e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers is_volatile = resolved_field->IsVolatile(); 653e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers stats_->ResolvedInstanceField(); 654e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers return true; // Fast path. 655e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 6561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 6591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 6611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 6621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 663c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 6641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 6651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6674dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 6681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers int& field_offset, int& ssb_index, 6698cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool& is_referrers_class, bool& is_volatile, bool is_put) { 6701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 6711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 6721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 6731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 6741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 6751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 6764dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 6771bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 678a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers DCHECK(resolved_field->IsStatic()); 6794dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 6801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 6818cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao Class* fields_class = resolved_field->GetDeclaringClass(); 6828cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 6831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 6841bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 6851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 686c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 6871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 6881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 689e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers bool access_ok = referrer_class->CanAccess(fields_class) && 690e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(fields_class, 691e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 692e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (!access_ok) { 693e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // The referring class can't access the resolved field, this may occur as a result of a 694e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // protected field being made public by a sub-class. Resort to the dex file to determine 695e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // the correct class for the access check. Don't change the field's class as that is 696e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // used to identify the SSB. 697e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); 698e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers Class* dex_fields_class = 699e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers mUnit->class_linker_->ResolveType(dex_file, 700e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers dex_file.GetFieldId(field_idx).class_idx_, 701e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class); 702e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers access_ok = referrer_class->CanAccess(dex_fields_class) && 703e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers referrer_class->CanAccessMember(dex_fields_class, 704e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers resolved_field->GetAccessFlags()); 705e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers } 7068cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 707e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers if (access_ok && !is_write_to_final_from_wrong_class) { 7081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 7091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 7104103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 7114103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 7124dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien if (fields_class->GetDexCache() == mUnit->dex_cache_) { 7134103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 7144103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 7154103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 7164103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7174103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 718c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 7194103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 7204103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 721e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // Search dex file for localized ssb index, may fail if field's class is a parent 722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers // of the class mentioned in the dex file and there is no dex cache entry. 7231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 7241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 7254dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindStringId(descriptor); 7261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 7271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 7284dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id)); 729b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes if (type_id != NULL) { 7301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 7314dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id); 7321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 7331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 734c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 7351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 7361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 7421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 7431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 7441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 7451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 7461bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 747c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 7481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 7491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 7501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 7512ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogersvoid Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, Method* method, 7522ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers uintptr_t& direct_code, uintptr_t& direct_method) { 7532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 7542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 7552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (sharp_type != kStatic && sharp_type != kDirect) { 7562ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 7572ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7582ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL; 7592ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (!method_code_in_boot) { 7602ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 7612ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7622ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized(); 7632ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (has_clinit_trampoline) { 7642ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 7652ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7662ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->DirectCallsToBoot(type); 7672ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->DirectMethodsToBoot(type); 7683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 7693fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (compiling_boot) { 7700637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom const bool kSupportBootImageFixup = true; 7713fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (kSupportBootImageFixup) { 7723fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MethodHelper mh(method); 7733fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (IsImageClass(mh.GetDeclaringClassDescriptor())) { 7740637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // We can only branch directly to Methods that are resolved in the DexCache. 7750637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // Otherwise we won't invoke the resolution trampoline. 7763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = -1; 7770637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom direct_code = -1; 7783fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 7793fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 7803fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } else { 7813fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (Runtime::Current()->GetHeap()->GetImageSpace()->Contains(method)) { 7823fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = reinterpret_cast<uintptr_t>(method); 7833fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 7843fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_code = reinterpret_cast<uintptr_t>(method->GetCode()); 7852ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7862ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers} 7872ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 788fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type, 7892ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers int& vtable_idx, uintptr_t& direct_code, 7902ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers uintptr_t& direct_method) { 791a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 7922ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 7932ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 7944dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx); 795a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 7964dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 797a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class != NULL) { 798a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Class* methods_class = resolved_method->GetDeclaringClass(); 799a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 800a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 801996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 802a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 803a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 804a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // method public. Resort to the dex file to determine the correct class for the access check 8054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); 806a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers methods_class = 8074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_linker_->ResolveType(dex_file, 8084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien dex_file.GetMethodId(method_idx).class_idx_, 8094dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien referrer_class); 810a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 811a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 812a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers referrer_class->CanAccessMember(methods_class, 813a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers resolved_method->GetAccessFlags())) { 814a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 815f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers const bool kEnableSharpening = true; 8162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Sharpen a virtual call into a direct call when the target is known. 8172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() || 8182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers methods_class->IsFinal()); 8192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // ensure the vtable index will be correct to dispatch in the vtable of the super class 8204155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class && 8212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers referrer_class->IsSubClass(methods_class) && 8224155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao vtable_idx < methods_class->GetVTable()->GetLength() && 8234155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao methods_class->GetVTable()->Get(vtable_idx) == resolved_method); 8242ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (kEnableSharpening && can_sharpen) { 8252ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->ResolvedMethod(type); 826fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 827fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 828fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method) 829fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers << PrettyMethod(resolved_method); 8302ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->VirtualMadeDirect(type); 8312ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method); 832fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers type = kDirect; 833fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 8342ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else if (type == kSuper) { 8352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Unsharpened super calls are suspicious so go slowpath. 8362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else { 837c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 8382ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method); 839a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 840a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 841a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 842a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 843a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 844a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Clean up any exception left by method/type resolution 845a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Thread* thread = Thread::Current(); 846a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (thread->IsExceptionPending()) { 847a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers thread->ClearException(); 848a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 849c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedMethod(type); 850a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 851a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 852a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 853f582258f0e296223a091fd64231a203ad71e9649Brian Carlstromvoid Compiler::AddCodePatch(DexCache* dex_cache, 854f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom const DexFile* dex_file, 855f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 856f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_access_flags, 857f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 858f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom bool target_is_direct, 8593fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 8603fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MutexLock mu(compiled_methods_lock_); 861f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom code_to_patch_.push_back(new PatchInformation(dex_cache, 862f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom dex_file, 863f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 864f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_access_flags, 865f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 866f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_is_direct, 867f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 8683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 869f582258f0e296223a091fd64231a203ad71e9649Brian Carlstromvoid Compiler::AddMethodPatch(DexCache* dex_cache, 870f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom const DexFile* dex_file, 871f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 872f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_access_flags, 873f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 874f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom bool target_is_direct, 8753fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 8763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MutexLock mu(compiled_methods_lock_); 877f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom methods_to_patch_.push_back(new PatchInformation(dex_cache, 878f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom dex_file, 879f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 880f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_access_flags, 881f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 882f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_is_direct, 883f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 8843fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 8853fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers 8865ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// Return true if the class should be skipped during compilation. We 8875ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// never skip classes in the boot class loader. However, if we have a 8885ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// non-boot class loader and we can resolve the class in the boot 8895ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// class loader, we do skip the class. This happens if an app bundles 8905ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// classes found in the boot classpath. Since at runtime we will 8915ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// select the class from the boot classpath, do not attempt to resolve 8925ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// or compile it now. 8935ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstromstatic bool SkipClass(const ClassLoader* class_loader, 8945ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile& dex_file, 8955ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile::ClassDef& class_def) { 8965ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (class_loader == NULL) { 8975ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 8985ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 8995ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 9005ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 9015ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, NULL); 9025ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (klass == NULL) { 9035ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Thread* self = Thread::Current(); 9045ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom CHECK(self->IsExceptionPending()); 9055ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom self->ClearException(); 9065ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 9075ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 9085ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return true; 9095ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom} 9105ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom 911731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstromclass Context { 912731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public: 913731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context(ClassLinker* class_linker, 914731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* class_loader, 915731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* compiler, 916731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom DexCache* dex_cache, 917731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile* dex_file) 918731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom : class_linker_(class_linker), 919731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom class_loader_(class_loader), 920731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom compiler_(compiler), 921731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom dex_cache_(dex_cache), 922731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom dex_file_(dex_file) {} 923731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 924731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* GetClassLinker() { 925731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(class_linker_ != NULL); 926731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_linker_; 927731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 928731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* GetClassLoader() { 929731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_loader_; 930731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 931731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* GetCompiler() { 932731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(compiler_ != NULL); 933731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return compiler_; 934731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 935731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom DexCache* GetDexCache() { 936731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_cache_ != NULL); 937731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_cache_; 938731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 939731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile* GetDexFile() { 940731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_file_ != NULL); 941731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_file_; 942731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 943731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 944731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom private: 945731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker_; 946731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* class_loader_; 947731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* compiler_; 948731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom DexCache* dex_cache_; 949731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile* dex_file_; 950d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 9519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 952d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughestypedef void Callback(Context* context, size_t index); 953d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 954d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesclass WorkerThread { 955d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes public: 9561e4092589f1400915e6213014da103aab8728ef6Elliott Hughes WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe, bool spawn) 9571e4092589f1400915e6213014da103aab8728ef6Elliott Hughes : spawn_(spawn), context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) { 9581e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 9591e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread"); 9601e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 961d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 962d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 963d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ~WorkerThread() { 9641e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 9651e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown"); 9661e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 967d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 968d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 969d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 9701e4092589f1400915e6213014da103aab8728ef6Elliott Hughes static void* Go(void* arg) { 971d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg); 972d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Runtime* runtime = Runtime::Current(); 9731e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 974462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes runtime->AttachCurrentThread("Compiler Worker", true, NULL); 9751e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 97634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes Thread::Current()->SetState(kRunnable); 977d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes worker->Run(); 9781e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 97934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes Thread::Current()->SetState(kNative); 9801e4092589f1400915e6213014da103aab8728ef6Elliott Hughes runtime->DetachCurrentThread(); 9811e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 982d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return NULL; 983d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 984d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 9851e4092589f1400915e6213014da103aab8728ef6Elliott Hughes void Go() { 9861e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Go(this); 9871e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 9881e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 989d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes void Run() { 99064277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom Thread* self = Thread::Current(); 991d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t i = begin_; i < end_; i += stripe_) { 992d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes callback_(context_, i); 99364277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException()) << " " << i; 994aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 9959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 9969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 997d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes pthread_t pthread_; 9981e4092589f1400915e6213014da103aab8728ef6Elliott Hughes bool spawn_; 999d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1000d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context* context_; 1001d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t begin_; 1002d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t end_; 1003d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Callback* callback_; 1004d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t stripe_; 10051e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 10061e4092589f1400915e6213014da103aab8728ef6Elliott Hughes friend void ForAll(Context*, size_t, size_t, Callback, size_t); 1007d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 1008d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 10095523ee070b005576c6f889415205d49ea77cf243Elliott Hughesvoid ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) { 101064277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom Thread* self = Thread::Current(); 101164277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException()); 10121e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_GT(thread_count, 0U); 1013845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 10141e4092589f1400915e6213014da103aab8728ef6Elliott Hughes std::vector<WorkerThread*> threads; 101581d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes for (size_t i = 0; i < thread_count; ++i) { 10161e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count, (i != 0))); 1017d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 10181e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads[0]->Go(); 1019d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 102081d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes // Switch to kVmWait while we're blocked waiting for the other threads to finish. 102134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes ScopedThreadStateChange tsc(self, kVmWait); 102281d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes STLDeleteElements(&threads); 102381d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes} 1024d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1025d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) { 1026731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile& dex_file = *context->GetDexFile(); 1027d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1028845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 1029845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 1030845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 1031845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 1032845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 1033845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 1034845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 1035d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1036731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom if (SkipClass(context->GetClassLoader(), dex_file, class_def)) { 1037d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1038d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1039845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 1040d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 1041d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 1042d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 1043d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 1044d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 1045d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 1046d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1047d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1048d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1049731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = context->GetClassLinker(); 1050d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1051d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 1052d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 1053d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 1054731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), true); 1055d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1056d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1057d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 10580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1059d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1060d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1061d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 1062d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 1063731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), false); 1064d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1065d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1066d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 106720cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1068d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1069d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1070d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 1071d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1072731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), true); 1073d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1074d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1075d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1076845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1077d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1078d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1079d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 1080d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1081731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), false); 1082d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1083d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1084d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1085845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1086d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1087d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1088d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 1089d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1090d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1091d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveType(Context* context, size_t type_idx) { 1092d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 1093d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1094731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Class* klass = context->GetClassLinker()->ResolveType(*context->GetDexFile(), 1095731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom type_idx, 1096731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetDexCache(), 1097731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader()); 1098d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 1099d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1100d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1101d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1102d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1103d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1104d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) { 1105d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1106d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1107d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1108d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Strings are easy in that they always are simply resolved to literals in the same file 1109d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (image_ && image_classes_ == NULL) { 1110d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // TODO: Add support for loading strings referenced by image_classes_ 1111d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // See also Compiler::CanAssumeTypeIsPresentInDexCache. 1112d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 1113d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes class_linker->ResolveString(dex_file, string_idx, dex_cache); 111420cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1115ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings"); 11169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 1117d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1118731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context context(class_linker, class_loader, this, dex_cache, &dex_file); 11195523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_); 1120ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 1121d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 11225523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 1123ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 11249ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 11259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1126ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Verify(const ClassLoader* class_loader, 1127ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 1128ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1129ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 113098eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 113198eacac683b78e60799323e8c7d59e7214808639jeffhao VerifyDexFile(class_loader, *dex_file); 113298eacac683b78e60799323e8c7d59e7214808639jeffhao } 113398eacac683b78e60799323e8c7d59e7214808639jeffhao} 113498eacac683b78e60799323e8c7d59e7214808639jeffhao 1135d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void VerifyClass(Context* context, size_t class_def_index) { 1136731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 1137731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def); 1138731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Class* klass = context->GetClassLinker()->FindClass(descriptor, context->GetClassLoader()); 1139d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 1140d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1141d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1142d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1143f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao 1144f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao /* 1145f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * At compile time, we can still structurally verify the class even if FindClass fails. 1146f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * This is to ensure the class is structurally sound for compilation. An unsound class 1147f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * will be rejected by the verifier and later skipped during compilation in the compiler. 1148f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao */ 1149f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao std::string error_msg; 1150776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (!verifier::MethodVerifier::VerifyClass(context->GetDexFile(), context->GetDexCache(), 1151731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), class_def_index, error_msg)) { 1152731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 1153f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao LOG(ERROR) << "Verification failed on class " 1154731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom << PrettyDescriptor(context->GetDexFile()->GetClassDescriptor(class_def)) 1155f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << " because: " << error_msg; 1156f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao } 1157d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1158d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1159d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 1160731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLinker()->VerifyClass(klass); 1161d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1162d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 1163d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 1164d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 1165d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 11661ac29447d6053b142f257330d6e237660076911ejeffhao art::Compiler::ClassReference ref(context->GetDexFile(), class_def_index); 1167776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (!verifier::MethodVerifier::IsClassRejected(ref)) { 11681ac29447d6053b142f257330d6e237660076911ejeffhao // If the erroneous class wasn't rejected by the verifier, it was a soft error. We want 11691ac29447d6053b142f257330d6e237660076911ejeffhao // to try verification again at run-time, so move back into the resolved state. 11701ac29447d6053b142f257330d6e237660076911ejeffhao klass->SetStatus(Class::kStatusResolved); 11711ac29447d6053b142f257330d6e237660076911ejeffhao } 1172d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1173d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 11741ac29447d6053b142f257330d6e237660076911ejeffhao CHECK(klass->IsVerified() || klass->IsResolved() || klass->IsErroneous()) << PrettyClass(klass); 1175d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 1176d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1177d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 117898eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1179b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ | PROT_WRITE); 1180d9cdfe91a4812a86d90a139569eac18e2b6de3fbElliott Hughes 1181731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1182731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context context(class_linker, class_loader, this, class_linker->FindDexCache(dex_file), &dex_file); 11835523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 1184d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1185b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ); 1186a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1187a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 1188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, 1189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 1190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1192a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(dex_file != NULL); 1193a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader, *dex_file); 1194a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 1195a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1196a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 1197a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 1198a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1199ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 1200ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1201a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1202a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 120327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass != NULL) { 12041ac29447d6053b142f257330d6e237660076911ejeffhao if (klass->IsVerified()) { 12051ac29447d6053b142f257330d6e237660076911ejeffhao // Only try to initialize classes that were successfully verified. 12060045a290e6b79a274250e3112880c04bde437d4aIan Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 12070045a290e6b79a274250e3112880c04bde437d4aIan Rogers bool can_init_static_fields = compiling_boot && 12080045a290e6b79a274250e3112880c04bde437d4aIan Rogers IsImageClass(descriptor); 12090045a290e6b79a274250e3112880c04bde437d4aIan Rogers class_linker->EnsureInitialized(klass, false, can_init_static_fields); 12101ac29447d6053b142f257330d6e237660076911ejeffhao } 12110755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom // record the final class status if necessary 12120755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom Class::Status status = klass->GetStatus(); 12130755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassReference ref(&dex_file, class_def_index); 1214c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 12150755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CompiledClass* compiled_class = GetCompiledClass(ref); 12160755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (compiled_class == NULL) { 12170755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_class = new CompiledClass(status); 1218a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes compiled_classes_.Put(ref, compiled_class); 12190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } else { 12200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK_EQ(status, compiled_class->GetStatus()); 12210755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 122227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 122327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // clear any class not found or verification exceptions 122427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 1225ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 1226ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom 1227ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1228ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 1229ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 123027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass == NULL) { 123127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 123227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } else if (klass->IsInitialized()) { 1233ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 1234ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 123598eacac683b78e60799323e8c7d59e7214808639jeffhao } 123698eacac683b78e60799323e8c7d59e7214808639jeffhao} 123798eacac683b78e60799323e8c7d59e7214808639jeffhao 123890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao// TODO: This class shares some implementation with WorkerThread. We don't want 123990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao// to perturb the non-LLVM side at the same time. Staging the refactoring for 124090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao// the future. 124190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liaoclass DexFilesWorkerThread { 124290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao public: 124390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao DexFilesWorkerThread(Context *worker_context, Callback class_callback, 124490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao const std::vector<const DexFile*>& dex_files, 124590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao volatile int32_t* shared_class_index, bool spawn) 124690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao : spawn_(spawn), worker_context_(worker_context), 124790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao class_callback_(class_callback), dex_files_(dex_files), 124890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao context_(NULL), shared_class_index_(shared_class_index) { 124990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (spawn_) { 125090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread"); 125190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 125290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 125390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 125490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao ~DexFilesWorkerThread() { 125590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (spawn_) { 125690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown"); 125790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 125890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao delete context_; 125990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 126090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 126190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao private: 126290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao static void* Go(void* arg) { 126390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao DexFilesWorkerThread* worker = reinterpret_cast<DexFilesWorkerThread*>(arg); 126490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Runtime* runtime = Runtime::Current(); 126590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (worker->spawn_) { 126690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao runtime->AttachCurrentThread("Compiler Worker", true, NULL); 126790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 126890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Thread::Current()->SetState(kRunnable); 126990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao worker->Run(); 127090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (worker->spawn_) { 127190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Thread::Current()->SetState(kNative); 127290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao runtime->DetachCurrentThread(); 127390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 127490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao return NULL; 127590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 127690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 127790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao void Go() { 127890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Go(this); 127990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 128090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 128190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao void SwitchToDexFile(size_t dex_file_index) { 128290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK (dex_file_index < dex_files_.size()); 128390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 128490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao const DexFile* dex_file = dex_files_[dex_file_index]; 128590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(dex_file != NULL); 128690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 128790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao // Destroy the old context 128890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao delete context_; 128990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 129090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao // TODO: Add a callback to let the client specify the class_linker and 129190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao // dex_cache in the context for the current working dex file. 129290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao context_ = new Context(/* class_linker */NULL, 129390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao worker_context_->GetClassLoader(), 129490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao worker_context_->GetCompiler(), 129590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao /* dex_cache */NULL, dex_file); 129690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 129790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(context_ != NULL); 129890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 129990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 130090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao void Run() { 130190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Thread* self = Thread::Current(); 130290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao size_t cur_dex_file_index = 0; 130390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao size_t class_index_base = 0; 130490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 130590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao SwitchToDexFile(0); 130690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 130790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao while (true) { 130890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao size_t class_index = 130990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao static_cast<size_t>(android_atomic_inc(shared_class_index_)); 131090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 131190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao const DexFile* dex_file; 131290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao do { 131390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao dex_file = dex_files_[cur_dex_file_index]; 131490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 131590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (class_index < (class_index_base + dex_file->NumClassDefs())) { 131690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao break; 131790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 131890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao class_index_base += dex_file->NumClassDefs(); 131990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 132090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao cur_dex_file_index++; 132190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } while (cur_dex_file_index < dex_files_.size()); 132290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 132390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (cur_dex_file_index >= dex_files_.size()) { 132490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao return; 132590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 132690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 132790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (dex_file != context_->GetDexFile()) { 132890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao SwitchToDexFile(cur_dex_file_index); 132990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 133090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 133190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao class_index -= class_index_base; 133290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao class_callback_(context_, class_index); 133390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException()); 133490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 133590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 133690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 133790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao pthread_t pthread_; 133890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao bool spawn_; 133990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 134090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Context* worker_context_; 134190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Callback* class_callback_; 134290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao const std::vector<const DexFile*>& dex_files_; 134390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 134490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Context* context_; 134590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao volatile int32_t* shared_class_index_; 134690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 134790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao friend void ForClassesInAllDexFiles(Context*, 134890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao const std::vector<const DexFile*>&, 134990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Callback, size_t); 135090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao}; 135190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 135290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liaovoid ForClassesInAllDexFiles(Context* worker_context, 135390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao const std::vector<const DexFile*>& dex_files, 135490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Callback class_callback, size_t thread_count) { 135590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Thread* self = Thread::Current(); 135690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException()); 135790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao CHECK_GT(thread_count, 0U); 135890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 135990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao std::vector<DexFilesWorkerThread*> threads; 136090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao volatile int32_t shared_class_index = 0; 136190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 136290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao for (size_t i = 0; i < thread_count; ++i) { 136390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao threads.push_back(new DexFilesWorkerThread(worker_context, class_callback, 136490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao dex_files, &shared_class_index, 136590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao /* spawn */ (i != 0))); 136690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 136790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao threads[0]->Go(); 136890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 136990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao // Switch to kVmWait while we're blocked waiting for the other threads to finish. 137090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao ScopedThreadStateChange tsc(self, kVmWait); 137190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao STLDeleteElements(&threads); 137290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao} 137390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao 1374ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader, 1375ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 137690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 137790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao if (dex_files.size() <= 0) { 137890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao return; // No dex file 137990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao } 138090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao Context context(NULL, class_loader, this, NULL, NULL); 138190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao ForClassesInAllDexFiles(&context, dex_files, Compiler::CompileClass, thread_count_); 138290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao#else 1383ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1384ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 138583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 138683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CompileDexFile(class_loader, *dex_file); 138783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 138890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao#endif 138983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 139083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 1391c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileClass(Context* context, size_t class_def_index) { 1392731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* class_loader = context->GetClassLoader(); 1393731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile& dex_file = *context->GetDexFile(); 1394c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 13955ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (SkipClass(class_loader, dex_file, class_def)) { 13965ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return; 13975ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 1398d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 1399d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 1400776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (verifier::MethodVerifier::IsClassRejected(ref)) { 1401d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 1402d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 14030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 14040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 14050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 14060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 14070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 14080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 14090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 14100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 14110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 14120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 14130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 14140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 14150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 14160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 14170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 1418731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1419731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom it.GetMemberIndex(), class_loader, dex_file); 14200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 14219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 14220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 14230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 1424731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1425731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom it.GetMemberIndex(), class_loader, dex_file); 14260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 14279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 14280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 14299ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 14309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1431c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1432731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context context(NULL, class_loader, this, NULL, &dex_file); 14335523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_); 1434c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1435c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 1436a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 1437a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes std::string key(shorty); 1438a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes if (is_static) { 1439a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes key += "$"; // Must not be a shorty type character. 1440a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 1441a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes return key; 1442a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes} 1443a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes 1444a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 1445a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers uint32_t method_idx, const ClassLoader* class_loader, 1446a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile& dex_file) { 1447f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1448bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 14494dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1450169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 145157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file); 14523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1453169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 14542cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 1455b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiled_method = (*compiler_)(*this, code_item, access_flags, method_idx, class_loader, 1456b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dex_file); 1457bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1458bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 14593bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 14605abfa3ea35781464df8fae60aaf03f48a295e965buzbee if (duration_ns > MsToNs(100)) { 1461bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 14623bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1463f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1464f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 1465f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 14660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 14670755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 1468c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 1469a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes compiled_methods_.Put(ref, compiled_method); 14700755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 14712cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 14729baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 147345619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers uint32_t shorty_len; 147445619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); 1475169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 1476a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 1477a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key); 14780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 1479c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len); 14800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 1481a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes InsertInvokeStub(key, compiled_invoke_stub); 14823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 14830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file); 14840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 148528ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 1486a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const { 1487a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 1488a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes return FindInvokeStub(key); 14893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 14903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1491a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(const std::string& key) const { 1492c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 14930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 14940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 14953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 14960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 14970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 14980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 14993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 15003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 15013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 1502a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesvoid Compiler::InsertInvokeStub(const std::string& key, 15030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub) { 1504c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1505a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key); 1506a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes if (it != compiled_invoke_stubs_.end()) { 1507a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes // Someone else won the race. 1508a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes delete compiled_invoke_stub; 1509a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } else { 1510a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes compiled_invoke_stubs_.Put(key, compiled_invoke_stub); 1511a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 15120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 15130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 15140755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const { 1515c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 15160755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 15170755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 15180755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 15190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 15200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 15210755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 15220755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 15230755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 15240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const { 1525c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 15260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 15270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 15283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 15292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 15303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 15313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 15329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 15339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1534e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) { 1535e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1536e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1537e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CHECK(dex_file != NULL); 1538e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsDexFile(class_loader, *dex_file); 1539e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1540e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1541e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1542e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1543e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1544e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1545e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 1546e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1547e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1548e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 1549e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (klass == NULL || !klass->IsVerified()) { 1550e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1551e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1552e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1553e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1554e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (class_data == NULL) { 1555e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom // empty class such as a marker interface 1556e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1557e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1558e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassDataItemIterator it(dex_file, class_data); 1559e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextStaticField()) { 1560e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1561e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1562e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextInstanceField()) { 1563e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1564e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1565e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextDirectMethod()) { 1566e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1567e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, true); 1568e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1569e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1570e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1571e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextVirtualMethod()) { 1572e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1573e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, false); 1574e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1575e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1576e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1577e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1578e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1579e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1580e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) { 1581e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (method == NULL) { 1582e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1583e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1584e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1585e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint16_t method_idx = method->GetDexMethodIndex(); 1586e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom MethodReference ref(&dex_file, method_idx); 1587e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CompiledMethod* compiled_method = GetCompiledMethod(ref); 1588e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (compiled_method == NULL) { 1589e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1590e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1591776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers const std::vector<uint8_t>* gc_map = verifier::MethodVerifier::GetGcMap(ref); 1592e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (gc_map == NULL) { 1593e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1594e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1595e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom compiled_method->SetGcMap(*gc_map); 1596e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1597e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 15988b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#if defined(ART_USE_LLVM_COMPILER) 15998b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) { 1600106b2a03be66748a25b9019e4c222cee498d559fLogan Chien typedef void (*SetBitcodeFileNameFn)(Compiler&, std::string const&); 1601106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1602106b2a03be66748a25b9019e4c222cee498d559fLogan Chien SetBitcodeFileNameFn set_bitcode_file_name = 1603106b2a03be66748a25b9019e4c222cee498d559fLogan Chien FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(instruction_set_), 1604106b2a03be66748a25b9019e4c222cee498d559fLogan Chien compiler_library_, 1605106b2a03be66748a25b9019e4c222cee498d559fLogan Chien "compilerLLVMSetBitcodeFileName"); 1606106b2a03be66748a25b9019e4c222cee498d559fLogan Chien 1607106b2a03be66748a25b9019e4c222cee498d559fLogan Chien set_bitcode_file_name(*this, filename); 16088b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 1609f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 1610f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chienvoid Compiler::EnableAutoElfLoading() { 1611f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien compiler_enable_auto_elf_loading_(*this); 1612f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien} 1613f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 1614f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chienconst void* Compiler::GetMethodCodeAddr(const CompiledMethod* cm, 1615f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien const Method* method) const { 1616f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien return compiler_get_method_code_addr_(*this, cm, method); 1617f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien} 1618f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien 1619f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chienconst Method::InvokeStub* Compiler::GetMethodInvokeStubAddr(const CompiledInvokeStub* cm, 1620f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien const Method* method) const { 1621f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien return compiler_get_method_invoke_stub_addr_(*this, cm, method); 1622f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien} 1623df57614aa99801a50202e284ee8e8497d8e92621Logan Chien 1624df57614aa99801a50202e284ee8e8497d8e92621Logan Chienstd::vector<ElfImage> Compiler::GetElfImages() const { 1625df57614aa99801a50202e284ee8e8497d8e92621Logan Chien typedef std::vector<ElfImage> (*GetElfImagesFn)(const Compiler&); 1626df57614aa99801a50202e284ee8e8497d8e92621Logan Chien 1627df57614aa99801a50202e284ee8e8497d8e92621Logan Chien GetElfImagesFn get_elf_images = 1628df57614aa99801a50202e284ee8e8497d8e92621Logan Chien FindFunction<GetElfImagesFn>(MakeCompilerSoName(instruction_set_), 1629df57614aa99801a50202e284ee8e8497d8e92621Logan Chien compiler_library_, 1630df57614aa99801a50202e284ee8e8497d8e92621Logan Chien "compilerLLVMGetElfImages"); 1631df57614aa99801a50202e284ee8e8497d8e92621Logan Chien 1632df57614aa99801a50202e284ee8e8497d8e92621Logan Chien return get_elf_images(*this); 1633df57614aa99801a50202e284ee8e8497d8e92621Logan Chien} 16348b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#endif 16358b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 16369ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1637