compiler_driver.cc revision ba0668ecd2a6459ed7c77012995ad08d27f88725
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 252cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom#include "assembler.h" 269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 271f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h" 289ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "dex_cache.h" 29f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao#include "dex_verifier.h" 309baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 314dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#include "oat_compilation_unit.h" 323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 336d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 341f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 35b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include "space.h" 363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "stl_util.h" 37601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes#include "timing_logger.h" 389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 39059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 40059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#include <mach-o/dyld.h> 41059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 42059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 45c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm { 46bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 471cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type); 488add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 49c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 50c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 { 51bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 521cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type); 538add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 56996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic double Percentage(size_t x, size_t y) { 57996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return 100.0 * ((double)x) / ((double)(x + y)); 58996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 59996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 60996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic void DumpStat(size_t x, size_t y, const char* str) { 61996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (x == 0 && y == 0) { 62996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return; 63996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 64996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases"; 65996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 66996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 67c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersclass AOTCompilationStats { 68c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers public: 69c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"), 70c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_(0), types_not_in_dex_cache_(0), 71c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_(0), strings_not_in_dex_cache_(0), 72c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_(0), unresolved_types_(0), 73c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_(0), unresolved_instance_fields_(0), 742ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0) { 752ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 76c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[i] = 0; 77c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[i] = 0; 782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[i] = 0; 792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[i] = 0; 802ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[i] = 0; 812ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void Dump() { 85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache"); 86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache"); 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_types_, unresolved_types_, "types resolved"); 88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); 89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, 90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields resolved"); 91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_, 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields local to a class"); 93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 942ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers for (size_t i = 0; i <= kMaxInvokeType; i++) { 95c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers std::ostringstream oss; 962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss << static_cast<InvokeType>(i) << " methods were AOT resolved"; 97c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str()); 982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (virtual_made_direct_[i] > 0) { 992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " methods made direct"; 1012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(virtual_made_direct_[i], 1022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i], 1032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_calls_to_boot_[i] > 0) { 1062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot"; 1082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_calls_to_boot_[i], 1092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i], 1102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (direct_methods_to_boot_[i] > 0) { 1132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers std::ostringstream oss2; 1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot"; 1152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DumpStat(direct_methods_to_boot_[i], 1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i], 1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers oss2.str().c_str()); 1182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 119c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 120c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 121996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 122996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers// Allow lossy statistics in non-debug builds 123996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG 124996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() MutexLock mu(stats_lock_) 125996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else 126996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() 127996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif 128996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeInDexCache() { 130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_++; 132c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 133996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNotInDexCache() { 135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_not_in_dex_cache_++; 137c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 138996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringInDexCache() { 140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_++; 142c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 143996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringNotInDexCache() { 145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_not_in_dex_cache_++; 147c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 148996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeDoesntNeedAccessCheck() { 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_++; 152c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 153996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNeedsAccessCheck() { 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_types_++; 157c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 158996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedInstanceField() { 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_++; 162c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 163996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedInstanceField(){ 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_instance_fields_++; 167c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 168996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedLocalStaticField() { 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_local_static_fields_++; 172c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 173996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedStaticField() { 175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_static_fields_++; 177c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 178996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedStaticField() { 180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_static_fields_++; 182c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 183996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedMethod(InvokeType type) { 185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 186c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 187c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[type]++; 188996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 189996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 190c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedMethod(InvokeType type) { 191c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 192c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 193c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[type]++; 194996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 195c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 1962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void VirtualMadeDirect(InvokeType type) { 1972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 1982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 1992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers virtual_made_direct_[type]++; 2002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 2022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectCallsToBoot(InvokeType type) { 2032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 2042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers STATS_LOCK(); 2052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_calls_to_boot_[type]++; 2062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 2072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 2082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers void DirectMethodsToBoot(InvokeType type) { 2092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers DCHECK_LE(type, kMaxInvokeType); 210fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers STATS_LOCK(); 2112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_methods_to_boot_[type]++; 212fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } 2132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private: 215c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Mutex stats_lock_; 216c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 217c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_in_dex_cache_; 218c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_not_in_dex_cache_; 219c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 220c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_in_dex_cache_; 221c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_not_in_dex_cache_; 222c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 223c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_types_; 224c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_types_; 225c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 226c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_instance_fields_; 227c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_instance_fields_; 228c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 229c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_local_static_fields_; 230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_static_fields_; 231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_static_fields_; 232c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_methods_[kMaxInvokeType + 1]; 234c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_methods_[kMaxInvokeType + 1]; 2352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t virtual_made_direct_[kMaxInvokeType + 1]; 2362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_calls_to_boot_[kMaxInvokeType + 1]; 2372ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers size_t direct_methods_to_boot_[kMaxInvokeType + 1]; 238c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 239c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);; 240c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}; 241996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 242b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughesstatic std::string MakeCompilerSoName(InstructionSet instruction_set) { 243b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes // TODO: is the ARM/Thumb2 instruction set distinction really buying us anything, 244b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes // or just causing hassle like this? 245b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (instruction_set == kThumb2) { 246b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes instruction_set = kArm; 247b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 248b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 249059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Capitalize the instruction set, because that's what we do in the build system. 250b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes std::ostringstream instruction_set_name_os; 251b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes instruction_set_name_os << instruction_set; 252b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes std::string instruction_set_name(instruction_set_name_os.str()); 253b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes for (size_t i = 0; i < instruction_set_name.size(); ++i) { 254b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes instruction_set_name[i] = toupper(instruction_set_name[i]); 255b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 257059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Bad things happen if we pull in the libartd-compiler to a libart dex2oat or vice versa, 258059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // because we end up with both libart and libartd in the same address space! 259b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#ifndef NDEBUG 260b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes const char* suffix = "d"; 261b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#else 262b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes const char* suffix = ""; 263b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#endif 264059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 265059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Work out the filename for the compiler library. 266c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#if !defined(ART_USE_LLVM_COMPILER) 267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string library_name(StringPrintf("art%s-compiler-%s", suffix, instruction_set_name.c_str())); 268c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#else 269c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao std::string library_name(StringPrintf("art%s-compiler-llvm", suffix)); 270c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#endif 271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str())); 272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 273059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__) 274059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find 275059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the 276059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // same work. 277059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::vector<char> executable_path(1); 278059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes uint32_t executable_path_length = 0; 279059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes _NSGetExecutablePath(&executable_path[0], &executable_path_length); 280059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes while (_NSGetExecutablePath(&executable_path[0], &executable_path_length) == -1) { 281059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes executable_path.resize(executable_path_length); 282059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes } 283059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 284059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes executable_path.resize(executable_path.size() - 1); // Strip trailing NUL. 285059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes std::string path(&executable_path[0]); 286059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 287059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/dex2oat". 288059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes size_t last_slash = path.find_last_of('/'); 289059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes CHECK_NE(last_slash, std::string::npos) << path; 290059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 291059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 292059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes // Strip the "/bin". 293059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes last_slash = path.find_last_of('/'); 294059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes path.resize(last_slash); 295059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes 296059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes filename = path + "/lib/" + filename; 297059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif 298059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes return filename; 299b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 300b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 30146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn> 30246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) { 30346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes Fn fn = reinterpret_cast<Fn>(dlsym(library, name)); 30446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes if (fn == NULL) { 30546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror(); 30646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes } 307059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn); 30846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes return fn; 30946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes} 31046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes 3115523ee070b005576c6f889415205d49ea77cf243Elliott HughesCompiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count, 312ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom bool support_debugging, const std::set<std::string>* image_classes, 313ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom bool dump_stats, bool dump_timings) 314aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom : instruction_set_(instruction_set), 315c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 316c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 317c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 318aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 3195523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 320de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 321c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 322ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_stats_(dump_stats), 323ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom dump_timings_(dump_timings), 324b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes image_classes_(image_classes), 325b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_(NULL), 32646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes compiler_(NULL), 3276f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes compiler_context_(NULL), 32846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_(NULL), 32946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes create_invoke_stub_(NULL) 330b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes{ 331c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao std::string compiler_so_name(MakeCompilerSoName(instruction_set_)); 332b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY); 333b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ == NULL) { 334b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror(); 335b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 336b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_; 337b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 3383fa1b7e7a7fc9785ba4e8335d730e5caf6343322Elliott Hughes compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod"); 33946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtJniCompileMethod"); 34046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes create_invoke_stub_ = FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateInvokeStub"); 341b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 34225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 343ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 344ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 345ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 346c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 347c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 3483320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() { 349c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 350c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 351c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 352c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 353c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 354c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 355c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 356c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 357c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 358c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 359c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 360bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 361f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 362f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom MutexLock mu(compiled_methods_lock_); 363f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&code_to_patch_); 364f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 365f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom { 366f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom MutexLock mu(compiled_methods_lock_); 367f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom STLDeleteElements(&methods_to_patch_); 368f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom } 369c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 370c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_), 371c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiler_library_, 372c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao "compilerLLVMDispose"); 373c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao (*f)(*this); 374c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#endif 375b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (compiler_library_ != NULL) { 376b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes VLOG(compiler) << "dlclose(" << compiler_library_ << ")"; 377b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dlclose(compiler_library_); 378b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 3793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 3803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 3811cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, 3821cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type) { 383ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 3841cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return x86::X86CreateResolutionTrampoline(type); 385ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 386ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 387ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 3881cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return arm::ArmCreateResolutionTrampoline(type); 389ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 390ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 391ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 3928add92dcf59568c72c17e9a979948b1a7a0b1264Elliott HughesByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 393169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 394169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 395169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 3968add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 397169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 3988add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 399169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 40049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 401169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 402169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 403169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 404169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 405ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan RogersByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 406ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 407ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return x86::CreateAbstractMethodErrorStub(); 408ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 409ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 410ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 411ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return arm::CreateAbstractMethodErrorStub(); 412ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 413ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 414ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 415254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilsonvoid Compiler::CompileAll(const ClassLoader* class_loader, 416ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 41725c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 418ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 419601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("compiler"); 420601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 421601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 422601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 423ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Compile(class_loader, dex_files); 424601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("Compile"); 425601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 426ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 427601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PostCompile"); 428601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 429ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) { 430601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.Dump(); 431601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 432996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 433ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom if (dump_stats_) { 434ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom stats_->Dump(); 435ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom } 4368a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 4378a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 4383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromvoid Compiler::CompileOne(const Method* method) { 43925c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 440ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4418a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 442ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4430571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Find the dex_file 4440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 4450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); 446ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 447ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(&dex_file); 448ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 449601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("CompileOne"); 450601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 451ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 453a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset()); 454a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file); 455ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 456ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 4579ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 4589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 459ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader, 460d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 461ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 462ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 4639ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 464d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ResolveDexFile(class_loader, *dex_file, timings); 4659ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 4669ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 4679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 468ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PreCompile(const ClassLoader* class_loader, 469601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 470d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Resolve(class_loader, dex_files, timings); 471601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 472ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Verify(class_loader, dex_files); 473601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.Verify"); 474601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom InitializeClassesWithoutClinit(class_loader, dex_files); 476601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.InitializeClassesWithoutClinit"); 477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 478ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 479ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PostCompile(const ClassLoader* class_loader, 480ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 481e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMaps(class_loader, dex_files); 482d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 483c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_), 484c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiler_library_, 485c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao "compilerLLVMMaterializeRemainder"); 486c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao (*f)(*this); 487d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 489ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const { 491ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 492ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 493ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 494ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 495ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 496ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 4976d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, 498996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 4996d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 500c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5016d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5026d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 5031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5046d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 505c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 5066d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 5076d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 508996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 509996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 510c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 511996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 512c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 513996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 514996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 5166d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 5171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache, 518996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t string_idx) { 5191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // TODO: Add support for loading strings referenced by image_classes_ 5201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 5211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // The following is a test saying that if we're building the image without a restricted set of 5231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // image classes then we can assume the string is present in the dex cache if it is there now 524996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL; 525996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 526c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 527996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 528c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 529996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 530996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache, 534996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers const DexFile& dex_file, uint32_t type_idx) { 5351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 5361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 538c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 5401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 5421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 5431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 544c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 5461bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 5481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 549996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 550996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 551c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 552996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 553c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 554996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 555996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 5591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexCache* dex_cache, 5601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile& dex_file, 561996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 5621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 5631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 5641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 565c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 5671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 5691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 5701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 571c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 5721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 5731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 5751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 576996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 577996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 578c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 579996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 580c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 581996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 582996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 5831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5841bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5854dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Class* ComputeReferrerClass(OatCompilationUnit* mUnit) { 5864dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile::MethodId& referrer_method_id = 5874dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->GetMethodId(mUnit->method_idx_); 588a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 5894dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveType( 5904dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, referrer_method_id.class_idx_, 5914dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_cache_, mUnit->class_loader_); 5924dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 593a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 5944dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) { 5954dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveField( 5964dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, field_idx, mUnit->dex_cache_, 5974dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, false); 598a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 599a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6004dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) { 6014dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveMethod( 6024dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, method_idx, mUnit->dex_cache_, 6034dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, true); 604a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 605a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6064dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 6078cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao int& field_offset, bool& is_volatile, bool is_put) { 6081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 6091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 6101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 6111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 6124dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 6131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 6144dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 6151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve referring class then access check, failure to pass the 6161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* fields_class = resolved_field->GetDeclaringClass(); 6178cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 6188cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao fields_class != referrer_class; 6198cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (referrer_class != NULL && referrer_class->CanAccess(fields_class) && 6208cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) && 6218cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao !is_write_to_final_from_wrong_class) { 6221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 6231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 624c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedInstanceField(); 6251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // Fast path. 6261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 6291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 6301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 6311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 6321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 633c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 6341bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 6351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 6361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 6374dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 6381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers int& field_offset, int& ssb_index, 6398cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool& is_referrers_class, bool& is_volatile, bool is_put) { 6401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 6411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 6421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 6431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 6441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 6451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 6464dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 6471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 648a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers DCHECK(resolved_field->IsStatic()); 6494dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 6501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 6518cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao Class* fields_class = resolved_field->GetDeclaringClass(); 6528cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 6531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 6541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 6551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 656c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 6571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 6598cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class->CanAccess(fields_class) && 6618cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) && 6628cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao !is_write_to_final_from_wrong_class) { 6631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 6641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 6654103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 6664103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 6674dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien if (fields_class->GetDexCache() == mUnit->dex_cache_) { 6684103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 6694103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 6704103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 6714103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 6724103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 673c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 6744103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 6754103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 6764103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // Search dex file for localized ssb index 6771bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 6781bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 6794dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindStringId(descriptor); 6801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 6811bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 6824dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id)); 6831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if(type_id != NULL) { 6841bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 6854dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id); 6861bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 6871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 688c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 6891bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 6901bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6931bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6941bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6951bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 6961bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 6971bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 6981bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 6991bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 7001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 701c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 7021bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 7031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 7041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 7052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogersvoid Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, Method* method, 7062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers uintptr_t& direct_code, uintptr_t& direct_method) { 7072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 7082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 7092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (sharp_type != kStatic && sharp_type != kDirect) { 7102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 7112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL; 7132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (!method_code_in_boot) { 7142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 7152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized(); 7172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (has_clinit_trampoline) { 7182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return; 7192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7202ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->DirectCallsToBoot(type); 7212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->DirectMethodsToBoot(type); 7223fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; 7233fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (compiling_boot) { 7240637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom const bool kSupportBootImageFixup = true; 7253fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (kSupportBootImageFixup) { 7263fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MethodHelper mh(method); 7273fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (IsImageClass(mh.GetDeclaringClassDescriptor())) { 7280637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // We can only branch directly to Methods that are resolved in the DexCache. 7290637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom // Otherwise we won't invoke the resolution trampoline. 7303fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = -1; 7310637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom direct_code = -1; 7323fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 7333fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 7343fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } else { 7353fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers if (Runtime::Current()->GetHeap()->GetImageSpace()->Contains(method)) { 7363fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_method = reinterpret_cast<uintptr_t>(method); 7373fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers } 7383fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers direct_code = reinterpret_cast<uintptr_t>(method->GetCode()); 7392ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 7402ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers} 7412ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 742fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type, 7432ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers int& vtable_idx, uintptr_t& direct_code, 7442ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers uintptr_t& direct_method) { 745a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 7462ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_code = 0; 7472ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers direct_method = 0; 7484dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx); 749a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 7504dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 751a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class != NULL) { 752a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Class* methods_class = resolved_method->GetDeclaringClass(); 753a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 754a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 755996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 756a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 757a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 758a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // method public. Resort to the dex file to determine the correct class for the access check 7594dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); 760a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers methods_class = 7614dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_linker_->ResolveType(dex_file, 7624dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien dex_file.GetMethodId(method_idx).class_idx_, 7634dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien referrer_class); 764a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 765a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 766a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 767a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers referrer_class->CanAccessMember(methods_class, 768a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers resolved_method->GetAccessFlags())) { 769a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 770f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers const bool kEnableSharpening = true; 7712ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Sharpen a virtual call into a direct call when the target is known. 7722ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() || 7732ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers methods_class->IsFinal()); 7742ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // ensure the vtable index will be correct to dispatch in the vtable of the super class 7754155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class && 7762ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers referrer_class->IsSubClass(methods_class) && 7774155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao vtable_idx < methods_class->GetVTable()->GetLength() && 7784155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao methods_class->GetVTable()->Get(vtable_idx) == resolved_method); 7792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if (kEnableSharpening && can_sharpen) { 7802ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->ResolvedMethod(type); 781fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 782fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 783fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method) 784fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers << PrettyMethod(resolved_method); 7852ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers stats_->VirtualMadeDirect(type); 7862ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method); 787fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers type = kDirect; 788fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 7892ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else if (type == kSuper) { 7902ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Unsharpened super calls are suspicious so go slowpath. 7912ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } else { 792c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 7932ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method); 794a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 795a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 796a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 797a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 798a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 799a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Clean up any exception left by method/type resolution 800a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Thread* thread = Thread::Current(); 801a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (thread->IsExceptionPending()) { 802a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers thread->ClearException(); 803a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 804c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedMethod(type); 805a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 806a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 807a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 808f582258f0e296223a091fd64231a203ad71e9649Brian Carlstromvoid Compiler::AddCodePatch(DexCache* dex_cache, 809f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom const DexFile* dex_file, 810f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 811f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_access_flags, 812f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 813f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom bool target_is_direct, 8143fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 8153fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MutexLock mu(compiled_methods_lock_); 816f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom code_to_patch_.push_back(new PatchInformation(dex_cache, 817f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom dex_file, 818f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 819f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_access_flags, 820f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 821f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_is_direct, 822f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 8233fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 824f582258f0e296223a091fd64231a203ad71e9649Brian Carlstromvoid Compiler::AddMethodPatch(DexCache* dex_cache, 825f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom const DexFile* dex_file, 826f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_method_idx, 827f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t referrer_access_flags, 828f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom uint32_t target_method_idx, 829f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom bool target_is_direct, 8303fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers size_t literal_offset) { 8313fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers MutexLock mu(compiled_methods_lock_); 832f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom methods_to_patch_.push_back(new PatchInformation(dex_cache, 833f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom dex_file, 834f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_method_idx, 835f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom referrer_access_flags, 836f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_method_idx, 837f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom target_is_direct, 838f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom literal_offset)); 8393fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers} 8403fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers 8415ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// Return true if the class should be skipped during compilation. We 8425ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// never skip classes in the boot class loader. However, if we have a 8435ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// non-boot class loader and we can resolve the class in the boot 8445ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// class loader, we do skip the class. This happens if an app bundles 8455ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// classes found in the boot classpath. Since at runtime we will 8465ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// select the class from the boot classpath, do not attempt to resolve 8475ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// or compile it now. 8485ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstromstatic bool SkipClass(const ClassLoader* class_loader, 8495ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile& dex_file, 8505ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile::ClassDef& class_def) { 8515ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (class_loader == NULL) { 8525ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 8535ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 8545ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 8555ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 8565ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, NULL); 8575ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (klass == NULL) { 8585ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Thread* self = Thread::Current(); 8595ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom CHECK(self->IsExceptionPending()); 8605ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom self->ClearException(); 8615ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 8625ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 8635ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return true; 8645ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom} 8655ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom 866731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstromclass Context { 867731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public: 868731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context(ClassLinker* class_linker, 869731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* class_loader, 870731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* compiler, 871731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom DexCache* dex_cache, 872731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile* dex_file) 873731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom : class_linker_(class_linker), 874731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom class_loader_(class_loader), 875731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom compiler_(compiler), 876731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom dex_cache_(dex_cache), 877731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom dex_file_(dex_file) {} 878731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 879731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* GetClassLinker() { 880731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(class_linker_ != NULL); 881731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_linker_; 882731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 883731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* GetClassLoader() { 884731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return class_loader_; 885731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 886731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* GetCompiler() { 887731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(compiler_ != NULL); 888731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return compiler_; 889731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 890731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom DexCache* GetDexCache() { 891731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_cache_ != NULL); 892731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_cache_; 893731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 894731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile* GetDexFile() { 895731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom CHECK(dex_file_ != NULL); 896731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom return dex_file_; 897731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom } 898731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom 899731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom private: 900731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker_; 901731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* class_loader_; 902731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Compiler* compiler_; 903731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom DexCache* dex_cache_; 904731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile* dex_file_; 905d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 9069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 907d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughestypedef void Callback(Context* context, size_t index); 908d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 909d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesclass WorkerThread { 910d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes public: 9111e4092589f1400915e6213014da103aab8728ef6Elliott Hughes WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe, bool spawn) 9121e4092589f1400915e6213014da103aab8728ef6Elliott Hughes : spawn_(spawn), context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) { 9131e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 9141e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread"); 9151e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 916d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 917d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 918d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ~WorkerThread() { 9191e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 9201e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown"); 9211e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 922d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 923d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 924d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 9251e4092589f1400915e6213014da103aab8728ef6Elliott Hughes static void* Go(void* arg) { 926d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg); 927d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Runtime* runtime = Runtime::Current(); 9281e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 929462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes runtime->AttachCurrentThread("Compiler Worker", true, NULL); 9301e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 931d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->SetState(Thread::kRunnable); 932d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes worker->Run(); 9331e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 9341e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Thread::Current()->SetState(Thread::kNative); 9351e4092589f1400915e6213014da103aab8728ef6Elliott Hughes runtime->DetachCurrentThread(); 9361e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 937d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return NULL; 938d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 939d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 9401e4092589f1400915e6213014da103aab8728ef6Elliott Hughes void Go() { 9411e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Go(this); 9421e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 9431e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 944d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes void Run() { 945d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t i = begin_; i < end_; i += stripe_) { 946d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes callback_(context_, i); 947aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 9489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 9499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 950d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes pthread_t pthread_; 9511e4092589f1400915e6213014da103aab8728ef6Elliott Hughes bool spawn_; 952d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 953d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context* context_; 954d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t begin_; 955d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t end_; 956d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Callback* callback_; 957d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t stripe_; 9581e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 9591e4092589f1400915e6213014da103aab8728ef6Elliott Hughes friend void ForAll(Context*, size_t, size_t, Callback, size_t); 960d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 961d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 9625523ee070b005576c6f889415205d49ea77cf243Elliott Hughesvoid ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) { 9631e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_GT(thread_count, 0U); 964845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 9651e4092589f1400915e6213014da103aab8728ef6Elliott Hughes std::vector<WorkerThread*> threads; 96681d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes for (size_t i = 0; i < thread_count; ++i) { 9671e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count, (i != 0))); 968d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 9691e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads[0]->Go(); 970d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 97181d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes // Switch to kVmWait while we're blocked waiting for the other threads to finish. 97281d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait); 97381d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes STLDeleteElements(&threads); 97481d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes} 975d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 976d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) { 977731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile& dex_file = *context->GetDexFile(); 978d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 979845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 980845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 981845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 982845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 983845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 984845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 985845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 986d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 987731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom if (SkipClass(context->GetClassLoader(), dex_file, class_def)) { 988d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 989d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 990845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 991d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 992d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 993d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 994d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 995d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 996d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 997d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 998d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 999d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1000731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = context->GetClassLinker(); 1001d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1002d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 1003d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 1004d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 1005731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), true); 1006d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1007d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1008d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 10090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1010d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1011d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1012d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 1013d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 1014731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), false); 1015d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 1016d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1017d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 101820cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1019d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1020d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1021d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 1022d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1023731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), true); 1024d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1025d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1026d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1027845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1028d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1029d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1030d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 1031d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1032731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), false); 1033d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 1034d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1035d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1036845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 1037d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 1038d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1039d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 1040d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1041d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1042d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveType(Context* context, size_t type_idx) { 1043d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 1044d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1045731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Class* klass = context->GetClassLinker()->ResolveType(*context->GetDexFile(), 1046731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom type_idx, 1047731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetDexCache(), 1048731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader()); 1049d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 1050d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1051d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 1052d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1053d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1054d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1055d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) { 1056d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1057d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1058d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1059d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Strings are easy in that they always are simply resolved to literals in the same file 1060d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (image_ && image_classes_ == NULL) { 1061d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // TODO: Add support for loading strings referenced by image_classes_ 1062d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // See also Compiler::CanAssumeTypeIsPresentInDexCache. 1063d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 1064d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes class_linker->ResolveString(dex_file, string_idx, dex_cache); 106520cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1066ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings"); 10679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 1068d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1069731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context context(class_linker, class_loader, this, dex_cache, &dex_file); 10705523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_); 1071ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 1072d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 10735523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 1074ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 10759ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 10769ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1077ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Verify(const ClassLoader* class_loader, 1078ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 1079ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1080ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 108198eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 108298eacac683b78e60799323e8c7d59e7214808639jeffhao VerifyDexFile(class_loader, *dex_file); 108398eacac683b78e60799323e8c7d59e7214808639jeffhao } 108498eacac683b78e60799323e8c7d59e7214808639jeffhao} 108598eacac683b78e60799323e8c7d59e7214808639jeffhao 1086d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void VerifyClass(Context* context, size_t class_def_index) { 1087731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 1088731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def); 1089731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Class* klass = context->GetClassLinker()->FindClass(descriptor, context->GetClassLoader()); 1090d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 1091d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 1092d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 1093d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 1094f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao 1095f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao /* 1096f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * At compile time, we can still structurally verify the class even if FindClass fails. 1097f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * This is to ensure the class is structurally sound for compilation. An unsound class 1098f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * will be rejected by the verifier and later skipped during compilation in the compiler. 1099f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao */ 1100f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao std::string error_msg; 1101731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom if (!verifier::DexVerifier::VerifyClass(context->GetDexFile(), context->GetDexCache(), 1102731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLoader(), class_def_index, error_msg)) { 1103731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index); 1104f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao LOG(ERROR) << "Verification failed on class " 1105731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom << PrettyDescriptor(context->GetDexFile()->GetClassDescriptor(class_def)) 1106f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << " because: " << error_msg; 1107f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao } 1108d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 1109d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1110d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 1111731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetClassLinker()->VerifyClass(klass); 1112d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1113d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 1114d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 1115d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 1116d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 11171ac29447d6053b142f257330d6e237660076911ejeffhao art::Compiler::ClassReference ref(context->GetDexFile(), class_def_index); 11181ac29447d6053b142f257330d6e237660076911ejeffhao if (!verifier::DexVerifier::IsClassRejected(ref)) { 11191ac29447d6053b142f257330d6e237660076911ejeffhao // If the erroneous class wasn't rejected by the verifier, it was a soft error. We want 11201ac29447d6053b142f257330d6e237660076911ejeffhao // to try verification again at run-time, so move back into the resolved state. 11211ac29447d6053b142f257330d6e237660076911ejeffhao klass->SetStatus(Class::kStatusResolved); 11221ac29447d6053b142f257330d6e237660076911ejeffhao } 1123d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 1124d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 11251ac29447d6053b142f257330d6e237660076911ejeffhao CHECK(klass->IsVerified() || klass->IsResolved() || klass->IsErroneous()) << PrettyClass(klass); 1126d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 1127d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 1128d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 112998eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1130b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ | PROT_WRITE); 1131d9cdfe91a4812a86d90a139569eac18e2b6de3fbElliott Hughes 1132731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1133731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context context(class_linker, class_loader, this, class_linker->FindDexCache(dex_file), &dex_file); 11345523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 1135d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 1136b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ); 1137a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1138a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 1139ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, 1140ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 1141ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1142ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1143a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(dex_file != NULL); 1144a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader, *dex_file); 1145a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 1146a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 1147a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 1148a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 1149a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1150ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 1151ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1152a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1153a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 115427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass != NULL) { 11551ac29447d6053b142f257330d6e237660076911ejeffhao if (klass->IsVerified()) { 11561ac29447d6053b142f257330d6e237660076911ejeffhao // Only try to initialize classes that were successfully verified. 11571ac29447d6053b142f257330d6e237660076911ejeffhao class_linker->EnsureInitialized(klass, false); 11581ac29447d6053b142f257330d6e237660076911ejeffhao } 11590755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom // record the final class status if necessary 11600755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom Class::Status status = klass->GetStatus(); 11610755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassReference ref(&dex_file, class_def_index); 1162c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 11630755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CompiledClass* compiled_class = GetCompiledClass(ref); 11640755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (compiled_class == NULL) { 11650755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_class = new CompiledClass(status); 11660755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_classes_[ref] = compiled_class; 11670755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } else { 11680755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK_EQ(status, compiled_class->GetStatus()); 11690755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 117027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 117127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // clear any class not found or verification exceptions 117227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 1173ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 1174ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom 1175ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1176ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 1177ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 117827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass == NULL) { 117927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 118027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } else if (klass->IsInitialized()) { 1181ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 1182ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 118398eacac683b78e60799323e8c7d59e7214808639jeffhao } 118498eacac683b78e60799323e8c7d59e7214808639jeffhao} 118598eacac683b78e60799323e8c7d59e7214808639jeffhao 1186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader, 1187ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 1188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 119083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 119183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CompileDexFile(class_loader, *dex_file); 119283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 119383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 119483db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 1195c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileClass(Context* context, size_t class_def_index) { 1196731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const ClassLoader* class_loader = context->GetClassLoader(); 1197731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom const DexFile& dex_file = *context->GetDexFile(); 1198c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 11997f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#if defined(ART_USE_LLVM_COMPILER) 12007f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien // TODO: Remove this. We should not lock the compiler_lock_ in CompileClass() 1201c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao // However, without this mutex lock, we will get segmentation fault before 1202c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao // LLVM becomes multithreaded. 1203c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao Compiler* cmplr = context->GetCompiler(); 1204c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao CompilerMutexLockFn f = 1205c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao FindFunction<CompilerMutexLockFn>(MakeCompilerSoName(cmplr->GetInstructionSet()), 1206c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao cmplr->compiler_library_, 1207c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao "compilerLLVMMutexLock"); 1208c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao UniquePtr<MutexLock> GUARD((*f)(*cmplr)); 12097f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#endif 12107f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 12115ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (SkipClass(class_loader, dex_file, class_def)) { 12125ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return; 12135ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 1214d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 1215d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 1216d1224c79631bd1801b067a0f212b91afa961a362jeffhao if (verifier::DexVerifier::IsClassRejected(ref)) { 1217d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 1218d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 12190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 12200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 12210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 12220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 12230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 12240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 12250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 12260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 12270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 12280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 12290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 12300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 12310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 12320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 12330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 1234731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1235731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom it.GetMemberIndex(), class_loader, dex_file); 12360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 12379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 12380571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 12390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 1240731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 1241731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom it.GetMemberIndex(), class_loader, dex_file); 12420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 12439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 12440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 12459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 12469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1247c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1248731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom Context context(NULL, class_loader, this, NULL, &dex_file); 12495523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_); 1250c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1251c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 1252a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 1253a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers uint32_t method_idx, const ClassLoader* class_loader, 1254a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile& dex_file) { 1255f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1256bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 12574dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1258169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 125946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, class_loader, dex_file); 12603320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1261169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 12622cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 1263b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes compiled_method = (*compiler_)(*this, code_item, access_flags, method_idx, class_loader, 1264b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes dex_file); 1265bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1266bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 12673bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 12685abfa3ea35781464df8fae60aaf03f48a295e965buzbee if (duration_ns > MsToNs(100)) { 1269bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 12703bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1271f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1272f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 1273f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 12740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 12750755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 1276c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 12770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_methods_[ref] = compiled_method; 12780755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 12792cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 12809baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 128145619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers uint32_t shorty_len; 128245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); 1283169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 12840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(is_static, shorty); 12850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 1286c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len); 12870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 12880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InsertInvokeStub(is_static, shorty, compiled_invoke_stub); 12893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 12900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file); 12910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 129228ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 12930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 12940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::string key(shorty); 12950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (is_static) { 1296bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes key += "$"; // Must not be a shorty type character. 12970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 12980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return key; 12993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 13003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 13010571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const { 1302c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1303955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 13040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 13050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 13063320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 13070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 13080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 13090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 13103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 13113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 13123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 13130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid Compiler::InsertInvokeStub(bool is_static, const char* shorty, 13140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub) { 1315c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1316955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 13170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_invoke_stubs_[key] = compiled_invoke_stub; 13180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 13190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 13200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const { 1321c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 13220755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 13230755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 13240755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 13250755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 13260755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 13270755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 13280755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 13290755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 13300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const { 1331c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 13320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 13330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 13343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 13352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 13363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 13373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 13389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 13399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1340e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) { 1341e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1342e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1343e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CHECK(dex_file != NULL); 1344e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsDexFile(class_loader, *dex_file); 1345e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1346e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1347e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1348e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1349e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1350e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1351e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 1352e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1353e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1354e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 1355e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (klass == NULL || !klass->IsVerified()) { 1356e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1357e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1358e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1359e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1360e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (class_data == NULL) { 1361e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom // empty class such as a marker interface 1362e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1363e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1364e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassDataItemIterator it(dex_file, class_data); 1365e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextStaticField()) { 1366e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1367e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1368e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextInstanceField()) { 1369e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1370e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1371e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextDirectMethod()) { 1372e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1373e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, true); 1374e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1375e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1376e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1377e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextVirtualMethod()) { 1378e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1379e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, false); 1380e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1381e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1382e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1383e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1384e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1385e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1386e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) { 1387e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (method == NULL) { 1388e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1389e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1390e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1391e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint16_t method_idx = method->GetDexMethodIndex(); 1392e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom MethodReference ref(&dex_file, method_idx); 1393e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CompiledMethod* compiled_method = GetCompiledMethod(ref); 1394e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (compiled_method == NULL) { 1395e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1396e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1397e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const std::vector<uint8_t>* gc_map = verifier::DexVerifier::GetGcMap(ref); 1398e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (gc_map == NULL) { 1399e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1400e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1401e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom compiled_method->SetGcMap(*gc_map); 1402e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1403e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 14048b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#if defined(ART_USE_LLVM_COMPILER) 14058b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetElfFileName(std::string const& filename) { 1406c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao elf_filename_ = filename; 14078b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 14088b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 14098b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) { 1410c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao bitcode_filename_ = filename; 1411c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao} 1412c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liaostd::string const& Compiler::GetElfFileName() { 1413c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao return elf_filename_; 1414c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao} 1415c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liaostd::string const& Compiler::GetBitcodeFileName() { 1416c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao return bitcode_filename_; 14178b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 14188b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#endif 14198b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 14209ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1421