compiler_driver.cc revision fb6adba0d5d5505610fbd325e7911db700a2f1e8
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" 282cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom#include "jni_compiler.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 37d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 38d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#include "compiler_llvm/compiler_llvm.h" 39d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 40d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao 419ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 43d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if !defined(ART_USE_LLVM_COMPILER) 44996cc586ce76235ee3efa1eff86de51dabcc5d53Ian RogersCompiledMethod* oatCompileMethod(Compiler& compiler, const DexFile::CodeItem* code_item, 4511d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes uint32_t access_flags, uint32_t method_idx, 4611d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes const ClassLoader* class_loader, 4711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes const DexFile& dex_file, InstructionSet); 48d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 4911d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 50c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm { 51bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 5245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers CompiledInvokeStub* ArmCreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len); 531cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type); 548add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 55c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 56c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 { 57bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 5845619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers CompiledInvokeStub* X86CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len); 591cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type); 608add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 61e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 63d1224c79631bd1801b067a0f212b91afa961a362jeffhaonamespace verifier { 64d1224c79631bd1801b067a0f212b91afa961a362jeffhao class DexVerifier { 65d1224c79631bd1801b067a0f212b91afa961a362jeffhao public: 66d1224c79631bd1801b067a0f212b91afa961a362jeffhao static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref); 67d1224c79631bd1801b067a0f212b91afa961a362jeffhao static bool IsClassRejected(Compiler::ClassReference ref); 68d1224c79631bd1801b067a0f212b91afa961a362jeffhao }; 69d1224c79631bd1801b067a0f212b91afa961a362jeffhao} 70d1224c79631bd1801b067a0f212b91afa961a362jeffhao 71996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic double Percentage(size_t x, size_t y) { 72996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return 100.0 * ((double)x) / ((double)(x + y)); 73996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 74996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 75996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic void DumpStat(size_t x, size_t y, const char* str) { 76996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (x == 0 && y == 0) { 77996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return; 78996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 79996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases"; 80996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers} 81996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersclass AOTCompilationStats { 83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers public: 84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"), 85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_(0), types_not_in_dex_cache_(0), 86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_(0), strings_not_in_dex_cache_(0), 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_(0), unresolved_types_(0), 88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_(0), unresolved_instance_fields_(0), 89fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0), 90fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers virtual_made_direct_(0) { 91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers for (size_t i = 0; i < kMaxInvokeType; i++) { 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[i] = 0; 93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[i] = 0; 94c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 95c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 96c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 97c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void Dump() { 98c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache"); 99c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache"); 100c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_types_, unresolved_types_, "types resolved"); 101c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); 102c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, 103c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields resolved"); 104c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_, 105c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "static fields local to a class"); 106c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 107c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers for (size_t i = 0; i < kMaxInvokeType; i++) { 108c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers std::ostringstream oss; 109c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers oss << "resolved " << static_cast<InvokeType>(i) << " methods"; 110c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str()); 111c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 112fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers DumpStat(virtual_made_direct_, resolved_methods_[kVirtual] + unresolved_methods_[kVirtual], 113fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers "made direct from virtual"); 114c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 115996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 116996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers// Allow lossy statistics in non-debug builds 117996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG 118996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() MutexLock mu(stats_lock_) 119996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else 120996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() 121996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif 122996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 123c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeInDexCache() { 124c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 125c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_in_dex_cache_++; 126c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 127996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 128c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNotInDexCache() { 129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers types_not_in_dex_cache_++; 131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 132996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 133c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringInDexCache() { 134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_in_dex_cache_++; 136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 137996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 138c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void StringNotInDexCache() { 139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers strings_not_in_dex_cache_++; 141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 142996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 143c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeDoesntNeedAccessCheck() { 144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_types_++; 146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 147996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 148c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void TypeNeedsAccessCheck() { 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_types_++; 151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 152996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 153c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedInstanceField() { 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_instance_fields_++; 156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 157996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 158c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedInstanceField(){ 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_instance_fields_++; 161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 162996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 163c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedLocalStaticField() { 164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_local_static_fields_++; 166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 167996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 168c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedStaticField() { 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_static_fields_++; 171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 172996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 173c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedStaticField() { 174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_static_fields_++; 176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 177996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 178c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void ResolvedMethod(InvokeType type) { 179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers resolved_methods_[type]++; 182996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 183996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers void UnresolvedMethod(InvokeType type) { 185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DCHECK_LE(type, kMaxInvokeType); 186c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers STATS_LOCK(); 187c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers unresolved_methods_[type]++; 188996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 189c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 190fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers void VirtualMadeDirect() { 191fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers STATS_LOCK(); 192fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers virtual_made_direct_++; 193fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } 194c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private: 195c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Mutex stats_lock_; 196c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 197c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_in_dex_cache_; 198c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t types_not_in_dex_cache_; 199c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 200c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_in_dex_cache_; 201c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t strings_not_in_dex_cache_; 202c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 203c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_types_; 204c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_types_; 205c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 206c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_instance_fields_; 207c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_instance_fields_; 208c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 209c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_local_static_fields_; 210c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_static_fields_; 211c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_static_fields_; 212c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 213c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t resolved_methods_[kMaxInvokeType + 1]; 214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers size_t unresolved_methods_[kMaxInvokeType + 1]; 215fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers size_t virtual_made_direct_; 216c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 217c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);; 218c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}; 219996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 2205523ee070b005576c6f889415205d49ea77cf243Elliott HughesCompiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count, 221de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes bool support_debugging, const std::set<std::string>* image_classes) 222aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom : instruction_set_(instruction_set), 223aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom jni_compiler_(instruction_set), 224c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 225c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 226c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 227aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 2285523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 229de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes support_debugging_(support_debugging), 230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_(new AOTCompilationStats), 231d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao image_classes_(image_classes) 232d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 233d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao , 234d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao compiler_llvm_(new compiler_llvm::CompilerLLVM(this, instruction_set)) 235d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 236d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao { 23725c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 238ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 239ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 240ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 241c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 242c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 2433320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() { 244c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 245c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 246c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 247c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 248c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 249c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 250c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 251c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 252c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 253c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 254c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 255bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 2563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 2573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 2581cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, 2591cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type) { 260ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 2611cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return x86::X86CreateResolutionTrampoline(type); 262ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 263ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 264ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 2651cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return arm::ArmCreateResolutionTrampoline(type); 266ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 267ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 268ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 2698add92dcf59568c72c17e9a979948b1a7a0b1264Elliott HughesByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 270169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 271169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 272169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 2738add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 274169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 2758add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 276169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 277ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes LOG(FATAL) << "Unknown InstructionSet: " << static_cast<int>(instruction_set); 278169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 279169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 280169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 281169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 282ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan RogersByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 283ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 284ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return x86::CreateAbstractMethodErrorStub(); 285ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 286ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 287ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 288ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return arm::CreateAbstractMethodErrorStub(); 289ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 290ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 291ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 292254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilsonvoid Compiler::CompileAll(const ClassLoader* class_loader, 293ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 29425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 295ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 296601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("compiler"); 297601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 298601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 299601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 300ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Compile(class_loader, dex_files); 301601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("Compile"); 302601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 303ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 304601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PostCompile"); 305601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 306601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes if (timings.GetTotalNs() > MsToNs(1000)) { 307601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.Dump(); 308601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 309996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 310c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->Dump(); 3118a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 3128a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 3133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromvoid Compiler::CompileOne(const Method* method) { 31425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 315ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3168a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 317ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Find the dex_file 3190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 3200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); 321ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 322ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(&dex_file); 323ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 324601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("CompileOne"); 325601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 326ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 328a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset()); 329a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file); 330ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 331ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 3329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 3339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 334ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader, 335d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 336ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 337ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 3389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 339d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ResolveDexFile(class_loader, *dex_file, timings); 3409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 3419ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 3429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 343ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PreCompile(const ClassLoader* class_loader, 344601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 345d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Resolve(class_loader, dex_files, timings); 346601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 347ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Verify(class_loader, dex_files); 348601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.Verify"); 349601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 350ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom InitializeClassesWithoutClinit(class_loader, dex_files); 351601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.InitializeClassesWithoutClinit"); 352ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 353ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 354ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PostCompile(const ClassLoader* class_loader, 355ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 356e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMaps(class_loader, dex_files); 357d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 3587f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien compiler_llvm_->MaterializeRemainder(); 359d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 360ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 361ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 362ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const { 363ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 364ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 365ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 366ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 367ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 368ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 3696d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, 370996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 3716d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 372c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 3736d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 3746d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 3751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 3766d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 377c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 3786d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 3796d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 380996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 381996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 382c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeInDexCache(); 383996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 384c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNotInDexCache(); 385996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 386996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 3876d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 3886d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 3891bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache, 390996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t string_idx) { 3911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // TODO: Add support for loading strings referenced by image_classes_ 3921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // See also Compiler::ResolveDexFile 3931bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 3941bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // The following is a test saying that if we're building the image without a restricted set of 3951bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // image classes then we can assume the string is present in the dex cache if it is there now 396996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL; 397996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 398c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringInDexCache(); 399996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 400c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->StringNotInDexCache(); 401996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 402996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 4031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 4041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 4051bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache, 406996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers const DexFile& dex_file, uint32_t type_idx) { 4071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier 4081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 4091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 410c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 4121bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 4141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 4151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 416c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 4181bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access check, will return true if access is ok or false if we're going to have to 4201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // check this at runtime (for example for class loaders). 421996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class); 422996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 423c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 424996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 425c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 426996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 427996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 4281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 4291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 4301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, 4311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexCache* dex_cache, 4321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile& dex_file, 433996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers uint32_t type_idx) { 4341bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Get type from dex cache assuming it was populated by the verifier. 4351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* resolved_class = dex_cache->GetResolvedType(type_idx); 4361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_class == NULL) { 437c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Unknown class needs access checks. 4391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx); 4411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); 4421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class == NULL) { 443c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 4441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete referrer knowledge needs access check. 4451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4461bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Perform access and instantiable checks, will return true if access is ok or false if we're 4471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // going to have to check this at runtime (for example for class loaders). 448996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable(); 449996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (result) { 450c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeDoesntNeedAccessCheck(); 451996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 452c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->TypeNeedsAccessCheck(); 453996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } 454996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return result; 4551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 4561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 4574dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Class* ComputeReferrerClass(OatCompilationUnit* mUnit) { 4584dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile::MethodId& referrer_method_id = 4594dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->GetMethodId(mUnit->method_idx_); 460a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4614dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveType( 4624dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, referrer_method_id.class_idx_, 4634dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_cache_, mUnit->class_loader_); 4644dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien} 465a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4664dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) { 4674dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveField( 4684dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, field_idx, mUnit->dex_cache_, 4694dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, false); 470a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 471a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4724dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) { 4734dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien return mUnit->class_linker_->ResolveMethod( 4744dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien *mUnit->dex_file_, method_idx, mUnit->dex_cache_, 4754dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_loader_, true); 476a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 477a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 4784dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 4798cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao int& field_offset, bool& is_volatile, bool is_put) { 4801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 4811bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 4821bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 4831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 4844dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 4851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 4864dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 4871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve referring class then access check, failure to pass the 4881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Class* fields_class = resolved_field->GetDeclaringClass(); 4898cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() && 4908cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao fields_class != referrer_class; 4918cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (referrer_class != NULL && referrer_class->CanAccess(fields_class) && 4928cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) && 4938cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao !is_write_to_final_from_wrong_class) { 4941bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 4951bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 496c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedInstanceField(); 4971bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // Fast path. 4981bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 4991bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 5011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 5021bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 5031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 5041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 505c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedInstanceField(); 5061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 5071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 5094dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit, 5101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers int& field_offset, int& ssb_index, 5118cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool& is_referrers_class, bool& is_volatile, bool is_put) { 5121bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Conservative defaults 5131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = -1; 5141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers ssb_index = -1; 5151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = false; 5161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = true; 5171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Try to resolve field 5184dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Field* resolved_field = ComputeReferrerField(mUnit, field_idx); 5191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (resolved_field != NULL) { 520a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers DCHECK(resolved_field->IsStatic()); 5214dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 5221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class != NULL) { 5238cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao Class* fields_class = resolved_field->GetDeclaringClass(); 5248cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao if (fields_class == referrer_class) { 5251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_referrers_class = true; // implies no worrying about class initialization 5261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 5271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 528c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedLocalStaticField(); 5291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; // fast path 5301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } else { 5318cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal(); 5321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (referrer_class->CanAccess(fields_class) && 5338cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) && 5348cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao !is_write_to_final_from_wrong_class) { 5351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // We have the resolved field, we must make it into a ssbIndex for the referrer 5361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // in its static storage base (which may fail if it doesn't have a slot for it) 5374103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // TODO: for images we can elide the static storage base null check 5384103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // if we know there's a non-null entry in the image 5394dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien if (fields_class->GetDexCache() == mUnit->dex_cache_) { 5404103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // common case where the dex cache of both the referrer and the field are the same, 5414103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // no need to search the dex file 5424103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers ssb_index = fields_class->GetDexTypeIndex(); 5434103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers field_offset = resolved_field->GetOffset().Int32Value(); 5444103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers is_volatile = resolved_field->IsVolatile(); 545c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 5464103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers return true; 5474103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers } 5484103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers // Search dex file for localized ssb index 5491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); 5501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::StringId* string_id = 5514dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindStringId(descriptor); 5521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (string_id != NULL) { 5531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers const DexFile::TypeId* type_id = 5544dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id)); 5551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if(type_id != NULL) { 5561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // medium path, needs check of static storage base being initialized 5574dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id); 5581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers field_offset = resolved_field->GetOffset().Int32Value(); 5591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers is_volatile = resolved_field->IsVolatile(); 560c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedStaticField(); 5611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return true; 5621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 5681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers // Clean up any exception left by field/type resolution 5691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers Thread* thread = Thread::Current(); 5701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers if (thread->IsExceptionPending()) { 5711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers thread->ClearException(); 5721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers } 573c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedStaticField(); 5741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers return false; // Incomplete knowledge needs slow path. 5751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers} 5761bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers 577fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type, 578996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers int& vtable_idx) { 579a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = -1; 5804dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx); 581a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (resolved_method != NULL) { 5824dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien Class* referrer_class = ComputeReferrerClass(mUnit); 583a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class != NULL) { 584a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Class* methods_class = resolved_method->GetDeclaringClass(); 585a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (!referrer_class->CanAccess(methods_class) || 586a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers !referrer_class->CanAccessMember(methods_class, 587996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers resolved_method->GetAccessFlags())) { 588a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // The referring class can't access the resolved method, this may occur as a result of a 589a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // protected method being made public by implementing an interface that re-declares the 590a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // method public. Resort to the dex file to determine the correct class for the access check 5914dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); 592a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers methods_class = 5934dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien mUnit->class_linker_->ResolveType(dex_file, 5944dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien dex_file.GetMethodId(method_idx).class_idx_, 5954dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien referrer_class); 596a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 597a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 598a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (referrer_class->CanAccess(methods_class) && 599a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers referrer_class->CanAccessMember(methods_class, 600a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers resolved_method->GetAccessFlags())) { 601a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers vtable_idx = resolved_method->GetMethodIndex(); 602fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers if (type == kVirtual && (resolved_method->IsFinal() || methods_class->IsFinal())) { 603fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers stats_->ResolvedMethod(kVirtual); 604fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // Sharpen a virtual call into a direct call. The method_idx is into referrer's 605fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers // dex cache, check that this resolved method is where we expect it. 606fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method) 607fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers << PrettyMethod(resolved_method); 608fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers type = kDirect; 609fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers stats_->VirtualMadeDirect(); 610fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return true; 611fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers } else if (type != kSuper) { 612c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers // nothing left to do for static/direct/virtual/interface dispatch 613c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 614a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 615a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } else { 616a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // ensure the vtable index will be correct to dispatch in the vtable of the super class 617996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (referrer_class->IsSubClass(methods_class) && 618996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers vtable_idx < methods_class->GetVTable()->GetLength()) { 619c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->ResolvedMethod(type); 620a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return true; 621a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 622a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 623a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 624a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 625a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 626a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Clean up any exception left by method/type resolution 627a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers Thread* thread = Thread::Current(); 628a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers if (thread->IsExceptionPending()) { 629a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers thread->ClearException(); 630a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers } 631c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers stats_->UnresolvedMethod(type); 632a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers return false; // Incomplete knowledge needs slow path. 633a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers} 634a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 6355ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// Return true if the class should be skipped during compilation. We 6365ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// never skip classes in the boot class loader. However, if we have a 6375ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// non-boot class loader and we can resolve the class in the boot 6385ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// class loader, we do skip the class. This happens if an app bundles 6395ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// classes found in the boot classpath. Since at runtime we will 6405ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// select the class from the boot classpath, do not attempt to resolve 6415ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// or compile it now. 6425ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstromstatic bool SkipClass(const ClassLoader* class_loader, 6435ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile& dex_file, 6445ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile::ClassDef& class_def) { 6455ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (class_loader == NULL) { 6465ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 6475ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 6485ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 6495ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 6505ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, NULL); 6515ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (klass == NULL) { 6525ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Thread* self = Thread::Current(); 6535ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom CHECK(self->IsExceptionPending()); 6545ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom self->ClearException(); 6555ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 6565ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 6575ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return true; 6585ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom} 6595ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom 660d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstruct Context { 661d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker; 662d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const ClassLoader* class_loader; 663c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes Compiler* compiler; 664d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache; 665d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile* dex_file; 666d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 6679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 668d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughestypedef void Callback(Context* context, size_t index); 669d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 670d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesclass WorkerThread { 671d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes public: 6721e4092589f1400915e6213014da103aab8728ef6Elliott Hughes WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe, bool spawn) 6731e4092589f1400915e6213014da103aab8728ef6Elliott Hughes : spawn_(spawn), context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) { 6741e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 6751e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread"); 6761e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 677d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 678d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 679d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ~WorkerThread() { 6801e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (spawn_) { 6811e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown"); 6821e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 683d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 684d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 685d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 6861e4092589f1400915e6213014da103aab8728ef6Elliott Hughes static void* Go(void* arg) { 687d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg); 688d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Runtime* runtime = Runtime::Current(); 6891e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 6901e4092589f1400915e6213014da103aab8728ef6Elliott Hughes runtime->AttachCurrentThread("Compiler Worker", true); 6911e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 692d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->SetState(Thread::kRunnable); 693d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes worker->Run(); 6941e4092589f1400915e6213014da103aab8728ef6Elliott Hughes if (worker->spawn_) { 6951e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Thread::Current()->SetState(Thread::kNative); 6961e4092589f1400915e6213014da103aab8728ef6Elliott Hughes runtime->DetachCurrentThread(); 6971e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 698d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return NULL; 699d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 700d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 7011e4092589f1400915e6213014da103aab8728ef6Elliott Hughes void Go() { 7021e4092589f1400915e6213014da103aab8728ef6Elliott Hughes Go(this); 7031e4092589f1400915e6213014da103aab8728ef6Elliott Hughes } 7041e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 705d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes void Run() { 706d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t i = begin_; i < end_; i += stripe_) { 707d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes callback_(context_, i); 708aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 7099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 7109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 711d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes pthread_t pthread_; 7121e4092589f1400915e6213014da103aab8728ef6Elliott Hughes bool spawn_; 713d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 714d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context* context_; 715d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t begin_; 716d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t end_; 717d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Callback* callback_; 718d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t stripe_; 7191e4092589f1400915e6213014da103aab8728ef6Elliott Hughes 7201e4092589f1400915e6213014da103aab8728ef6Elliott Hughes friend void ForAll(Context*, size_t, size_t, Callback, size_t); 721d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 722d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 7235523ee070b005576c6f889415205d49ea77cf243Elliott Hughesvoid ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) { 7241e4092589f1400915e6213014da103aab8728ef6Elliott Hughes CHECK_GT(thread_count, 0U); 725845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 7261e4092589f1400915e6213014da103aab8728ef6Elliott Hughes std::vector<WorkerThread*> threads; 72781d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes for (size_t i = 0; i < thread_count; ++i) { 7281e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count, (i != 0))); 729d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 7301e4092589f1400915e6213014da103aab8728ef6Elliott Hughes threads[0]->Go(); 731d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 73281d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes // Switch to kVmWait while we're blocked waiting for the other threads to finish. 73381d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait); 73481d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes STLDeleteElements(&threads); 73581d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes} 736d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 737d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) { 738d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile& dex_file = *context->dex_file; 739d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 740845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 741845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 742845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 743845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 744845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 745845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 746845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 747d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 748d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (SkipClass(context->class_loader, dex_file, class_def)) { 749d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 750d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 751845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 752d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 753d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 754d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 755d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 756d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 757d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 758d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 759d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 760d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 761d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = context->class_linker; 762d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 763d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 764d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 765d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 766d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, true); 767d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 768d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 769d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 7700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 771d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 772d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 773d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 774d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 775d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, false); 776d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 777d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 778d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 77920cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 780d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 781d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 782d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 783d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 784d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, true); 785d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 786d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 787d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 788845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 789d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 790d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 791d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 792d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 793d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, false); 794d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 795d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 796d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 797845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 798d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 799d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 800d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 801d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 802d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 803d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveType(Context* context, size_t type_idx) { 804d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 805d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 806d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = context->class_linker; 807d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile& dex_file = *context->dex_file; 808d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Class* klass = class_linker->ResolveType(dex_file, type_idx, context->dex_cache, context->class_loader); 809d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 810d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 811d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 812d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 813d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 814d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 815d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) { 816d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 817d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 818d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 819d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Strings are easy in that they always are simply resolved to literals in the same file 820d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (image_ && image_classes_ == NULL) { 821d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // TODO: Add support for loading strings referenced by image_classes_ 822d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // See also Compiler::CanAssumeTypeIsPresentInDexCache. 823d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 824d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes class_linker->ResolveString(dex_file, string_idx, dex_cache); 82520cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 826ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings"); 8279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 828d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 829d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context context; 830d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_linker = class_linker; 831d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_loader = class_loader; 832d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_cache = dex_cache; 833d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_file = &dex_file; 834d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 8355523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_); 836ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 837d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 8385523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 839ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 8409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 8419ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 842ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Verify(const ClassLoader* class_loader, 843ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 844ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 845ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 84698eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 84798eacac683b78e60799323e8c7d59e7214808639jeffhao VerifyDexFile(class_loader, *dex_file); 84898eacac683b78e60799323e8c7d59e7214808639jeffhao } 84998eacac683b78e60799323e8c7d59e7214808639jeffhao} 85098eacac683b78e60799323e8c7d59e7214808639jeffhao 851d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void VerifyClass(Context* context, size_t class_def_index) { 852d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index); 853d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const char* descriptor = context->dex_file->GetClassDescriptor(class_def); 854d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Class* klass = context->class_linker->FindClass(descriptor, context->class_loader); 855d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 856d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 857d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 858d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 859d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 860d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 861d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 862d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_linker->VerifyClass(klass); 863d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 864d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 865d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 866d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 867d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 868d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // We want to try verification again at run-time, so move back into the resolved state. 869d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes klass->SetStatus(Class::kStatusResolved); 870d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 871d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 872d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass); 873d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 874d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 875d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 87698eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 877b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ | PROT_WRITE); 878d9cdfe91a4812a86d90a139569eac18e2b6de3fbElliott Hughes 879d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context context; 880d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_linker = Runtime::Current()->GetClassLinker(); 881d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_loader = class_loader; 882d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_file = &dex_file; 8835523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 884d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 885b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ); 886a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 887a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 888ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, 889ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 890ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 891ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 892a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(dex_file != NULL); 893a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader, *dex_file); 894a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 895a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 896a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 897a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 898a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 899ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 900ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 901a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 902a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 90327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass != NULL) { 90427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom class_linker->EnsureInitialized(klass, false); 9050755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom // record the final class status if necessary 9060755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom Class::Status status = klass->GetStatus(); 9070755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassReference ref(&dex_file, class_def_index); 908c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 9090755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CompiledClass* compiled_class = GetCompiledClass(ref); 9100755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (compiled_class == NULL) { 9110755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_class = new CompiledClass(status); 9120755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_classes_[ref] = compiled_class; 9130755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } else { 9140755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK_EQ(status, compiled_class->GetStatus()); 9150755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 91627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 91727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // clear any class not found or verification exceptions 91827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 919ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 920ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom 921ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 922ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 923ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 92427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass == NULL) { 92527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 92627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } else if (klass->IsInitialized()) { 927ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 928ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 92998eacac683b78e60799323e8c7d59e7214808639jeffhao } 93098eacac683b78e60799323e8c7d59e7214808639jeffhao} 93198eacac683b78e60799323e8c7d59e7214808639jeffhao 932ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader, 933ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 934ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 935ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 93683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 93783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CompileDexFile(class_loader, *dex_file); 93883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 93983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 94083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 941c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileClass(Context* context, size_t class_def_index) { 942c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const ClassLoader* class_loader = context->class_loader; 943c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile& dex_file = *context->dex_file; 944c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 9457f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9467f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#if defined(ART_USE_LLVM_COMPILER) 9477f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien compiler_llvm::CompilerLLVM* compiler_llvm = context->compiler->GetCompilerLLVM(); 9487f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9497f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien MutexLock GUARD(compiler_llvm->compiler_lock_); 9507f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien // TODO: Remove this. We should not lock the compiler_lock_ in CompileClass() 9517f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien // However, without this mutex lock, we will get segmentation fault. 9527f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#endif 9537f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9545ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (SkipClass(class_loader, dex_file, class_def)) { 9555ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return; 9565ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 957d1224c79631bd1801b067a0f212b91afa961a362jeffhao ClassReference ref(&dex_file, class_def_index); 958d1224c79631bd1801b067a0f212b91afa961a362jeffhao // Skip compiling classes with generic verifier failures since they will still fail at runtime 959d1224c79631bd1801b067a0f212b91afa961a362jeffhao if (verifier::DexVerifier::IsClassRejected(ref)) { 960d1224c79631bd1801b067a0f212b91afa961a362jeffhao return; 961d1224c79631bd1801b067a0f212b91afa961a362jeffhao } 9620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 9630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 9640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 9650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 9660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 9670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 9680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 9690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 9700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 9720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 9730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 9750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 9760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 977c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 978c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes it.GetMemberIndex(), class_loader, dex_file); 9790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9809ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 9810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 9820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 983c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 984c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes it.GetMemberIndex(), class_loader, dex_file); 9850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 9869ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 9870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 9887f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien 9897f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#if defined(ART_USE_LLVM_COMPILER) 9907f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien compiler_llvm->MaterializeIfThresholdReached(); 9917f76761d8705b7aa5b1fdd2fc1ebb80250992f4cLogan Chien#endif 9929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 9939ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 994c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 995c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes Context context; 996c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.class_loader = class_loader; 997c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.compiler = this; 998c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.dex_file = &dex_file; 9995523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_); 1000c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 1001c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 1002a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 1003a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers uint32_t method_idx, const ClassLoader* class_loader, 1004a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile& dex_file) { 1005f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 1006bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 10074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 10084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#if defined(ART_USE_LLVM_COMPILER) 10094dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien ClassLinker *class_linker = Runtime::Current()->GetClassLinker(); 10104dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien DexCache *dex_cache = class_linker->FindDexCache(dex_file); 10114dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1012dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien OatCompilationUnit oat_compilation_unit( 1013dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien class_loader, class_linker, dex_file, *dex_cache, code_item, 1014dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien method_idx, access_flags); 10154dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#endif 10164dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien 1017169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 101888894ee835411de72025cd8a5d8d111a6f2a004aLogan Chien#if defined(ART_USE_LLVM_COMPILER) 1019dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien compiled_method = compiler_llvm_->CompileNativeMethod(&oat_compilation_unit); 102088894ee835411de72025cd8a5d8d111a6f2a004aLogan Chien#else 1021169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file); 102288894ee835411de72025cd8a5d8d111a6f2a004aLogan Chien#endif 10233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 1024169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 10252cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 1026d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 1027dbe72bde0815ad53d26ec26da581c163d7928656Logan Chien compiled_method = compiler_llvm_->CompileDexMethod(&oat_compilation_unit); 1028d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#else 1029a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers compiled_method = oatCompileMethod(*this, code_item, access_flags, method_idx, class_loader, 1030a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers dex_file, kThumb2); 1031d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif 1032bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 1033bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 10343bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 10355abfa3ea35781464df8fae60aaf03f48a295e965buzbee if (duration_ns > MsToNs(100)) { 1036bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 10373bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 1038f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 1039f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 1040f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 10410571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 10420755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 1043c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 10440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_methods_[ref] = compiled_method; 10450755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 10462cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 10479baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 104845619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers uint32_t shorty_len; 104945619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); 1050169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 10510571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(is_static, shorty); 10520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 1053f04364f0ff789935d05490ee684f01c3de431780Logan Chien#if defined(ART_USE_LLVM_COMPILER) 1054f04364f0ff789935d05490ee684f01c3de431780Logan Chien compiled_invoke_stub = compiler_llvm_->CreateInvokeStub(is_static, shorty); 1055f04364f0ff789935d05490ee684f01c3de431780Logan Chien#else 10560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (instruction_set_ == kX86) { 105745619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers compiled_invoke_stub = ::art::x86::X86CreateInvokeStub(is_static, shorty, shorty_len); 10580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 10590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 10600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Generates invocation stub using ARM instruction set 106145619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers compiled_invoke_stub = ::art::arm::ArmCreateInvokeStub(is_static, shorty, shorty_len); 10620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1063f04364f0ff789935d05490ee684f01c3de431780Logan Chien#endif 1064f04364f0ff789935d05490ee684f01c3de431780Logan Chien 10650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 10660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InsertInvokeStub(is_static, shorty, compiled_invoke_stub); 10673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 10680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file); 10690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 107028ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 10710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 10720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::string key(shorty); 10730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (is_static) { 1074bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes key += "$"; // Must not be a shorty type character. 10750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 10760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return key; 10773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 10783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 10790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const { 1080c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1081955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 10820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 10830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 10843320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 10850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 10860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 10870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 10883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 10893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 10903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 10910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid Compiler::InsertInvokeStub(bool is_static, const char* shorty, 10920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub) { 1093c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 1094955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 10950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_invoke_stubs_[key] = compiled_invoke_stub; 10960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 10970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 10980755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const { 1099c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 11000755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 11010755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 11020755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 11030755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 11040755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 11050755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 11060755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 11070755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 11080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const { 1109c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 11100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 11110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 11123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 11132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 11143320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 11153320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 11169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 11179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1118e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) { 1119e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 1120e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1121e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CHECK(dex_file != NULL); 1122e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsDexFile(class_loader, *dex_file); 1123e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1124e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1125e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1126e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1127e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1128e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 1129e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 1130e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1131e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1132e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 1133e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (klass == NULL || !klass->IsVerified()) { 1134e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1135e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1136e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1137e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1138e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (class_data == NULL) { 1139e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom // empty class such as a marker interface 1140e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 1141e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1142e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassDataItemIterator it(dex_file, class_data); 1143e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextStaticField()) { 1144e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1145e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1146e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextInstanceField()) { 1147e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1148e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1149e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextDirectMethod()) { 1150e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1151e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, true); 1152e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1153e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1154e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1155e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextVirtualMethod()) { 1156e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 1157e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, false); 1158e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 1159e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 1160e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1161e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1162e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1163e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 1164e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) { 1165e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (method == NULL) { 1166e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 1167e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1168e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1169e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint16_t method_idx = method->GetDexMethodIndex(); 1170e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom MethodReference ref(&dex_file, method_idx); 1171e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CompiledMethod* compiled_method = GetCompiledMethod(ref); 1172e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (compiled_method == NULL) { 1173e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1174e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1175e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const std::vector<uint8_t>* gc_map = verifier::DexVerifier::GetGcMap(ref); 1176e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (gc_map == NULL) { 1177e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 1178e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 1179e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom compiled_method->SetGcMap(*gc_map); 1180e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 1181e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 11828b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#if defined(ART_USE_LLVM_COMPILER) 11838b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetElfFileName(std::string const& filename) { 11848b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien compiler_llvm_->SetElfFileName(filename); 11858b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 11868b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 11878b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) { 11888b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien compiler_llvm_->SetBitcodeFileName(filename); 11898b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien} 11908b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#endif 11918b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien 11929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 1193