compiler_driver.cc revision f56197c5519395fcf8226a7148cc87367e0a7ad4
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 2127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h> 22d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <unistd.h> 2327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 242cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom#include "assembler.h" 259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 261f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h" 279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "dex_cache.h" 28f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao#include "dex_verifier.h" 299baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 304dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#include "oat_compilation_unit.h" 313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h" 326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 331f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "stl_util.h" 35601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes#include "timing_logger.h" 369ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 379787ac4a18e71a57ed2b559759e9903b557a65ddLogan Chien#if !defined(ART_USE_LLVM_COMPILER) 389787ac4a18e71a57ed2b559759e9903b557a65ddLogan Chien#include "jni_compiler.h" 399787ac4a18e71a57ed2b559759e9903b557a65ddLogan Chien#endif 409787ac4a18e71a57ed2b559759e9903b557a65ddLogan Chien 41d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 42d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#include "compiler_llvm/compiler_llvm.h" 43d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 44d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao 459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 47d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if !defined(ART_USE_LLVM_COMPILER) 48996cc586ce76235ee3efa1eff86de51dabcc5d53Ian RogersCompiledMethod* oatCompileMethod(Compiler& compiler, const DexFile::CodeItem* code_item, 4911d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes uint32_t access_flags, uint32_t method_idx, 5011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes const ClassLoader* class_loader, 5111d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes const DexFile& dex_file, InstructionSet); 52d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 5311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 54c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm { 55bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 5645619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers CompiledInvokeStub* ArmCreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len); 571cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type); 588add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 59c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 60c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 { 61bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 6245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers CompiledInvokeStub* X86CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len); 631cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type); 648add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 65e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 66e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 67996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic double Percentage(size_t x, size_t y) { 68996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return 100.0 * ((double)x) / ((double)(x + y)); 69996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 70996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 71996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic void DumpStat(size_t x, size_t y, const char* str) { 72996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (x == 0 && y == 0) { 73996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return; 74996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 75996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases"; 76996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 77996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 78c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersclass AOTCompilationStats { 79c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers public: 80c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"), 81c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_(0), types_not_in_dex_cache_(0), 82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_(0), strings_not_in_dex_cache_(0), 83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_(0), unresolved_types_(0), 84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_(0), unresolved_instance_fields_(0), 85fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0), 86fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers virtual_made_direct_(0) { 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers for (size_t i = 0; i < kMaxInvokeType; i++) { 88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[i] = 0; 89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[i] = 0; 90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void Dump() { 94c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache"); 95c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache"); 96c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_types_, unresolved_types_, "types resolved"); 97c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); 98c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, 99c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields resolved"); 100c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_, 101c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields local to a class"); 102c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 103c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers for (size_t i = 0; i < kMaxInvokeType; i++) { 104c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers std::ostringstream oss; 105c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers oss << "resolved " << static_cast<InvokeType>(i) << " methods"; 106c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str()); 107c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 108fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers DumpStat(virtual_made_direct_, resolved_methods_[kVirtual] + unresolved_methods_[kVirtual], 109fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers "made direct from virtual"); 110c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 111996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 112996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers// Allow lossy statistics in non-debug builds 113996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG 114996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() MutexLock mu(stats_lock_) 115996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else 116996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() 117996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif 118996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 119c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeInDexCache() { 120c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 121c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_++; 122c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 123996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 124c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNotInDexCache() { 125c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 126c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_not_in_dex_cache_++; 127c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 128996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringInDexCache() { 130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_++; 132c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 133996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringNotInDexCache() { 135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_not_in_dex_cache_++; 137c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 138996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeDoesntNeedAccessCheck() { 140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_++; 142c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 143996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNeedsAccessCheck() { 145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_types_++; 147c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 148996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedInstanceField() { 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_++; 152c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 153996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedInstanceField(){ 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_instance_fields_++; 157c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 158996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedLocalStaticField() { 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_local_static_fields_++; 162c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 163996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedStaticField() { 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_static_fields_++; 167c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 168996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedStaticField() { 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_static_fields_++; 172c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 173996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedMethod(InvokeType type) { 175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 177c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[type]++; 178996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 179996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedMethod(InvokeType type) { 181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 182c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 183c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[type]++; 184996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 186fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers void VirtualMadeDirect() { 187fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers STATS_LOCK(); 188fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers virtual_made_direct_++; 189fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } 190c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private: 191c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Mutex stats_lock_; 192c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 193c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_in_dex_cache_; 194c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_not_in_dex_cache_; 195c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 196c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_in_dex_cache_; 197c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_not_in_dex_cache_; 198c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 199c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_types_; 200c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_types_; 201c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 202c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_instance_fields_; 203c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_instance_fields_; 204c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 205c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_local_static_fields_; 206c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_static_fields_; 207c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_static_fields_; 208c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 209c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_methods_[kMaxInvokeType + 1]; 210c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_methods_[kMaxInvokeType + 1]; 211fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers size_t virtual_made_direct_; 212c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 213c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);; 214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}; 215996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 2165523ee070b005576c6f889415205d49ea77cf243Elliott HughesCompiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count, 217de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes bool support_debugging, const std::set<std::string>* image_classes) 218aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom : instruction_set_(instruction_set), 2199787ac4a18e71a57ed2b559759e9903b557a65ddLogan Chien#if !defined(ART_USE_LLVM_COMPILER) 220aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom jni_compiler_(instruction_set), 2219787ac4a18e71a57ed2b559759e9903b557a65ddLogan Chien#endif 222c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 223c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 224c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 225aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 2265523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 227de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 228c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 229d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao image_classes_(image_classes) 230d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 231d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao , 232d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao compiler_llvm_(new compiler_llvm::CompilerLLVM(this, instruction_set)) 233d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 234d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao { 23525c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 236ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 237ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 238ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 239c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 240c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 2413320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() { 242c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 243c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 244c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 245c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 246c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 247c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 248c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 249c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 250c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 251c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 252c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 253bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 2543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 2553320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2561cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, 2571cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type) { 258ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 2591cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return x86::X86CreateResolutionTrampoline(type); 260ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 261ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 262ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 2631cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return arm::ArmCreateResolutionTrampoline(type); 264ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 265ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 266ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 2678add92dcf59568c72c17e9a979948b1a7a0b1264Elliott HughesByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 268169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 269169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 270169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 2718add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 272169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 2738add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 274169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 275ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes LOG(FATAL) << "Unknown InstructionSet: " << static_cast<int>(instruction_set); 276169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 277169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 278169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 279169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 280ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan RogersByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 281ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 282ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return x86::CreateAbstractMethodErrorStub(); 283ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 284ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 285ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 286ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return arm::CreateAbstractMethodErrorStub(); 287ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 288ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 289ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 290254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilsonvoid Compiler::CompileAll(const ClassLoader* class_loader, 291ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 29225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 293ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 294601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("compiler"); 295601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 296601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 297601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 298ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Compile(class_loader, dex_files); 299601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("Compile"); 300601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 301ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 302601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PostCompile"); 303601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 304601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes if (timings.GetTotalNs() > MsToNs(1000)) { 305601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.Dump(); 306601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 307996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 308c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->Dump(); 3098a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 3108a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 3113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromvoid Compiler::CompileOne(const Method* method) { 31225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 313ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3148a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 315ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Find the dex_file 3170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 3180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); 319ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 320ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(&dex_file); 321ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 322601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("CompileOne"); 323601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 324ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 326a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset()); 327a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file); 328ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 329ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 3309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 3319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 332ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader, 333d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 334ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 335ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 3369ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 337d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ResolveDexFile(class_loader, *dex_file, timings); 3389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 3399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 3409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 341ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PreCompile(const ClassLoader* class_loader, 342601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 343d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Resolve(class_loader, dex_files, timings); 344601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 345ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Verify(class_loader, dex_files); 346601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.Verify"); 347601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 348ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom InitializeClassesWithoutClinit(class_loader, dex_files); 349601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.InitializeClassesWithoutClinit"); 350ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 351ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 352ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PostCompile(const ClassLoader* class_loader, 353ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 354e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMaps(class_loader, dex_files); 355d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 3567f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien compiler_llvm_->MaterializeRemainder(); 357d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 358ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 359ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 360ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const { 361ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 362ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 363ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 364ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 365ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 366ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3676d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, 368996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 3696d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 370c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 3716d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 3726d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 3731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 3746d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 375c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 3766d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 3776d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 378996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 379996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 380c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 381996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 382c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 383996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 384996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 3856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 3866d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 3871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache, 388996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t string_idx) { 3891bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // TODO: Add support for loading strings referenced by image_classes_ 3901bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 3911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 3921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // The following is a test saying that if we're building the image without a restricted set of 3931bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // image classes then we can assume the string is present in the dex cache if it is there now 394996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL; 395996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 396c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 397996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 398c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 399996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 400996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 4011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 4021bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 4031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache, 404996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers const DexFile& dex_file, uint32_t type_idx) { 4051bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 4061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 4071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 408c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 4101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 4121bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 4131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 414c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 4161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 4181bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 419996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 420996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 421c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 422996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 423c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 424996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 425996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 4261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 4271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 4281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 4291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexCache* dex_cache, 4301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile& dex_file, 431996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 4321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 4331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 4341bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 435c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 4371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 4391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 4401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 441c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 4431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 4451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 446996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 447996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 448c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 449996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 450c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 451996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 452996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 4531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 4541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 4554dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Class* ComputeReferrerClass(OatCompilationUnit* mUnit) { 4564dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile::MethodId& referrer_method_id = 4574dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->GetMethodId(mUnit->method_idx_); 458a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4594dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveType( 4604dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, referrer_method_id.class_idx_, 4614dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_cache_, mUnit->class_loader_); 4624dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 463a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4644dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) { 4654dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveField( 4664dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, field_idx, mUnit->dex_cache_, 4674dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, false); 468a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 469a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4704dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) { 4714dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveMethod( 4724dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, method_idx, mUnit->dex_cache_, 4734dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, true); 474a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 475a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4764dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 4778cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao int& field_offset, bool& is_volatile, bool is_put) { 4781bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 4791bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 4801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 4811bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 4824dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 4831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 4844dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 4851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve referring class then access check, failure to pass the 4861bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* fields_class = resolved_field->GetDeclaringClass(); 4878cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 4888cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao fields_class != referrer_class; 4898cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (referrer_class != NULL && referrer_class->CanAccess(fields_class) && 4908cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) && 4918cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao !is_write_to_final_from_wrong_class) { 4921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 4931bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 494c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedInstanceField(); 4951bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // Fast path. 4961bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4971bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4981bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 4991bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 5001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 5011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 5021bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 503c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 5041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 5051bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 5081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers int& field_offset, int& ssb_index, 5098cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool& is_referrers_class, bool& is_volatile, bool is_put) { 5101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 5111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 5121bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 5131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 5141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 5151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 5164dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 5171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 518a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers DCHECK(resolved_field->IsStatic()); 5194dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 5201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 5218cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao Class* fields_class = resolved_field->GetDeclaringClass(); 5228cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 5231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 5241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 5251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 526c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 5271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 5281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 5298cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 5301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class->CanAccess(fields_class) && 5318cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) && 5328cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao !is_write_to_final_from_wrong_class) { 5331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 5341bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 5354103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 5364103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 5374dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien if (fields_class->GetDexCache() == mUnit->dex_cache_) { 5384103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 5394103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 5404103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 5414103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 5424103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 543c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 5444103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 5454103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 5464103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // Search dex file for localized ssb index 5471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 5481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 5494dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindStringId(descriptor); 5501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 5511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 5524dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id)); 5531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if(type_id != NULL) { 5541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 5554dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id); 5561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 5571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 558c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 5591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 5601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 5671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 5681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 5691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 5701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 571c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 5721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 5731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 575fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type, 576996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers int& vtable_idx) { 577a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 5784dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx); 579a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 5804dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 581a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class != NULL) { 582a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Class* methods_class = resolved_method->GetDeclaringClass(); 583a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 584a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 585996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 586a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 587a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 588a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // method public. Resort to the dex file to determine the correct class for the access check 5894dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); 590a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers methods_class = 5914dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_linker_->ResolveType(dex_file, 5924dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien dex_file.GetMethodId(method_idx).class_idx_, 5934dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien referrer_class); 594a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 595a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 596a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 597a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers referrer_class->CanAccessMember(methods_class, 598a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers resolved_method->GetAccessFlags())) { 599a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 600fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers if (type == kVirtual && (resolved_method->IsFinal() || methods_class->IsFinal())) { 601fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers stats_->ResolvedMethod(kVirtual); 602fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 603fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 604fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method) 605fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers << PrettyMethod(resolved_method); 606fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers type = kDirect; 607fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers stats_->VirtualMadeDirect(); 608fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 609fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } else if (type != kSuper) { 610c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers // nothing left to do for static/direct/virtual/interface dispatch 611c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 612a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 613a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } else { 614a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // ensure the vtable index will be correct to dispatch in the vtable of the super class 615996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (referrer_class->IsSubClass(methods_class) && 616996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers vtable_idx < methods_class->GetVTable()->GetLength()) { 617c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 618a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 619a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 620a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 621a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 622a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 623a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 624a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Clean up any exception left by method/type resolution 625a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Thread* thread = Thread::Current(); 626a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (thread->IsExceptionPending()) { 627a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers thread->ClearException(); 628a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 629c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedMethod(type); 630a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 631a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 632a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6335ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// Return true if the class should be skipped during compilation. We 6345ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// never skip classes in the boot class loader. However, if we have a 6355ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// non-boot class loader and we can resolve the class in the boot 6365ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// class loader, we do skip the class. This happens if an app bundles 6375ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// classes found in the boot classpath. Since at runtime we will 6385ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// select the class from the boot classpath, do not attempt to resolve 6395ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// or compile it now. 6405ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstromstatic bool SkipClass(const ClassLoader* class_loader, 6415ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile& dex_file, 6425ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile::ClassDef& class_def) { 6435ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (class_loader == NULL) { 6445ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 6455ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 6465ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 6475ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 6485ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, NULL); 6495ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (klass == NULL) { 6505ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Thread* self = Thread::Current(); 6515ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom CHECK(self->IsExceptionPending()); 6525ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom self->ClearException(); 6535ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 6545ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 6555ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return true; 6565ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom} 6575ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom 658d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstruct Context { 659d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker; 660d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const ClassLoader* class_loader; 661c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes Compiler* compiler; 662d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache; 663d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile* dex_file; 664d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 6659ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 666d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughestypedef void Callback(Context* context, size_t index); 667d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 668d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesclass WorkerThread { 669d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes public: 6701e4092589f1400915e6213014da103aab8728ef6Elliott Hughes WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe, bool spawn) 6711e4092589f1400915e6213014da103aab8728ef6Elliott Hughes : spawn_(spawn), context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) { 6721e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 6731e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread"); 6741e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 675d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 676d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 677d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ~WorkerThread() { 6781e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 6791e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown"); 6801e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 681d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 682d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 683d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 6841e4092589f1400915e6213014da103aab8728ef6Elliott Hughes static void* Go(void* arg) { 685d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg); 686d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Runtime* runtime = Runtime::Current(); 6871e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 6881e4092589f1400915e6213014da103aab8728ef6Elliott Hughes runtime->AttachCurrentThread("Compiler Worker", true); 6891e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 690d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->SetState(Thread::kRunnable); 691d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes worker->Run(); 6921e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 6931e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Thread::Current()->SetState(Thread::kNative); 6941e4092589f1400915e6213014da103aab8728ef6Elliott Hughes runtime->DetachCurrentThread(); 6951e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 696d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return NULL; 697d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 698d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 6991e4092589f1400915e6213014da103aab8728ef6Elliott Hughes void Go() { 7001e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Go(this); 7011e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 7021e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 703d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes void Run() { 704d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t i = begin_; i < end_; i += stripe_) { 705d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes callback_(context_, i); 706aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 7079ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 7089ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 709d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes pthread_t pthread_; 7101e4092589f1400915e6213014da103aab8728ef6Elliott Hughes bool spawn_; 711d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 712d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context* context_; 713d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t begin_; 714d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t end_; 715d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Callback* callback_; 716d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t stripe_; 7171e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 7181e4092589f1400915e6213014da103aab8728ef6Elliott Hughes friend void ForAll(Context*, size_t, size_t, Callback, size_t); 719d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 720d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 7215523ee070b005576c6f889415205d49ea77cf243Elliott Hughesvoid ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) { 7221e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_GT(thread_count, 0U); 723845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 7241e4092589f1400915e6213014da103aab8728ef6Elliott Hughes std::vector<WorkerThread*> threads; 72581d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes for (size_t i = 0; i < thread_count; ++i) { 7261e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count, (i != 0))); 727d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 7281e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads[0]->Go(); 729d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 73081d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes // Switch to kVmWait while we're blocked waiting for the other threads to finish. 73181d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait); 73281d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes STLDeleteElements(&threads); 73381d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes} 734d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 735d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) { 736d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile& dex_file = *context->dex_file; 737d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 738845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 739845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 740845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 741845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 742845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 743845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 744845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 745d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 746d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (SkipClass(context->class_loader, dex_file, class_def)) { 747d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 748d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 749845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 750d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 751d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 752d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 753d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 754d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 755d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 756d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 757d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 758d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 759d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = context->class_linker; 760d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 761d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 762d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 763d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 764d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, true); 765d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 766d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 767d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 7680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 769d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 770d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 771d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 772d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 773d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, false); 774d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 775d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 776d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 77720cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 778d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 779d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 780d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 781d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 782d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, true); 783d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 784d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 785d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 786845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 787d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 788d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 789d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 790d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 791d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, false); 792d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 793d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 794d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 795845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 796d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 797d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 798d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 799d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 800d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 801d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveType(Context* context, size_t type_idx) { 802d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 803d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 804d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = context->class_linker; 805d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile& dex_file = *context->dex_file; 806d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Class* klass = class_linker->ResolveType(dex_file, type_idx, context->dex_cache, context->class_loader); 807d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 808d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 809d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 810d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 811d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 812d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 813d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) { 814d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 815d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 816d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 817d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Strings are easy in that they always are simply resolved to literals in the same file 818d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (image_ && image_classes_ == NULL) { 819d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // TODO: Add support for loading strings referenced by image_classes_ 820d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // See also Compiler::CanAssumeTypeIsPresentInDexCache. 821d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 822d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes class_linker->ResolveString(dex_file, string_idx, dex_cache); 82320cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 824ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings"); 8259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 826d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 827d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context context; 828d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_linker = class_linker; 829d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_loader = class_loader; 830d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_cache = dex_cache; 831d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_file = &dex_file; 832d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 8335523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_); 834ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 835d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 8365523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 837ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 8389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 8399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 840ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Verify(const ClassLoader* class_loader, 841ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 842ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 843ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 84498eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 84598eacac683b78e60799323e8c7d59e7214808639jeffhao VerifyDexFile(class_loader, *dex_file); 84698eacac683b78e60799323e8c7d59e7214808639jeffhao } 84798eacac683b78e60799323e8c7d59e7214808639jeffhao} 84898eacac683b78e60799323e8c7d59e7214808639jeffhao 849d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void VerifyClass(Context* context, size_t class_def_index) { 850d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index); 851d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const char* descriptor = context->dex_file->GetClassDescriptor(class_def); 852d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Class* klass = context->class_linker->FindClass(descriptor, context->class_loader); 853d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 854d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 855d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 856d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 857f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao 858f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao /* 859f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * At compile time, we can still structurally verify the class even if FindClass fails. 860f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * This is to ensure the class is structurally sound for compilation. An unsound class 861f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao * will be rejected by the verifier and later skipped during compilation in the compiler. 862f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao */ 863f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao std::string error_msg; 864f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao if (!verifier::DexVerifier::VerifyClass(context->dex_file, context->dex_cache, 865f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao context->class_loader, class_def_index, error_msg)) { 866f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index); 867f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao LOG(ERROR) << "Verification failed on class " 868f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << PrettyDescriptor(context->dex_file->GetClassDescriptor(class_def)) 869f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao << " because: " << error_msg; 870f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao } 871d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 872d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 873d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 874d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_linker->VerifyClass(klass); 875d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 876d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 877d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 878d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 879d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 880d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // We want to try verification again at run-time, so move back into the resolved state. 881d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes klass->SetStatus(Class::kStatusResolved); 882d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 883d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 884d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass); 885d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 886d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 887d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 88898eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 889b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ | PROT_WRITE); 890d9cdfe91a4812a86d90a139569eac18e2b6de3fbElliott Hughes 891d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context context; 892d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_linker = Runtime::Current()->GetClassLinker(); 893d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_loader = class_loader; 894f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao context.dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); 895d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_file = &dex_file; 8965523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 897d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 898b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ); 899a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 900a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 901ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, 902ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 903ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 904ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 905a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(dex_file != NULL); 906a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader, *dex_file); 907a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 908a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 909a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 910a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 911a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 912ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 913ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 914a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 915a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 91627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass != NULL) { 91727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom class_linker->EnsureInitialized(klass, false); 9180755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom // record the final class status if necessary 9190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom Class::Status status = klass->GetStatus(); 9200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassReference ref(&dex_file, class_def_index); 921c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 9220755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CompiledClass* compiled_class = GetCompiledClass(ref); 9230755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (compiled_class == NULL) { 9240755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_class = new CompiledClass(status); 9250755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_classes_[ref] = compiled_class; 9260755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } else { 9270755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK_EQ(status, compiled_class->GetStatus()); 9280755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 92927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 93027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // clear any class not found or verification exceptions 93127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 932ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 933ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom 934ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 935ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 936ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 93727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass == NULL) { 93827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 93927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } else if (klass->IsInitialized()) { 940ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 941ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 94298eacac683b78e60799323e8c7d59e7214808639jeffhao } 94398eacac683b78e60799323e8c7d59e7214808639jeffhao} 94498eacac683b78e60799323e8c7d59e7214808639jeffhao 945ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader, 946ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 947ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 948ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 94983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 95083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CompileDexFile(class_loader, *dex_file); 95183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 95283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 95383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 954c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileClass(Context* context, size_t class_def_index) { 955c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const ClassLoader* class_loader = context->class_loader; 956c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile& dex_file = *context->dex_file; 957c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 9587f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9597f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#if defined(ART_USE_LLVM_COMPILER) 9607f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien compiler_llvm::CompilerLLVM* compiler_llvm = context->compiler->GetCompilerLLVM(); 9617f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9627f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien MutexLock GUARD(compiler_llvm->compiler_lock_); 9637f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien // TODO: Remove this. We should not lock the compiler_lock_ in CompileClass() 9647f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien // However, without this mutex lock, we will get segmentation fault. 9657f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#endif 9667f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9675ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (SkipClass(class_loader, dex_file, class_def)) { 9685ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return; 9695ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 970d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 971d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 972d1224c79631bd1801b067a0f212b91afa961a362jeffhao if (verifier::DexVerifier::IsClassRejected(ref)) { 973d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 974d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 9750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 9760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 9770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 9780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 9790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 9800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 9810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 9820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 9830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 9850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 9860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 9880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 9890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 990c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 991c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes it.GetMemberIndex(), class_loader, dex_file); 9920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9939ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 9940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 9950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 996c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 997c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes it.GetMemberIndex(), class_loader, dex_file); 9980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 10000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 10017f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 10027f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#if defined(ART_USE_LLVM_COMPILER) 10037f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien compiler_llvm->MaterializeIfThresholdReached(); 10047f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#endif 10059ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 10069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1007c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1008c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes Context context; 1009c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.class_loader = class_loader; 1010c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.compiler = this; 1011c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.dex_file = &dex_file; 10125523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_); 1013c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1014c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 1015a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 1016a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers uint32_t method_idx, const ClassLoader* class_loader, 1017a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile& dex_file) { 1018f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1019bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 10204dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 10214dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#if defined(ART_USE_LLVM_COMPILER) 10224dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ClassLinker *class_linker = Runtime::Current()->GetClassLinker(); 10234dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien DexCache *dex_cache = class_linker->FindDexCache(dex_file); 10244dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1025dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien OatCompilationUnit oat_compilation_unit( 1026dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien class_loader, class_linker, dex_file, *dex_cache, code_item, 1027dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien method_idx, access_flags); 10284dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#endif 10294dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1030169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 103188894ee835411de72025cd8a5d8d111a6f2a004aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 1032dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien compiled_method = compiler_llvm_->CompileNativeMethod(&oat_compilation_unit); 103388894ee835411de72025cd8a5d8d111a6f2a004aLogan Chien#else 1034169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file); 103588894ee835411de72025cd8a5d8d111a6f2a004aLogan Chien#endif 10363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1037169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 10382cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 1039d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 1040dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien compiled_method = compiler_llvm_->CompileDexMethod(&oat_compilation_unit); 1041d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#else 1042a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers compiled_method = oatCompileMethod(*this, code_item, access_flags, method_idx, class_loader, 1043a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers dex_file, kThumb2); 1044d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 1045bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1046bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 10473bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 10485abfa3ea35781464df8fae60aaf03f48a295e965buzbee if (duration_ns > MsToNs(100)) { 1049bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 10503bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1051f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1052f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 1053f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 10540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 10550755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 1056c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 10570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_methods_[ref] = compiled_method; 10580755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 10592cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 10609baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 106145619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers uint32_t shorty_len; 106245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); 1063169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 10640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(is_static, shorty); 10650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 1066f04364f0ff789935d05490ee684f01c3de431780Logan Chien#if defined(ART_USE_LLVM_COMPILER) 1067f04364f0ff789935d05490ee684f01c3de431780Logan Chien compiled_invoke_stub = compiler_llvm_->CreateInvokeStub(is_static, shorty); 1068f04364f0ff789935d05490ee684f01c3de431780Logan Chien#else 10690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (instruction_set_ == kX86) { 107045619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers compiled_invoke_stub = ::art::x86::X86CreateInvokeStub(is_static, shorty, shorty_len); 10710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 10720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 10730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Generates invocation stub using ARM instruction set 107445619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers compiled_invoke_stub = ::art::arm::ArmCreateInvokeStub(is_static, shorty, shorty_len); 10750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1076f04364f0ff789935d05490ee684f01c3de431780Logan Chien#endif 1077f04364f0ff789935d05490ee684f01c3de431780Logan Chien 10780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 10790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InsertInvokeStub(is_static, shorty, compiled_invoke_stub); 10803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 10810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file); 10820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 108328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 10840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 10850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::string key(shorty); 10860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (is_static) { 1087bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes key += "$"; // Must not be a shorty type character. 10880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 10890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return key; 10903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 10913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 10920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const { 1093c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1094955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 10950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 10960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 10973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 10980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 10990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 11000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 11013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 11023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 11033320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 11040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid Compiler::InsertInvokeStub(bool is_static, const char* shorty, 11050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub) { 1106c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1107955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 11080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_invoke_stubs_[key] = compiled_invoke_stub; 11090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 11100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 11110755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const { 1112c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 11130755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 11140755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 11150755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 11160755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 11170755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 11180755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 11190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 11200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 11210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const { 1122c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 11230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 11240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 11253320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 11262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 11273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 11283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 11299ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 11309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1131e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) { 1132e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1133e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1134e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CHECK(dex_file != NULL); 1135e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsDexFile(class_loader, *dex_file); 1136e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1137e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1138e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1139e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1140e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1141e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1142e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 1143e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1144e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1145e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 1146e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (klass == NULL || !klass->IsVerified()) { 1147e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1148e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1149e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1150e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1151e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (class_data == NULL) { 1152e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom // empty class such as a marker interface 1153e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1154e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1155e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassDataItemIterator it(dex_file, class_data); 1156e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextStaticField()) { 1157e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1158e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1159e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextInstanceField()) { 1160e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1161e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1162e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextDirectMethod()) { 1163e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1164e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, true); 1165e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1166e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1167e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1168e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextVirtualMethod()) { 1169e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1170e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, false); 1171e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1172e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1173e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1174e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1175e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1176e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1177e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) { 1178e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (method == NULL) { 1179e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1180e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1181e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1182e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint16_t method_idx = method->GetDexMethodIndex(); 1183e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom MethodReference ref(&dex_file, method_idx); 1184e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CompiledMethod* compiled_method = GetCompiledMethod(ref); 1185e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (compiled_method == NULL) { 1186e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1187e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1188e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const std::vector<uint8_t>* gc_map = verifier::DexVerifier::GetGcMap(ref); 1189e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (gc_map == NULL) { 1190e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1191e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1192e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom compiled_method->SetGcMap(*gc_map); 1193e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1194e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 11958b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#if defined(ART_USE_LLVM_COMPILER) 11968b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetElfFileName(std::string const& filename) { 11978b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien compiler_llvm_->SetElfFileName(filename); 11988b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 11998b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 12008b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) { 12018b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien compiler_llvm_->SetBitcodeFileName(filename); 12028b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 12038b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#endif 12048b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 12059ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1206