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