compiler_driver.cc revision 5523ee070b005576c6f889415205d49ea77cf243
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" 28e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom#include "dex_verifier.h" 292cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom#include "jni_compiler.h" 309baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.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 379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 3911d1b0c31ddd710d26068da8e0e4621002205b4bElliott HughesCompiledMethod* oatCompileMethod(const Compiler& compiler, const DexFile::CodeItem* code_item, 4011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes uint32_t access_flags, uint32_t method_idx, 4111d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes const ClassLoader* class_loader, 4211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes const DexFile& dex_file, InstructionSet); 4311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 44c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm { 45bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledInvokeStub* ArmCreateInvokeStub(bool is_static, const char* shorty); 471cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type); 488add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 49c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 50c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 { 51bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 520571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CompiledInvokeStub* X86CreateInvokeStub(bool is_static, const char* shorty); 531cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type); 548add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes ByteArray* CreateJniDlsymLookupStub(); 55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 56e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 575523ee070b005576c6f889415205d49ea77cf243Elliott HughesCompiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count, 58ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* image_classes) 59aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom : instruction_set_(instruction_set), 60aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom jni_compiler_(instruction_set), 61c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_classes_lock_("compiled classes lock"), 62c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_methods_lock_("compiled method lock"), 63c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes compiled_invoke_stubs_lock_("compiled invoke stubs lock"), 64aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_(image), 655523ee070b005576c6f889415205d49ea77cf243Elliott Hughes thread_count_(thread_count), 664dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes image_classes_(image_classes) { 6725c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 68ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_) { 69ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(image_classes_ == NULL); 70ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 71c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 72c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 733320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() { 74c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 75c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 76c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_classes_); 77c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 78c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 79c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 80c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_methods_); 81c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes } 82c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes { 83c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 84c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes STLDeleteValues(&compiled_invoke_stubs_); 85bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 881cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, 891cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type) { 90ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 911cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return x86::X86CreateResolutionTrampoline(type); 92ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 93ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 94ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 951cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return arm::ArmCreateResolutionTrampoline(type); 96ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 97ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 98ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 998add92dcf59568c72c17e9a979948b1a7a0b1264Elliott HughesByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) { 100169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers switch (instruction_set) { 101169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kArm: 102169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kThumb2: 1038add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return arm::CreateJniDlsymLookupStub(); 104169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers case kX86: 1058add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes return x86::CreateJniDlsymLookupStub(); 106169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers default: 107ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes LOG(FATAL) << "Unknown InstructionSet: " << static_cast<int>(instruction_set); 108169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers return NULL; 109169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } 110169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers} 111169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers 112ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan RogersByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) { 113ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers if (instruction_set == kX86) { 114ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return x86::CreateAbstractMethodErrorStub(); 115ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } else { 116ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(instruction_set == kArm || instruction_set == kThumb2); 117ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers // Generates resolution stub using ARM instruction set 118ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers return arm::CreateAbstractMethodErrorStub(); 119ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 120ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 121ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 122254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilsonvoid Compiler::CompileAll(const ClassLoader* class_loader, 123ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 12425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 125ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 126601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("compiler"); 127601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 128601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 129601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 130ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Compile(class_loader, dex_files); 131601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("Compile"); 132601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 133ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 134601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PostCompile"); 135601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 136601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes if (timings.GetTotalNs() > MsToNs(1000)) { 137601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.Dump(); 138601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes } 1398a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 1408a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 1413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromvoid Compiler::CompileOne(const Method* method) { 14225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 143ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1448a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 145ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Find the dex_file 1470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 1480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); 149ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 150ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(&dex_file); 151ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 152601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes TimingLogger timings("CompileOne"); 153601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes PreCompile(class_loader, dex_files, timings); 154ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx = method->GetDexMethodIndex(); 156a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset()); 157a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file); 158ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 159ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom PostCompile(class_loader, dex_files); 1609ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 1619ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 162ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader, 163d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 164ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 165ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 1669ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 167d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ResolveDexFile(class_loader, *dex_file, timings); 1689ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 1699ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 1709ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 171ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PreCompile(const ClassLoader* class_loader, 172601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes const std::vector<const DexFile*>& dex_files, TimingLogger& timings) { 173d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Resolve(class_loader, dex_files, timings); 174601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Verify(class_loader, dex_files); 176601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.Verify"); 177601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes 178ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom InitializeClassesWithoutClinit(class_loader, dex_files); 179601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes timings.AddSplit("PreCompile.InitializeClassesWithoutClinit"); 180ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 181ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 182ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PostCompile(const ClassLoader* class_loader, 183ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 184e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMaps(class_loader, dex_files); 185ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom SetCodeAndDirectMethods(dex_files); 186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 187ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const { 189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_ == NULL) { 190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 192ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes_->find(descriptor) != image_classes_->end(); 193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom} 194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1956d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, 1966d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers uint32_t type_idx) const { 1976d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (!IsImage()) { 1986d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 1996d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2006d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers Class* resolved_class = dex_cache->GetResolvedTypes()->Get(type_idx); 2016d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (resolved_class == NULL) { 2026d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return false; 2036d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 2046d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return IsImageClass(ClassHelper(resolved_class).GetDescriptor()); 2056d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers} 2066d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 2075ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// Return true if the class should be skipped during compilation. We 2085ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// never skip classes in the boot class loader. However, if we have a 2095ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// non-boot class loader and we can resolve the class in the boot 2105ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// class loader, we do skip the class. This happens if an app bundles 2115ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// classes found in the boot classpath. Since at runtime we will 2125ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// select the class from the boot classpath, do not attempt to resolve 2135ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// or compile it now. 2145ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstromstatic bool SkipClass(const ClassLoader* class_loader, 2155ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile& dex_file, 2165ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const DexFile::ClassDef& class_def) { 2175ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (class_loader == NULL) { 2185ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 2195ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 2205ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 2215ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 2225ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, NULL); 2235ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (klass == NULL) { 2245ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom Thread* self = Thread::Current(); 2255ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom CHECK(self->IsExceptionPending()); 2265ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom self->ClearException(); 2275ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return false; 2285ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 2295ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return true; 2305ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom} 2315ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom 232d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstruct Context { 233d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker; 234d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const ClassLoader* class_loader; 235c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes Compiler* compiler; 236d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache; 237d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile* dex_file; 238d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 2399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 240d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughestypedef void Callback(Context* context, size_t index); 241d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 242d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesclass WorkerThread { 243d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes public: 244d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe) 245d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes : context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) { 246d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Init, this), "compiler worker thread"); 247d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 248d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 249d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ~WorkerThread() { 250d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown"); 251d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 252d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 253d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private: 254d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes static void* Init(void* arg) { 255d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg); 256d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Runtime* runtime = Runtime::Current(); 257d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes runtime->AttachCurrentThread("Compiler Worker", true); 258d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->SetState(Thread::kRunnable); 259d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes worker->Run(); 260d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->SetState(Thread::kNative); 261d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes runtime->DetachCurrentThread(); 262d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return NULL; 263d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 264d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 265d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes void Run() { 266d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t i = begin_; i < end_; i += stripe_) { 267d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes callback_(context_, i); 268aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 2699ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 2709ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 271d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes pthread_t pthread_; 272d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 273d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context* context_; 274d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t begin_; 275d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t end_; 276d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Callback* callback_; 277d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes size_t stripe_; 278d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}; 279d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 2805523ee070b005576c6f889415205d49ea77cf243Elliott Hughesvoid ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) { 28181d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes std::vector<WorkerThread*> threads; 282845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 28381d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes for (size_t i = 0; i < thread_count; ++i) { 28481d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count)); 285d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 286d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 28781d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes // Switch to kVmWait while we're blocked waiting for the other threads to finish. 28881d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait); 28981d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes STLDeleteElements(&threads); 29081d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes} 291d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 292d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) { 293d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile& dex_file = *context->dex_file; 294d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 295845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 296845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 297845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 298845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 299845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 300845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 301845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 302d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 303d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (SkipClass(context->class_loader, dex_file, class_def)) { 304d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 305d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 306845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 307d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Note the class_data pointer advances through the headers, 308d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // static fields, instance fields, direct methods, and virtual 309d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // methods. 310d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const byte* class_data = dex_file.GetClassData(class_def); 311d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (class_data == NULL) { 312d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // empty class such as a marker interface 313d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 314d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 315d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 316d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = context->class_linker; 317d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 318d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassDataItemIterator it(dex_file, class_data); 319d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextStaticField()) { 320d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 321d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, true); 322d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 323d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 324d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 3250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 326d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 327d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 328d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextInstanceField()) { 329d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, 330d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, false); 331d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (field == NULL) { 332d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 333d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 33420cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 335d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 336d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 337d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextDirectMethod()) { 338d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 339d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, true); 340d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 341d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 342d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 343845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 344d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 345d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 346d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes while (it.HasNextVirtualMethod()) { 347d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 348d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_loader, false); 349d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (method == NULL) { 350d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 351d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 352845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 353d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes it.Next(); 354d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 355d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DCHECK(!it.HasNext()); 356d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 357d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 358d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveType(Context* context, size_t type_idx) { 359d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Class derived values are more complicated, they require the linker and loader. 360d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 361d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = context->class_linker; 362d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile& dex_file = *context->dex_file; 363d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Class* klass = class_linker->ResolveType(dex_file, type_idx, context->dex_cache, context->class_loader); 364d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 365d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 366d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 367d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 368d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 369d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 370d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) { 371d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 372d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes DexCache* dex_cache = class_linker->FindDexCache(dex_file); 373d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 374d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // Strings are easy in that they always are simply resolved to literals in the same file 375d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (image_ && image_classes_ == NULL) { 376d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // TODO: Add support for loading strings referenced by image_classes_ 377d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // See also Compiler::CanAssumeTypeIsPresentInDexCache. 378d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 379d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes class_linker->ResolveString(dex_file, string_idx, dex_cache); 38020cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 381ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings"); 3829ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 383d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 384d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context context; 385d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_linker = class_linker; 386d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_loader = class_loader; 387d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_cache = dex_cache; 388d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_file = &dex_file; 389d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 3905523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_); 391ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types"); 392d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 3935523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_); 394ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields"); 3959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 3969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 397ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Verify(const ClassLoader* class_loader, 398ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 399ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 400ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 40198eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 40298eacac683b78e60799323e8c7d59e7214808639jeffhao VerifyDexFile(class_loader, *dex_file); 40398eacac683b78e60799323e8c7d59e7214808639jeffhao } 40498eacac683b78e60799323e8c7d59e7214808639jeffhao} 40598eacac683b78e60799323e8c7d59e7214808639jeffhao 406d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void VerifyClass(Context* context, size_t class_def_index) { 407d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index); 408d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes const char* descriptor = context->dex_file->GetClassDescriptor(class_def); 409d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Class* klass = context->class_linker->FindClass(descriptor, context->class_loader); 410d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass == NULL) { 411d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread* self = Thread::Current(); 412d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(self->IsExceptionPending()); 413d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes self->ClearException(); 414d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes return; 415d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 416d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsResolved()) << PrettyClass(klass); 417d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context->class_linker->VerifyClass(klass); 418d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 419d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (klass->IsErroneous()) { 420d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // ClassLinker::VerifyClass throws, which isn't useful in the compiler. 421d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(Thread::Current()->IsExceptionPending()); 422d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Thread::Current()->ClearException(); 423d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // We want to try verification again at run-time, so move back into the resolved state. 424d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes klass->SetStatus(Class::kStatusResolved); 425d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes } 426d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 427d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass); 428d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException()); 429d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes} 430d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 43198eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 432b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ | PROT_WRITE); 433d9cdfe91a4812a86d90a139569eac18e2b6de3fbElliott Hughes 434d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes Context context; 435d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_linker = Runtime::Current()->GetClassLinker(); 436d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.class_loader = class_loader; 437d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes context.dex_file = &dex_file; 4385523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_); 439d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 440b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao dex_file.ChangePermissions(PROT_READ); 441a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 442a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 443ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, 444ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 445ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 446ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 447a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(dex_file != NULL); 448a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader, *dex_file); 449a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 450a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 451a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 452a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 453a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 454ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 455ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 456a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 457a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 45827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass != NULL) { 45927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom class_linker->EnsureInitialized(klass, false); 4600755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom // record the final class status if necessary 4610755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom Class::Status status = klass->GetStatus(); 4620755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassReference ref(&dex_file, class_def_index); 463c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 4640755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CompiledClass* compiled_class = GetCompiledClass(ref); 4650755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (compiled_class == NULL) { 4660755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_class = new CompiledClass(status); 4670755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom compiled_classes_[ref] = compiled_class; 4680755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } else { 4690755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK_EQ(status, compiled_class->GetStatus()); 4700755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 47127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 47227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // clear any class not found or verification exceptions 47327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 474ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 475ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom 476ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 477ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 478ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 47927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (klass == NULL) { 48027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom Thread::Current()->ClearException(); 48127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } else if (klass->IsInitialized()) { 482ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 483ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 48498eacac683b78e60799323e8c7d59e7214808639jeffhao } 48598eacac683b78e60799323e8c7d59e7214808639jeffhao} 48698eacac683b78e60799323e8c7d59e7214808639jeffhao 487ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader, 488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const DexFile*>& dex_files) { 489ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 49183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 49283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CompileDexFile(class_loader, *dex_file); 49383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 49483db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 49583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 496c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileClass(Context* context, size_t class_def_index) { 497c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const ClassLoader* class_loader = context->class_loader; 498c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile& dex_file = *context->dex_file; 499c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 5005ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom if (SkipClass(class_loader, dex_file, class_def)) { 5015ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom return; 5025ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom } 5030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const byte* class_data = dex_file.GetClassData(class_def); 5040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { 5050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // empty class, probably a marker interface 5060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 5070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 5090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Skip fields 5100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 5110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 5140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile direct methods 5170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 518c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 519c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes it.GetMemberIndex(), class_loader, dex_file); 5200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 5220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Compile virtual methods 5230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 524c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(), 525c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes it.GetMemberIndex(), class_loader, dex_file); 5260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 5279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 5280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 5299ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 5309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 531c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 532c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes Context context; 533c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.class_loader = class_loader; 534c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.compiler = this; 535c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes context.dex_file = &dex_file; 5365523ee070b005576c6f889415205d49ea77cf243Elliott Hughes ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_); 537c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes} 538c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes 539a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 540a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers uint32_t method_idx, const ClassLoader* class_loader, 541a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers const DexFile& dex_file) { 542f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes CompiledMethod* compiled_method = NULL; 543bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns = NanoTime(); 544169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if ((access_flags & kAccNative) != 0) { 545169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file); 5463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(compiled_method != NULL); 547169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if ((access_flags & kAccAbstract) != 0) { 5482cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 549a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers compiled_method = oatCompileMethod(*this, code_item, access_flags, method_idx, class_loader, 550a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers dex_file, kThumb2); 551bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file); 552bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 5533bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers uint64_t duration_ns = NanoTime() - start_ns; 5545abfa3ea35781464df8fae60aaf03f48a295e965buzbee if (duration_ns > MsToNs(100)) { 555bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file) 5563bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers << " took " << PrettyDuration(duration_ns); 557f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes } 558f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes 559f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes if (compiled_method != NULL) { 5600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodReference ref(&dex_file, method_idx); 5610755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file); 562c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 5630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_methods_[ref] = compiled_method; 5640755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file); 5652cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 5669baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 5670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 568169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers bool is_static = (access_flags & kAccStatic) != 0; 5690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(is_static, shorty); 5700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (compiled_invoke_stub == NULL) { 5710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (instruction_set_ == kX86) { 57211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiled_invoke_stub = ::art::x86::X86CreateInvokeStub(is_static, shorty); 5730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 5740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 5750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers // Generates invocation stub using ARM instruction set 57611d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes compiled_invoke_stub = ::art::arm::ArmCreateInvokeStub(is_static, shorty); 5770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(compiled_invoke_stub != NULL); 5790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InsertInvokeStub(is_static, shorty, compiled_invoke_stub); 5803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 5810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file); 5820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 58328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers 5840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) { 5850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers std::string key(shorty); 5860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (is_static) { 587bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes key += "$"; // Must not be a shorty type character. 5880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 5890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return key; 5903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 5913320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 5920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const { 593c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 594955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string key(MakeInvokeStubKey(is_static, shorty)); 5950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); 5960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_invoke_stubs_.end()) { 5973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 5980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } else { 5990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(it->second != NULL); 6000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return it->second; 6013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom } 6023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 6033320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 6040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersvoid Compiler::InsertInvokeStub(bool is_static, const char* shorty, 6050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const CompiledInvokeStub* compiled_invoke_stub) { 606c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_invoke_stubs_lock_); 607955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string key(MakeInvokeStubKey(is_static, shorty)); 6080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers compiled_invoke_stubs_[key] = compiled_invoke_stub; 6090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers} 6100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 6110755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const { 612c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_classes_lock_); 6130755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom ClassTable::const_iterator it = compiled_classes_.find(ref); 6140755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom if (it == compiled_classes_.end()) { 6150755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return NULL; 6160755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom } 6170755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom CHECK(it->second != NULL); 6180755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom return it->second; 6190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom} 6200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 6210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const { 622c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes MutexLock mu(compiled_methods_lock_); 6230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers MethodTable::const_iterator it = compiled_methods_.find(ref); 6240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (it == compiled_methods_.end()) { 6253320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return NULL; 6262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 6273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom CHECK(it->second != NULL); 6283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom return it->second; 6299ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 6309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 631e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) { 632e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 633e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile* dex_file = dex_files[i]; 634e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CHECK(dex_file != NULL); 635e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsDexFile(class_loader, *dex_file); 636e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 637e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 638e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 639e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 640e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 641e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 642e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 643e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 644e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 645e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 646e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (klass == NULL || !klass->IsVerified()) { 647e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 648e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 649e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 650e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 651e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (class_data == NULL) { 652e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom // empty class such as a marker interface 653e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom continue; 654e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 655e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom ClassDataItemIterator it(dex_file, class_data); 656e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextStaticField()) { 657e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 658e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 659e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextInstanceField()) { 660e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 661e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 662e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextDirectMethod()) { 663e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 664e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, true); 665e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 666e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 667e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 668e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom while (it.HasNextVirtualMethod()) { 669e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, 670e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom class_loader, false); 671e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom SetGcMapsMethod(dex_file, method); 672e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom it.Next(); 673e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 674e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 675e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 676e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 677e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) { 678e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (method == NULL) { 679e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom Thread::Current()->ClearException(); 680e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 681e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 682e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom uint16_t method_idx = method->GetDexMethodIndex(); 683e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom MethodReference ref(&dex_file, method_idx); 684e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom CompiledMethod* compiled_method = GetCompiledMethod(ref); 685e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (compiled_method == NULL) { 686e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 687e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 688e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const std::vector<uint8_t>* gc_map = verifier::DexVerifier::GetGcMap(ref); 689e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom if (gc_map == NULL) { 690e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom return; 691e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom } 692e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom compiled_method->SetGcMap(*gc_map); 693e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom} 694e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 695ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::SetCodeAndDirectMethods(const std::vector<const DexFile*>& dex_files) { 696ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i != dex_files.size(); ++i) { 697ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = dex_files[i]; 69883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 6998a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom SetCodeAndDirectMethodsDexFile(*dex_file); 70083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 70183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 70283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 7038a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstromvoid Compiler::SetCodeAndDirectMethodsDexFile(const DexFile& dex_file) { 704ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers Runtime* runtime = Runtime::Current(); 705ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers ClassLinker* class_linker = runtime->GetClassLinker(); 70683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 7079cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods(); 7081caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { 70983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom Method* method = dex_cache->GetResolvedMethod(i); 7103320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom if (method == NULL || method->IsDirect()) { 7111cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type = Runtime::GetTrampolineType(method); 7121cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers ByteArray* res_trampoline = runtime->GetResolutionStubArray(type); 7133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom code_and_direct_methods->SetResolvedDirectMethodTrampoline(i, res_trampoline); 7149cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom } else { 7159cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom // TODO: we currently leave the entry blank for resolved 7169cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom // non-direct methods. we could put in an error stub. 71783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 71883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 71983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 72083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 7219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 722