compiler_driver.cc revision 90dc30f4b9967e850d0594e57dfa8e7cb0369575
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "compiler.h"
189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
19d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <vector>
20d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
21b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include <dlfcn.h>
2227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <sys/mman.h>
23d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <unistd.h>
2427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom
259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h"
261f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h"
279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "dex_cache.h"
289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h"
294dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#include "oat_compilation_unit.h"
303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
321f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
33b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes#include "space.h"
343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "stl_util.h"
35601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes#include "timing_logger.h"
36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/method_verifier.h"
379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
38059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__)
39059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#include <mach-o/dyld.h>
40059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif
41059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art {
439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
44c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm {
45bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  ByteArray* CreateAbstractMethodErrorStub();
461cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers  ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type);
478add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes  ByteArray* CreateJniDlsymLookupStub();
48c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao}
49c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 {
50bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  ByteArray* CreateAbstractMethodErrorStub();
511cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers  ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type);
528add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes  ByteArray* CreateJniDlsymLookupStub();
53e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
55996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic double Percentage(size_t x, size_t y) {
56398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes  return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y));
57996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers}
58996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
59996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogersstatic void DumpStat(size_t x, size_t y, const char* str) {
60996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (x == 0 && y == 0) {
61996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers    return;
62996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
63996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases";
64996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers}
65996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
66c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersclass AOTCompilationStats {
67c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers public:
68c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"),
69c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     types_in_dex_cache_(0), types_not_in_dex_cache_(0),
70c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
71c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     resolved_types_(0), unresolved_types_(0),
72c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     resolved_instance_fields_(0), unresolved_instance_fields_(0),
732ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers     resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0) {
742ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    for (size_t i = 0; i <= kMaxInvokeType; i++) {
75c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      resolved_methods_[i] = 0;
76c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      unresolved_methods_[i] = 0;
772ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      virtual_made_direct_[i] = 0;
782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      direct_calls_to_boot_[i] = 0;
792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      direct_methods_to_boot_[i] = 0;
80b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes    }
81c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void Dump() {
84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_types_, unresolved_types_, "types resolved");
87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers             "static fields resolved");
90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_,
91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers             "static fields local to a class");
92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
932ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    for (size_t i = 0; i <= kMaxInvokeType; i++) {
94c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      std::ostringstream oss;
952ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      oss << static_cast<InvokeType>(i) << " methods were AOT resolved";
96c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      if (virtual_made_direct_[i] > 0) {
982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        std::ostringstream oss2;
992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        oss2 << static_cast<InvokeType>(i) << " methods made direct";
1002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        DumpStat(virtual_made_direct_[i],
1012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i],
1022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 oss2.str().c_str());
1032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      }
1042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      if (direct_calls_to_boot_[i] > 0) {
1052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        std::ostringstream oss2;
1062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot";
1072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        DumpStat(direct_calls_to_boot_[i],
1082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i],
1092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 oss2.str().c_str());
1102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      }
1112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      if (direct_methods_to_boot_[i] > 0) {
1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        std::ostringstream oss2;
1132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot";
1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        DumpStat(direct_methods_to_boot_[i],
1152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i],
1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 oss2.str().c_str());
1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      }
118c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    }
119c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
120996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
121996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers// Allow lossy statistics in non-debug builds
122996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG
123996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK() MutexLock mu(stats_lock_)
124996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else
125996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK()
126996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif
127996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
128c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeInDexCache() {
129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    types_in_dex_cache_++;
131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
132996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
133c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeNotInDexCache() {
134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    types_not_in_dex_cache_++;
136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
137996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
138c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void StringInDexCache() {
139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    strings_in_dex_cache_++;
141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
142996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
143c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void StringNotInDexCache() {
144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    strings_not_in_dex_cache_++;
146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
147996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
148c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeDoesntNeedAccessCheck() {
149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_types_++;
151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
152996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
153c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeNeedsAccessCheck() {
154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_types_++;
156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
157996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
158c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedInstanceField() {
159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_instance_fields_++;
161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
162996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
163b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes  void UnresolvedInstanceField() {
164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_instance_fields_++;
166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
167996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
168c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedLocalStaticField() {
169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_local_static_fields_++;
171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
172996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
173c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedStaticField() {
174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_static_fields_++;
176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
177996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
178c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void UnresolvedStaticField() {
179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_static_fields_++;
181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
182996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
183c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedMethod(InvokeType type) {
184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DCHECK_LE(type, kMaxInvokeType);
185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
186c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_methods_[type]++;
187996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
188996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
189c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void UnresolvedMethod(InvokeType type) {
190c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DCHECK_LE(type, kMaxInvokeType);
191c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
192c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_methods_[type]++;
193996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
194c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
1952ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  void VirtualMadeDirect(InvokeType type) {
1962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    DCHECK_LE(type, kMaxInvokeType);
1972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    STATS_LOCK();
1982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    virtual_made_direct_[type]++;
1992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
2002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
2012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  void DirectCallsToBoot(InvokeType type) {
2022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    DCHECK_LE(type, kMaxInvokeType);
2032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    STATS_LOCK();
2042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    direct_calls_to_boot_[type]++;
2052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
2062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
2072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  void DirectMethodsToBoot(InvokeType type) {
2082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    DCHECK_LE(type, kMaxInvokeType);
209fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers    STATS_LOCK();
2102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    direct_methods_to_boot_[type]++;
211fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers  }
2122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
213c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private:
214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  Mutex stats_lock_;
215c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
216c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t types_in_dex_cache_;
217c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t types_not_in_dex_cache_;
218c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
219c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t strings_in_dex_cache_;
220c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t strings_not_in_dex_cache_;
221c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
222c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_types_;
223c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_types_;
224c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
225c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_instance_fields_;
226c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_instance_fields_;
227c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
228c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_local_static_fields_;
229c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_static_fields_;
230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_static_fields_;
231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
232c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_methods_[kMaxInvokeType + 1];
233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_methods_[kMaxInvokeType + 1];
2342ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  size_t virtual_made_direct_[kMaxInvokeType + 1];
2352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  size_t direct_calls_to_boot_[kMaxInvokeType + 1];
2362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  size_t direct_methods_to_boot_[kMaxInvokeType + 1];
237c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
238b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes  DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
239c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers};
240996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
241b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughesstatic std::string MakeCompilerSoName(InstructionSet instruction_set) {
242b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  // TODO: is the ARM/Thumb2 instruction set distinction really buying us anything,
243b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  // or just causing hassle like this?
244b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (instruction_set == kThumb2) {
245b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    instruction_set = kArm;
246b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
247b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
248059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Capitalize the instruction set, because that's what we do in the build system.
249b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  std::ostringstream instruction_set_name_os;
250b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  instruction_set_name_os << instruction_set;
251b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  std::string instruction_set_name(instruction_set_name_os.str());
252b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  for (size_t i = 0; i < instruction_set_name.size(); ++i) {
253b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    instruction_set_name[i] = toupper(instruction_set_name[i]);
254b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
255059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Bad things happen if we pull in the libartd-compiler to a libart dex2oat or vice versa,
257059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // because we end up with both libart and libartd in the same address space!
25867d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes  const char* suffix = (kIsDebugBuild ? "d" : "");
259059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
260059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Work out the filename for the compiler library.
261c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#if !defined(ART_USE_LLVM_COMPILER)
262059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  std::string library_name(StringPrintf("art%s-compiler-%s", suffix, instruction_set_name.c_str()));
263c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#else
264c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao  std::string library_name(StringPrintf("art%s-compiler-llvm", suffix));
265c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#endif
266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str()));
267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__)
269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find
270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the
271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // same work.
272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  uint32_t executable_path_length = 0;
273448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  _NSGetExecutablePath(NULL, &executable_path_length);
274448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  std::string path(executable_path_length, static_cast<char>(0));
275448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0);
276059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
277059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Strip the "/dex2oat".
278059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  size_t last_slash = path.find_last_of('/');
279059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  CHECK_NE(last_slash, std::string::npos) << path;
280059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  path.resize(last_slash);
281059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
282059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Strip the "/bin".
283059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  last_slash = path.find_last_of('/');
284059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  path.resize(last_slash);
285059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
286059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  filename = path + "/lib/" + filename;
287059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif
288059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  return filename;
289b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes}
290b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
29146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn>
29246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) {
29346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  Fn fn = reinterpret_cast<Fn>(dlsym(library, name));
29446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  if (fn == NULL) {
29546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes    LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror();
29646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  }
297059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn);
29846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  return fn;
29946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes}
30046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes
3015523ee070b005576c6f889415205d49ea77cf243Elliott HughesCompiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count,
302ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                   bool support_debugging, const std::set<std::string>* image_classes,
303ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                   bool dump_stats, bool dump_timings)
304aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    : instruction_set_(instruction_set),
305c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_classes_lock_("compiled classes lock"),
306c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_methods_lock_("compiled method lock"),
307c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_invoke_stubs_lock_("compiled invoke stubs lock"),
308aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      image_(image),
3095523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      thread_count_(thread_count),
310de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes      support_debugging_(support_debugging),
311c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      stats_(new AOTCompilationStats),
312ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom      dump_stats_(dump_stats),
313ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom      dump_timings_(dump_timings),
314b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes      image_classes_(image_classes),
315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes      compiler_library_(NULL),
31646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes      compiler_(NULL),
3176f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes      compiler_context_(NULL),
31846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes      jni_compiler_(NULL),
319f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien      create_invoke_stub_(NULL)
320f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#if defined(ART_USE_LLVM_COMPILER)
321f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien    , compiler_enable_auto_elf_loading_(NULL),
322f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien      compiler_get_method_code_addr_(NULL),
323f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien      compiler_get_method_invoke_stub_addr_(NULL)
324f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#endif
325f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien{
326c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao  std::string compiler_so_name(MakeCompilerSoName(instruction_set_));
327b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY);
328b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (compiler_library_ == NULL) {
329b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror();
330b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
331b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_;
332b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
333106b2a03be66748a25b9019e4c222cee498d559fLogan Chien#if defined(ART_USE_LLVM_COMPILER)
334106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  // Initialize compiler_context_
335106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  typedef void (*InitCompilerContextFn)(Compiler&);
336106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
337106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  InitCompilerContextFn init_compiler_context =
338106b2a03be66748a25b9019e4c222cee498d559fLogan Chien    FindFunction<void (*)(Compiler&)>(compiler_so_name,
339106b2a03be66748a25b9019e4c222cee498d559fLogan Chien                                      compiler_library_,
340106b2a03be66748a25b9019e4c222cee498d559fLogan Chien                                      "ArtInitCompilerContext");
341106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
342106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  init_compiler_context(*this);
343106b2a03be66748a25b9019e4c222cee498d559fLogan Chien#endif
344106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
3453fa1b7e7a7fc9785ba4e8335d730e5caf6343322Elliott Hughes  compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod");
34646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtJniCompileMethod");
34746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  create_invoke_stub_ = FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateInvokeStub");
348b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
349f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#if defined(ART_USE_LLVM_COMPILER)
350f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien  compiler_enable_auto_elf_loading_ = FindFunction<CompilerEnableAutoElfLoadingFn>(
351f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien      compiler_so_name, compiler_library_, "compilerLLVMEnableAutoElfLoading");
352f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien  compiler_get_method_code_addr_ = FindFunction<CompilerGetMethodCodeAddrFn>(
353f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien      compiler_so_name, compiler_library_, "compilerLLVMGetMethodCodeAddr");
354f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien  compiler_get_method_invoke_stub_addr_ = FindFunction<CompilerGetMethodInvokeStubAddrFn>(
355f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien      compiler_so_name, compiler_library_, "compilerLLVMGetMethodInvokeStubAddr");
356f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien#endif
357f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
35825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  CHECK(!Runtime::Current()->IsStarted());
359ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (!image_) {
360ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    CHECK(image_classes_ == NULL);
361ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
362c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao}
363c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao
3643320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() {
365c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
366c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    MutexLock mu(compiled_classes_lock_);
367c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_classes_);
368c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  }
369c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
370c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    MutexLock mu(compiled_methods_lock_);
371c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_methods_);
372c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  }
373c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
374c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    MutexLock mu(compiled_invoke_stubs_lock_);
375c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_invoke_stubs_);
376bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
377f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  {
378f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    MutexLock mu(compiled_methods_lock_);
379f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    STLDeleteElements(&code_to_patch_);
380f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  }
381f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  {
382f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    MutexLock mu(compiled_methods_lock_);
383f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    STLDeleteElements(&methods_to_patch_);
384f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  }
385c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#if defined(ART_USE_LLVM_COMPILER)
386c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao  CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_),
387c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao                                                          compiler_library_,
388c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao                                                          "compilerLLVMDispose");
389c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao  (*f)(*this);
390c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao#endif
391b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (compiler_library_ != NULL) {
392b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    VLOG(compiler) << "dlclose(" << compiler_library_ << ")";
393b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    dlclose(compiler_library_);
394b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
3953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
3963320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
3971cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set,
3981cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers                                          Runtime::TrampolineType type) {
399ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  if (instruction_set == kX86) {
4001cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    return x86::X86CreateResolutionTrampoline(type);
401ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  } else {
402ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    CHECK(instruction_set == kArm || instruction_set == kThumb2);
403ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    // Generates resolution stub using ARM instruction set
4041cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers    return arm::ArmCreateResolutionTrampoline(type);
405ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
406ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
407ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
4088add92dcf59568c72c17e9a979948b1a7a0b1264Elliott HughesByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
409169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  switch (instruction_set) {
410169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kArm:
411169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kThumb2:
4128add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes      return arm::CreateJniDlsymLookupStub();
413169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kX86:
4148add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes      return x86::CreateJniDlsymLookupStub();
415169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    default:
41649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
417169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers      return NULL;
418169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  }
419169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers}
420169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers
421ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan RogersByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
422ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  if (instruction_set == kX86) {
423ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    return x86::CreateAbstractMethodErrorStub();
424ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  } else {
425ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    CHECK(instruction_set == kArm || instruction_set == kThumb2);
426ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    // Generates resolution stub using ARM instruction set
427ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    return arm::CreateAbstractMethodErrorStub();
428ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
429ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
430ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
431254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilsonvoid Compiler::CompileAll(const ClassLoader* class_loader,
432ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                          const std::vector<const DexFile*>& dex_files) {
43325c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  DCHECK(!Runtime::Current()->IsStarted());
434ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
435601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  TimingLogger timings("compiler");
436601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
437601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  PreCompile(class_loader, dex_files, timings);
438601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
439ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  Compile(class_loader, dex_files);
440601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  timings.AddSplit("Compile");
441601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
442ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  PostCompile(class_loader, dex_files);
443601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  timings.AddSplit("PostCompile");
444601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
445ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) {
446601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes    timings.Dump();
447601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  }
448996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
449ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  if (dump_stats_) {
450ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom    stats_->Dump();
451ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  }
4528a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom}
4538a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom
4543320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromvoid Compiler::CompileOne(const Method* method) {
45525c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  DCHECK(!Runtime::Current()->IsStarted());
456ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
4578a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader();
458ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
4590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Find the dex_file
4600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
4610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
462ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  std::vector<const DexFile*> dex_files;
463ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  dex_files.push_back(&dex_file);
464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
465601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  TimingLogger timings("CompileOne");
466601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  PreCompile(class_loader, dex_files, timings);
467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
4680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  uint32_t method_idx = method->GetDexMethodIndex();
469a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers  const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset());
470a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers  CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file);
471ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
472ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  PostCompile(class_loader, dex_files);
4739ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
4749ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader,
476d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes                       const std::vector<const DexFile*>& dex_files, TimingLogger& timings) {
477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
478ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
4799ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    CHECK(dex_file != NULL);
480d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    ResolveDexFile(class_loader, *dex_file, timings);
4819ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
4829ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
4839ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
484ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PreCompile(const ClassLoader* class_loader,
485601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes                          const std::vector<const DexFile*>& dex_files, TimingLogger& timings) {
486d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Resolve(class_loader, dex_files, timings);
487601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  Verify(class_loader, dex_files);
489601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  timings.AddSplit("PreCompile.Verify");
490601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
491ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  InitializeClassesWithoutClinit(class_loader, dex_files);
492601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  timings.AddSplit("PreCompile.InitializeClassesWithoutClinit");
493ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
494ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
495ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::PostCompile(const ClassLoader* class_loader,
496ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                           const std::vector<const DexFile*>& dex_files) {
497e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  SetGcMaps(class_loader, dex_files);
498d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#if defined(ART_USE_LLVM_COMPILER)
499c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao  CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_),
500c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao                                                          compiler_library_,
501c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao                                                          "compilerLLVMMaterializeRemainder");
502c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao  (*f)(*this);
503d1fec81868a3567560a3868350e0a945248e925bShih-wei Liao#endif
504ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
505ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
506ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const {
507ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_ == NULL) {
508ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
509ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
510ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  return image_classes_->find(descriptor) != image_classes_->end();
511ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
512ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5136d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache,
514996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                                uint32_t type_idx) {
5156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (!IsImage()) {
516c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
5176d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return false;
5186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
5191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Class* resolved_class = dex_cache->GetResolvedType(type_idx);
5206d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (resolved_class == NULL) {
521c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
5226d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return false;
5236d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
524996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor());
525996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
526c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeInDexCache();
527996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
528c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
529996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
530996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
5316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
5326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
5331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache,
534996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                                  uint32_t string_idx) {
5351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // TODO: Add support for loading strings referenced by image_classes_
5361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // See also Compiler::ResolveDexFile
5371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
5381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // The following is a test saying that if we're building the image without a restricted set of
5391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // image classes then we can assume the string is present in the dex cache if it is there now
540996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL;
541996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
542c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->StringInDexCache();
543996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
544c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->StringNotInDexCache();
545996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
546996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
5471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
5481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
5491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache,
550996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                          const DexFile& dex_file, uint32_t type_idx) {
5511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Get type from dex cache assuming it was populated by the verifier
5521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Class* resolved_class = dex_cache->GetResolvedType(type_idx);
5531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_class == NULL) {
554c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
5551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Unknown class needs access checks.
5561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
5571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
5581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
5591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (referrer_class == NULL) {
560c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
5611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Incomplete referrer knowledge needs access check.
5621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
5631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Perform access check, will return true if access is ok or false if we're going to have to
5641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // check this at runtime (for example for class loaders).
565996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = referrer_class->CanAccess(resolved_class);
566996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
567c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeDoesntNeedAccessCheck();
568996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
569c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
570996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
571996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
5721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
5731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
5741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
5751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers                                                      const DexCache* dex_cache,
5761bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers                                                      const DexFile& dex_file,
577996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                                      uint32_t type_idx) {
5781bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Get type from dex cache assuming it was populated by the verifier.
5791bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Class* resolved_class = dex_cache->GetResolvedType(type_idx);
5801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_class == NULL) {
581c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
5821bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Unknown class needs access checks.
5831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
5841bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
5851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
5861bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (referrer_class == NULL) {
587c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
5881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Incomplete referrer knowledge needs access check.
5891bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
5901bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Perform access and instantiable checks, will return true if access is ok or false if we're
5911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // going to have to check this at runtime (for example for class loaders).
592996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
593996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
594c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeDoesntNeedAccessCheck();
595996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
596c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
597996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
598996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
5991bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6014dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Class* ComputeReferrerClass(OatCompilationUnit* mUnit) {
6024dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  const DexFile::MethodId& referrer_method_id =
6034dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    mUnit->dex_file_->GetMethodId(mUnit->method_idx_);
604a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  return mUnit->class_linker_->ResolveType(
6064dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    *mUnit->dex_file_, referrer_method_id.class_idx_,
6074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    mUnit->dex_cache_, mUnit->class_loader_);
6084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien}
609a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6104dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) {
6114dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  return mUnit->class_linker_->ResolveField(
6124dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    *mUnit->dex_file_, field_idx, mUnit->dex_cache_,
6134dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    mUnit->class_loader_, false);
614a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
615a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6164dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienstatic Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) {
6174dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  return mUnit->class_linker_->ResolveMethod(
6184dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    *mUnit->dex_file_, method_idx, mUnit->dex_cache_,
6194dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    mUnit->class_loader_, true);
620a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
621a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6224dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
6238cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao                                        int& field_offset, bool& is_volatile, bool is_put) {
6241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Conservative defaults
6251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  field_offset = -1;
6261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_volatile = true;
6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Try to resolve field
6284dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  Field* resolved_field = ComputeReferrerField(mUnit, field_idx);
6291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_field != NULL) {
6304dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    Class* referrer_class = ComputeReferrerClass(mUnit);
631e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers    if (referrer_class != NULL) {
632e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      Class* fields_class = resolved_field->GetDeclaringClass();
633e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      bool access_ok = referrer_class->CanAccess(fields_class) &&
634e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                       referrer_class->CanAccessMember(fields_class,
635e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                       resolved_field->GetAccessFlags());
636e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (!access_ok) {
637e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // The referring class can't access the resolved field, this may occur as a result of a
638e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // protected field being made public by a sub-class. Resort to the dex file to determine
639e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // the correct class for the access check.
640e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache());
641e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file,
642e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         dex_file.GetFieldId(field_idx).class_idx_,
643e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         referrer_class);
644e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        access_ok = referrer_class->CanAccess(dex_fields_class) &&
645e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                    referrer_class->CanAccessMember(dex_fields_class,
646e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                    resolved_field->GetAccessFlags());
647e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
648e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() &&
649e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          fields_class != referrer_class;
650e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (access_ok && !is_write_to_final_from_wrong_class) {
651e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        field_offset = resolved_field->GetOffset().Int32Value();
652e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        is_volatile = resolved_field->IsVolatile();
653e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        stats_->ResolvedInstanceField();
654e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        return true;  // Fast path.
655e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
6561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    }
6571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Clean up any exception left by field/type resolution
6591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Thread* thread = Thread::Current();
6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (thread->IsExceptionPending()) {
6611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      thread->ClearException();
6621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
663c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedInstanceField();
6641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  return false;  // Incomplete knowledge needs slow path.
6651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6674dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
6681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers                                      int& field_offset, int& ssb_index,
6698cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao                                      bool& is_referrers_class, bool& is_volatile, bool is_put) {
6701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Conservative defaults
6711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  field_offset = -1;
6721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  ssb_index = -1;
6731bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_referrers_class = false;
6741bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_volatile = true;
6751bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Try to resolve field
6764dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  Field* resolved_field = ComputeReferrerField(mUnit, field_idx);
6771bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_field != NULL) {
678a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    DCHECK(resolved_field->IsStatic());
6794dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    Class* referrer_class = ComputeReferrerClass(mUnit);
6801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    if (referrer_class != NULL) {
6818cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao      Class* fields_class = resolved_field->GetDeclaringClass();
6828cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao      if (fields_class == referrer_class) {
6831bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        is_referrers_class = true;  // implies no worrying about class initialization
6841bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        field_offset = resolved_field->GetOffset().Int32Value();
6851bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        is_volatile = resolved_field->IsVolatile();
686c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers        stats_->ResolvedLocalStaticField();
6871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        return true;  // fast path
6881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      } else {
689e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        bool access_ok = referrer_class->CanAccess(fields_class) &&
690e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                         referrer_class->CanAccessMember(fields_class,
691e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         resolved_field->GetAccessFlags());
692e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        if (!access_ok) {
693e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // The referring class can't access the resolved field, this may occur as a result of a
694e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // protected field being made public by a sub-class. Resort to the dex file to determine
695e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // the correct class for the access check. Don't change the field's class as that is
696e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // used to identify the SSB.
697e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache());
698e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          Class* dex_fields_class =
699e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers              mUnit->class_linker_->ResolveType(dex_file,
700e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                dex_file.GetFieldId(field_idx).class_idx_,
701e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                referrer_class);
702e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          access_ok = referrer_class->CanAccess(dex_fields_class) &&
703e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                      referrer_class->CanAccessMember(dex_fields_class,
704e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                      resolved_field->GetAccessFlags());
705e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        }
7068cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao        bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal();
707e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        if (access_ok && !is_write_to_final_from_wrong_class) {
7081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          // We have the resolved field, we must make it into a ssbIndex for the referrer
7091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          // in its static storage base (which may fail if it doesn't have a slot for it)
7104103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          // TODO: for images we can elide the static storage base null check
7114103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          // if we know there's a non-null entry in the image
7124dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien          if (fields_class->GetDexCache() == mUnit->dex_cache_) {
7134103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            // common case where the dex cache of both the referrer and the field are the same,
7144103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            // no need to search the dex file
7154103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            ssb_index = fields_class->GetDexTypeIndex();
7164103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            field_offset = resolved_field->GetOffset().Int32Value();
7174103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            is_volatile = resolved_field->IsVolatile();
718c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers            stats_->ResolvedStaticField();
7194103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            return true;
7204103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          }
721e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // Search dex file for localized ssb index, may fail if field's class is a parent
722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // of the class mentioned in the dex file and there is no dex cache entry.
7231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor());
7241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          const DexFile::StringId* string_id =
7254dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien          mUnit->dex_file_->FindStringId(descriptor);
7261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          if (string_id != NULL) {
7271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers            const DexFile::TypeId* type_id =
7284dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien               mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id));
729b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes            if (type_id != NULL) {
7301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              // medium path, needs check of static storage base being initialized
7314dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien              ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id);
7321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              field_offset = resolved_field->GetOffset().Int32Value();
7331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              is_volatile = resolved_field->IsVolatile();
734c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers              stats_->ResolvedStaticField();
7351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              return true;
7361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers            }
7371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          }
7381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        }
7391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      }
7401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    }
7411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
7421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Clean up any exception left by field/type resolution
7431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  Thread* thread = Thread::Current();
7441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (thread->IsExceptionPending()) {
7451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      thread->ClearException();
7461bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
747c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedStaticField();
7481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  return false;  // Incomplete knowledge needs slow path.
7491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
7501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
7512ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogersvoid Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, Method* method,
7522ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                             uintptr_t& direct_code, uintptr_t& direct_method) {
7532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_code = 0;
7542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_method = 0;
7552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (sharp_type != kStatic && sharp_type != kDirect) {
7562ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
7572ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
7582ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL;
7592ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (!method_code_in_boot) {
7602ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
7612ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
7622ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized();
7632ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (has_clinit_trampoline) {
7642ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
7652ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
7662ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  stats_->DirectCallsToBoot(type);
7672ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  stats_->DirectMethodsToBoot(type);
7683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
7693fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  if (compiling_boot) {
7700637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom    const bool kSupportBootImageFixup = true;
7713fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    if (kSupportBootImageFixup) {
7723fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      MethodHelper mh(method);
7733fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      if (IsImageClass(mh.GetDeclaringClassDescriptor())) {
7740637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        // We can only branch directly to Methods that are resolved in the DexCache.
7750637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        // Otherwise we won't invoke the resolution trampoline.
7763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers        direct_method = -1;
7770637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        direct_code = -1;
7783fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      }
7793fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    }
7803fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  } else {
7813fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    if (Runtime::Current()->GetHeap()->GetImageSpace()->Contains(method)) {
7823fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      direct_method = reinterpret_cast<uintptr_t>(method);
7833fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    }
7843fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    direct_code = reinterpret_cast<uintptr_t>(method->GetCode());
7852ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
7862ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers}
7872ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
788fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type,
7892ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                 int& vtable_idx, uintptr_t& direct_code,
7902ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                 uintptr_t& direct_method) {
791a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  vtable_idx = -1;
7922ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_code = 0;
7932ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_method = 0;
7944dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien  Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx);
795a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  if (resolved_method != NULL) {
7964dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien    Class* referrer_class = ComputeReferrerClass(mUnit);
797a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    if (referrer_class != NULL) {
798a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      Class* methods_class = resolved_method->GetDeclaringClass();
799a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      if (!referrer_class->CanAccess(methods_class) ||
800a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          !referrer_class->CanAccessMember(methods_class,
801996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                           resolved_method->GetAccessFlags())) {
802a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // The referring class can't access the resolved method, this may occur as a result of a
803a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // protected method being made public by implementing an interface that re-declares the
804a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // method public. Resort to the dex file to determine the correct class for the access check
8054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien        const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache());
806a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        methods_class =
8074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien            mUnit->class_linker_->ResolveType(dex_file,
8084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien                                              dex_file.GetMethodId(method_idx).class_idx_,
8094dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien                                              referrer_class);
810a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      }
811a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      if (referrer_class->CanAccess(methods_class) &&
812a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          referrer_class->CanAccessMember(methods_class,
813a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers                                          resolved_method->GetAccessFlags())) {
814a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        vtable_idx = resolved_method->GetMethodIndex();
815f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers        const bool kEnableSharpening = true;
8162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        // Sharpen a virtual call into a direct call when the target is known.
8172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() ||
8182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                                methods_class->IsFinal());
8192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        // ensure the vtable index will be correct to dispatch in the vtable of the super class
8204155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao        can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class &&
8212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                      referrer_class->IsSubClass(methods_class) &&
8224155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao                                      vtable_idx < methods_class->GetVTable()->GetLength() &&
8234155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao                                      methods_class->GetVTable()->Get(vtable_idx) == resolved_method);
8242ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        if (kEnableSharpening && can_sharpen) {
8252ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          stats_->ResolvedMethod(type);
826fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          // Sharpen a virtual call into a direct call. The method_idx is into referrer's
827fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          // dex cache, check that this resolved method is where we expect it.
828fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method)
829fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers            << PrettyMethod(resolved_method);
8302ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          stats_->VirtualMadeDirect(type);
8312ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method);
832fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          type = kDirect;
833fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          return true;
8342ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        } else if (type == kSuper) {
8352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          // Unsharpened super calls are suspicious so go slowpath.
8362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        } else {
837c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers          stats_->ResolvedMethod(type);
8382ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method);
839a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          return true;
840a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        }
841a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      }
842a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    }
843a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  }
844a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  // Clean up any exception left by method/type resolution
845a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  Thread* thread = Thread::Current();
846a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  if (thread->IsExceptionPending()) {
847a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      thread->ClearException();
848a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  }
849c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedMethod(type);
850a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  return false;  // Incomplete knowledge needs slow path.
851a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
852a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
853f582258f0e296223a091fd64231a203ad71e9649Brian Carlstromvoid Compiler::AddCodePatch(DexCache* dex_cache,
854f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            const DexFile* dex_file,
855f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t referrer_method_idx,
856f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t referrer_access_flags,
857f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t target_method_idx,
858f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            bool target_is_direct,
8593fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers                            size_t literal_offset) {
8603fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  MutexLock mu(compiled_methods_lock_);
861f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  code_to_patch_.push_back(new PatchInformation(dex_cache,
862f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                dex_file,
863f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                referrer_method_idx,
864f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                referrer_access_flags,
865f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                target_method_idx,
866f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                target_is_direct,
867f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                literal_offset));
8683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers}
869f582258f0e296223a091fd64231a203ad71e9649Brian Carlstromvoid Compiler::AddMethodPatch(DexCache* dex_cache,
870f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              const DexFile* dex_file,
871f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t referrer_method_idx,
872f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t referrer_access_flags,
873f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t target_method_idx,
874f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              bool target_is_direct,
8753fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers                              size_t literal_offset) {
8763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  MutexLock mu(compiled_methods_lock_);
877f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  methods_to_patch_.push_back(new PatchInformation(dex_cache,
878f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   dex_file,
879f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   referrer_method_idx,
880f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   referrer_access_flags,
881f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   target_method_idx,
882f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   target_is_direct,
883f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   literal_offset));
8843fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers}
8853fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers
8865ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// Return true if the class should be skipped during compilation. We
8875ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// never skip classes in the boot class loader. However, if we have a
8885ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// non-boot class loader and we can resolve the class in the boot
8895ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// class loader, we do skip the class. This happens if an app bundles
8905ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// classes found in the boot classpath. Since at runtime we will
8915ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// select the class from the boot classpath, do not attempt to resolve
8925ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom// or compile it now.
8935ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstromstatic bool SkipClass(const ClassLoader* class_loader,
8945ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom                      const DexFile& dex_file,
8955ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom                      const DexFile::ClassDef& class_def) {
8965ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  if (class_loader == NULL) {
8975ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom    return false;
8985ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  }
8995ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  const char* descriptor = dex_file.GetClassDescriptor(class_def);
9005ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
9015ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  Class* klass = class_linker->FindClass(descriptor, NULL);
9025ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  if (klass == NULL) {
9035ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom    Thread* self = Thread::Current();
9045ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom    CHECK(self->IsExceptionPending());
9055ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom    self->ClearException();
9065ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom    return false;
9075ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  }
9085ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  return true;
9095ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom}
9105ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom
911731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstromclass Context {
912731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public:
913731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Context(ClassLinker* class_linker,
914731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom          const ClassLoader* class_loader,
915731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom          Compiler* compiler,
916731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom          DexCache* dex_cache,
917731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom          const DexFile* dex_file)
918731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    : class_linker_(class_linker),
919731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      class_loader_(class_loader),
920731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      compiler_(compiler),
921731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      dex_cache_(dex_cache),
922731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      dex_file_(dex_file) {}
923731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom
924731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* GetClassLinker() {
925731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(class_linker_ != NULL);
926731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return class_linker_;
927731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
928731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const ClassLoader* GetClassLoader() {
929731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return class_loader_;
930731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
931731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Compiler* GetCompiler() {
932731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(compiler_ != NULL);
933731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return compiler_;
934731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
935731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  DexCache* GetDexCache() {
936731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(dex_cache_ != NULL);
937731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return dex_cache_;
938731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
939731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile* GetDexFile() {
940731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(dex_file_ != NULL);
941731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return dex_file_;
942731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
943731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom
944731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom private:
945731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* class_linker_;
946731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const ClassLoader* class_loader_;
947731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Compiler* compiler_;
948731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  DexCache* dex_cache_;
949731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile* dex_file_;
950d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes};
9519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
952d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughestypedef void Callback(Context* context, size_t index);
953d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
954d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesclass WorkerThread {
955d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes public:
9561e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe, bool spawn)
9571e4092589f1400915e6213014da103aab8728ef6Elliott Hughes      : spawn_(spawn), context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) {
9581e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    if (spawn_) {
9591e4092589f1400915e6213014da103aab8728ef6Elliott Hughes      CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread");
9601e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    }
961d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
962d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
963d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ~WorkerThread() {
9641e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    if (spawn_) {
9651e4092589f1400915e6213014da103aab8728ef6Elliott Hughes      CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown");
9661e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    }
967d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
968d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
969d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private:
9701e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  static void* Go(void* arg) {
971d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg);
972d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Runtime* runtime = Runtime::Current();
9731e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    if (worker->spawn_) {
974462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes      runtime->AttachCurrentThread("Compiler Worker", true, NULL);
9751e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    }
97634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    Thread::Current()->SetState(kRunnable);
977d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    worker->Run();
9781e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    if (worker->spawn_) {
97934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes      Thread::Current()->SetState(kNative);
9801e4092589f1400915e6213014da103aab8728ef6Elliott Hughes      runtime->DetachCurrentThread();
9811e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    }
982d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return NULL;
983d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
984d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
9851e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  void Go() {
9861e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    Go(this);
9871e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  }
9881e4092589f1400915e6213014da103aab8728ef6Elliott Hughes
989d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  void Run() {
99064277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom    Thread* self = Thread::Current();
991d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    for (size_t i = begin_; i < end_; i += stripe_) {
992d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      callback_(context_, i);
99364277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom      CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException()) << " " << i;
994aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
9959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
9969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
997d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  pthread_t pthread_;
9981e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  bool spawn_;
999d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1000d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Context* context_;
1001d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  size_t begin_;
1002d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  size_t end_;
1003d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Callback* callback_;
1004d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  size_t stripe_;
10051e4092589f1400915e6213014da103aab8728ef6Elliott Hughes
10061e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  friend void ForAll(Context*, size_t, size_t, Callback, size_t);
1007d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes};
1008d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
10095523ee070b005576c6f889415205d49ea77cf243Elliott Hughesvoid ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) {
101064277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom  Thread* self = Thread::Current();
101164277f38032208a0c1081ff9e466c04009b96383Brian Carlstrom  CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
10121e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  CHECK_GT(thread_count, 0U);
1013845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom
10141e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  std::vector<WorkerThread*> threads;
101581d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes  for (size_t i = 0; i < thread_count; ++i) {
10161e4092589f1400915e6213014da103aab8728ef6Elliott Hughes    threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count, (i != 0)));
1017d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
10181e4092589f1400915e6213014da103aab8728ef6Elliott Hughes  threads[0]->Go();
1019d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
102081d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes  // Switch to kVmWait while we're blocked waiting for the other threads to finish.
102134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  ScopedThreadStateChange tsc(self, kVmWait);
102281d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes  STLDeleteElements(&threads);
102381d9151c884a548ea2ff843a49704e1aaf9fe64fElliott Hughes}
1024d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1025d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) {
1026731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile& dex_file = *context->GetDexFile();
1027d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1028845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // Method and Field are the worst. We can't resolve without either
1029845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // context from the code use (to disambiguate virtual vs direct
1030845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // method and instance vs static field) or from class
1031845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // definitions. While the compiler will resolve what it can as it
1032845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // needs it, here we try to resolve fields and methods used in class
1033845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // definitions, since many of them many never be referenced by
1034845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // generated code.
1035d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1036731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  if (SkipClass(context->GetClassLoader(), dex_file, class_def)) {
1037d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1038d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1039845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom
1040d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Note the class_data pointer advances through the headers,
1041d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // static fields, instance fields, direct methods, and virtual
1042d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // methods.
1043d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  const byte* class_data = dex_file.GetClassData(class_def);
1044d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (class_data == NULL) {
1045d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // empty class such as a marker interface
1046d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1047d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1048d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Thread* self = Thread::Current();
1049731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* class_linker = context->GetClassLinker();
1050d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1051d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ClassDataItemIterator it(dex_file, class_data);
1052d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextStaticField()) {
1053d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
1054731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                              context->GetClassLoader(), true);
1055d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (field == NULL) {
1056d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1057d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
10580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    }
1059d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1060d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1061d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextInstanceField()) {
1062d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
1063731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                              context->GetClassLoader(), false);
1064d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (field == NULL) {
1065d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1066d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
106720cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom    }
1068d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1069d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1070d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextDirectMethod()) {
1071d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
1072731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                                 context->GetClassLoader(), true);
1073d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (method == NULL) {
1074d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1075d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
1076845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom    }
1077d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1078d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1079d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextVirtualMethod()) {
1080d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
1081731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                                 context->GetClassLoader(), false);
1082d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (method == NULL) {
1083d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1084d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
1085845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom    }
1086d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1087d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1088d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  DCHECK(!it.HasNext());
1089d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1090d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1091d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void ResolveType(Context* context, size_t type_idx) {
1092d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Class derived values are more complicated, they require the linker and loader.
1093d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Thread* self = Thread::Current();
1094731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Class* klass = context->GetClassLinker()->ResolveType(*context->GetDexFile(),
1095731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                                        type_idx,
1096731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                                        context->GetDexCache(),
1097731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                                        context->GetClassLoader());
1098d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass == NULL) {
1099d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(self->IsExceptionPending());
1100d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread::Current()->ClearException();
1101d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1102d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1103d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1104d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) {
1105d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1106d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1107d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1108d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Strings are easy in that they always are simply resolved to literals in the same file
1109d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (image_ && image_classes_ == NULL) {
1110d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // TODO: Add support for loading strings referenced by image_classes_
1111d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // See also Compiler::CanAssumeTypeIsPresentInDexCache.
1112d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) {
1113d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      class_linker->ResolveString(dex_file, string_idx, dex_cache);
111420cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom    }
1115ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes    timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings");
11169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
1117d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1118731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Context context(class_linker, class_loader, this, dex_cache, &dex_file);
11195523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_);
1120ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes  timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types");
1121d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
11225523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
1123ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes  timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields");
11249ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
11259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
1126ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Verify(const ClassLoader* class_loader,
1127ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                      const std::vector<const DexFile*>& dex_files) {
1128ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1129ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
113098eacac683b78e60799323e8c7d59e7214808639jeffhao    CHECK(dex_file != NULL);
113198eacac683b78e60799323e8c7d59e7214808639jeffhao    VerifyDexFile(class_loader, *dex_file);
113298eacac683b78e60799323e8c7d59e7214808639jeffhao  }
113398eacac683b78e60799323e8c7d59e7214808639jeffhao}
113498eacac683b78e60799323e8c7d59e7214808639jeffhao
1135d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughesstatic void VerifyClass(Context* context, size_t class_def_index) {
1136731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
1137731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def);
1138731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Class* klass = context->GetClassLinker()->FindClass(descriptor, context->GetClassLoader());
1139d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass == NULL) {
1140d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread* self = Thread::Current();
1141d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(self->IsExceptionPending());
1142d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    self->ClearException();
1143f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao
1144f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    /*
1145f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * At compile time, we can still structurally verify the class even if FindClass fails.
1146f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * This is to ensure the class is structurally sound for compilation. An unsound class
1147f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * will be rejected by the verifier and later skipped during compilation in the compiler.
1148f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     */
1149f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    std::string error_msg;
1150776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    if (!verifier::MethodVerifier::VerifyClass(context->GetDexFile(), context->GetDexCache(),
1151731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom        context->GetClassLoader(), class_def_index, error_msg)) {
1152731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
1153f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao      LOG(ERROR) << "Verification failed on class "
1154731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                 << PrettyDescriptor(context->GetDexFile()->GetClassDescriptor(class_def))
1155f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao                 << " because: " << error_msg;
1156f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    }
1157d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1158d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1159d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  CHECK(klass->IsResolved()) << PrettyClass(klass);
1160731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  context->GetClassLinker()->VerifyClass(klass);
1161d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1162d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass->IsErroneous()) {
1163d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1164d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(Thread::Current()->IsExceptionPending());
1165d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread::Current()->ClearException();
11661ac29447d6053b142f257330d6e237660076911ejeffhao    art::Compiler::ClassReference ref(context->GetDexFile(), class_def_index);
1167776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    if (!verifier::MethodVerifier::IsClassRejected(ref)) {
11681ac29447d6053b142f257330d6e237660076911ejeffhao      // If the erroneous class wasn't rejected by the verifier, it was a soft error. We want
11691ac29447d6053b142f257330d6e237660076911ejeffhao      // to try verification again at run-time, so move back into the resolved state.
11701ac29447d6053b142f257330d6e237660076911ejeffhao      klass->SetStatus(Class::kStatusResolved);
11711ac29447d6053b142f257330d6e237660076911ejeffhao    }
1172d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1173d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
11741ac29447d6053b142f257330d6e237660076911ejeffhao  CHECK(klass->IsVerified() || klass->IsResolved() || klass->IsErroneous()) << PrettyClass(klass);
1175d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
1176d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1177d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
117898eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
1179b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao  dex_file.ChangePermissions(PROT_READ | PROT_WRITE);
1180d9cdfe91a4812a86d90a139569eac18e2b6de3fbElliott Hughes
1181731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1182731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Context context(class_linker, class_loader, this, class_linker->FindDexCache(dex_file), &dex_file);
11835523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
1184d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1185b4df5146854c42bf03c4ca02f441b6db73bfde0cjeffhao  dex_file.ChangePermissions(PROT_READ);
1186a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom}
1187a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom
1188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader,
1189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                                              const std::vector<const DexFile*>& dex_files) {
1190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
1192a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom    CHECK(dex_file != NULL);
1193a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom    InitializeClassesWithoutClinit(class_loader, *dex_file);
1194a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom  }
1195a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom}
1196a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom
1197a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) {
1198a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1199ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom  for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
1200ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1201a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom    const char* descriptor = dex_file.GetClassDescriptor(class_def);
1202a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom    Class* klass = class_linker->FindClass(descriptor, class_loader);
120327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    if (klass != NULL) {
12041ac29447d6053b142f257330d6e237660076911ejeffhao      if (klass->IsVerified()) {
12051ac29447d6053b142f257330d6e237660076911ejeffhao        // Only try to initialize classes that were successfully verified.
12060045a290e6b79a274250e3112880c04bde437d4aIan Rogers        bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
12070045a290e6b79a274250e3112880c04bde437d4aIan Rogers        bool can_init_static_fields = compiling_boot &&
12080045a290e6b79a274250e3112880c04bde437d4aIan Rogers            IsImageClass(descriptor);
12090045a290e6b79a274250e3112880c04bde437d4aIan Rogers        class_linker->EnsureInitialized(klass, false, can_init_static_fields);
12101ac29447d6053b142f257330d6e237660076911ejeffhao      }
12110755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      // record the final class status if necessary
12120755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      Class::Status status = klass->GetStatus();
12130755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      ClassReference ref(&dex_file, class_def_index);
1214c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      MutexLock mu(compiled_classes_lock_);
12150755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      CompiledClass* compiled_class = GetCompiledClass(ref);
12160755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      if (compiled_class == NULL) {
12170755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom        compiled_class = new CompiledClass(status);
1218a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes        compiled_classes_.Put(ref, compiled_class);
12190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      } else {
12200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom        DCHECK_EQ(status, compiled_class->GetStatus());
12210755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      }
122227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    }
122327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    // clear any class not found or verification exceptions
122427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    Thread::Current()->ClearException();
1225ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom  }
1226ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom
1227ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom  DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1228ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom  for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) {
1229ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom    Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
123027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    if (klass == NULL) {
123127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom      Thread::Current()->ClearException();
123227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    } else if (klass->IsInitialized()) {
1233ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom      dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass);
1234ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom    }
123598eacac683b78e60799323e8c7d59e7214808639jeffhao  }
123698eacac683b78e60799323e8c7d59e7214808639jeffhao}
123798eacac683b78e60799323e8c7d59e7214808639jeffhao
123890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao// TODO: This class shares some implementation with WorkerThread. We don't want
123990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao// to perturb the non-LLVM side at the same time. Staging the refactoring for
124090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao// the future.
124190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liaoclass DexFilesWorkerThread {
124290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao public:
124390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  DexFilesWorkerThread(Context *worker_context, Callback class_callback,
124490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                       const std::vector<const DexFile*>& dex_files,
124590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                       volatile int32_t* shared_class_index, bool spawn)
124690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      : spawn_(spawn), worker_context_(worker_context),
124790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        class_callback_(class_callback), dex_files_(dex_files),
124890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        context_(NULL), shared_class_index_(shared_class_index) {
124990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    if (spawn_) {
125090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread");
125190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    }
125290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
125390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
125490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  ~DexFilesWorkerThread() {
125590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    if (spawn_) {
125690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown");
125790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    }
125890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    delete context_;
125990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
126090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
126190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao private:
126290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  static void* Go(void* arg) {
126390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    DexFilesWorkerThread* worker = reinterpret_cast<DexFilesWorkerThread*>(arg);
126490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    Runtime* runtime = Runtime::Current();
126590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    if (worker->spawn_) {
126690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      runtime->AttachCurrentThread("Compiler Worker", true, NULL);
126790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    }
126890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    Thread::Current()->SetState(kRunnable);
126990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    worker->Run();
127090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    if (worker->spawn_) {
127190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      Thread::Current()->SetState(kNative);
127290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      runtime->DetachCurrentThread();
127390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    }
127490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    return NULL;
127590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
127690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
127790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  void Go() {
127890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    Go(this);
127990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
128090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
128190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  void SwitchToDexFile(size_t dex_file_index) {
128290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    CHECK (dex_file_index < dex_files_.size());
128390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
128490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    const DexFile* dex_file = dex_files_[dex_file_index];
128590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    CHECK(dex_file != NULL);
128690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
128790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    // Destroy the old context
128890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    delete context_;
128990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
129090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    // TODO: Add a callback to let the client specify the class_linker and
129190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    //       dex_cache in the context for the current working dex file.
129290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    context_ = new Context(/* class_linker */NULL,
129390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                           worker_context_->GetClassLoader(),
129490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                           worker_context_->GetCompiler(),
129590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                           /* dex_cache */NULL, dex_file);
129690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
129790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    CHECK(context_ != NULL);
129890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
129990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
130090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  void Run() {
130190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    Thread* self = Thread::Current();
130290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    size_t cur_dex_file_index = 0;
130390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    size_t class_index_base = 0;
130490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
130590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    SwitchToDexFile(0);
130690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
130790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    while (true) {
130890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      size_t class_index =
130990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao          static_cast<size_t>(android_atomic_inc(shared_class_index_));
131090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
131190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      const DexFile* dex_file;
131290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      do {
131390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        dex_file = dex_files_[cur_dex_file_index];
131490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
131590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        if (class_index < (class_index_base + dex_file->NumClassDefs())) {
131690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao          break;
131790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        }
131890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        class_index_base += dex_file->NumClassDefs();
131990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
132090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        cur_dex_file_index++;
132190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      } while (cur_dex_file_index < dex_files_.size());
132290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
132390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      if (cur_dex_file_index >= dex_files_.size()) {
132490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        return;
132590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      }
132690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
132790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      if (dex_file != context_->GetDexFile()) {
132890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao        SwitchToDexFile(cur_dex_file_index);
132990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      }
133090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
133190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      class_index -= class_index_base;
133290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      class_callback_(context_, class_index);
133390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao      CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
133490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    }
133590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
133690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
133790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  pthread_t pthread_;
133890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  bool spawn_;
133990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
134090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  Context* worker_context_;
134190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  Callback* class_callback_;
134290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  const std::vector<const DexFile*>& dex_files_;
134390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
134490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  Context* context_;
134590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  volatile int32_t* shared_class_index_;
134690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
134790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  friend void ForClassesInAllDexFiles(Context*,
134890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                                      const std::vector<const DexFile*>&,
134990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                                      Callback, size_t);
135090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao};
135190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
135290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liaovoid ForClassesInAllDexFiles(Context* worker_context,
135390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                             const std::vector<const DexFile*>& dex_files,
135490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                             Callback class_callback, size_t thread_count) {
135590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  Thread* self = Thread::Current();
135690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
135790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  CHECK_GT(thread_count, 0U);
135890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
135990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  std::vector<DexFilesWorkerThread*> threads;
136090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  volatile int32_t shared_class_index = 0;
136190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
136290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  for (size_t i = 0; i < thread_count; ++i) {
136390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    threads.push_back(new DexFilesWorkerThread(worker_context, class_callback,
136490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                                               dex_files, &shared_class_index,
136590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao                                               /* spawn */ (i != 0)));
136690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
136790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  threads[0]->Go();
136890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
136990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  // Switch to kVmWait while we're blocked waiting for the other threads to finish.
137090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  ScopedThreadStateChange tsc(self, kVmWait);
137190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  STLDeleteElements(&threads);
137290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao}
137390dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
1374ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader,
1375ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       const std::vector<const DexFile*>& dex_files) {
137690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao#if defined(ART_USE_LLVM_COMPILER)
137790dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  if (dex_files.size() <= 0) {
137890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    return;  // No dex file
137990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  }
138090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  Context context(NULL, class_loader, this, NULL, NULL);
138190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao  ForClassesInAllDexFiles(&context, dex_files, Compiler::CompileClass, thread_count_);
138290dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao#else
1383ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1384ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
138583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom    CHECK(dex_file != NULL);
138683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom    CompileDexFile(class_loader, *dex_file);
138783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom  }
138890dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao#endif
138983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom}
139083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom
1391c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileClass(Context* context, size_t class_def_index) {
1392731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const ClassLoader* class_loader = context->GetClassLoader();
1393731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile& dex_file = *context->GetDexFile();
1394c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
13955ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  if (SkipClass(class_loader, dex_file, class_def)) {
13965ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom    return;
13975ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  }
1398d1224c79631bd1801b067a0f212b91afa961a362jeffhao  ClassReference ref(&dex_file, class_def_index);
1399d1224c79631bd1801b067a0f212b91afa961a362jeffhao  // Skip compiling classes with generic verifier failures since they will still fail at runtime
1400776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (verifier::MethodVerifier::IsClassRejected(ref)) {
1401d1224c79631bd1801b067a0f212b91afa961a362jeffhao    return;
1402d1224c79631bd1801b067a0f212b91afa961a362jeffhao  }
14030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const byte* class_data = dex_file.GetClassData(class_def);
14040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (class_data == NULL) {
14050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    // empty class, probably a marker interface
14060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    return;
14070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
14080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  ClassDataItemIterator it(dex_file, class_data);
14090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Skip fields
14100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextStaticField()) {
14110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
14120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
14130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextInstanceField()) {
14140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
14150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
14160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Compile direct methods
14170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextDirectMethod()) {
1418731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1419731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                          it.GetMemberIndex(), class_loader, dex_file);
14200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
14219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
14220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Compile virtual methods
14230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextVirtualMethod()) {
1424731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1425731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                                          it.GetMemberIndex(), class_loader, dex_file);
14260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
14279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
14280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  DCHECK(!it.HasNext());
14299ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
14309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
1431c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughesvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
1432731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  Context context(NULL, class_loader, this, NULL, &dex_file);
14335523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_);
1434c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes}
1435c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes
1436a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) {
1437a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  std::string key(shorty);
1438a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  if (is_static) {
1439a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    key += "$";  // Must not be a shorty type character.
1440a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
1441a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return key;
1442a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
1443a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
1444a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
1445a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers                             uint32_t method_idx, const ClassLoader* class_loader,
1446a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogers                             const DexFile& dex_file) {
1447f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  CompiledMethod* compiled_method = NULL;
1448bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns = NanoTime();
14494dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien
1450169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  if ((access_flags & kAccNative) != 0) {
145157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file);
14523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_method != NULL);
1453169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  } else if ((access_flags & kAccAbstract) != 0) {
14542cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom  } else {
1455b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    compiled_method = (*compiler_)(*this, code_item, access_flags, method_idx, class_loader,
1456b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes                                   dex_file);
1457bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes    CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
1458bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
14593bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers  uint64_t duration_ns = NanoTime() - start_ns;
14605abfa3ea35781464df8fae60aaf03f48a295e965buzbee  if (duration_ns > MsToNs(100)) {
1461bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes    LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
14623bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers                 << " took " << PrettyDuration(duration_ns);
1463f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  }
1464f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes
1465f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  if (compiled_method != NULL) {
14660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    MethodReference ref(&dex_file, method_idx);
14670755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file);
1468c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    MutexLock mu(compiled_methods_lock_);
1469a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    compiled_methods_.Put(ref, compiled_method);
14700755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file);
14712cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom  }
14729baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
147345619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers  uint32_t shorty_len;
147445619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers  const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len);
1475169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  bool is_static = (access_flags & kAccStatic) != 0;
1476a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  std::string key(MakeInvokeStubKey(is_static, shorty));
1477a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key);
14780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (compiled_invoke_stub == NULL) {
1479c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao    compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len);
14800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    CHECK(compiled_invoke_stub != NULL);
1481a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    InsertInvokeStub(key, compiled_invoke_stub);
14823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
14830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file);
14840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
148528ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers
1486a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const {
1487a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const std::string key(MakeInvokeStubKey(is_static, shorty));
1488a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return FindInvokeStub(key);
14893320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
14903320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1491a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(const std::string& key) const {
1492c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  MutexLock mu(compiled_invoke_stubs_lock_);
14930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
14940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (it == compiled_invoke_stubs_.end()) {
14953320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    return NULL;
14960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  } else {
14970571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    DCHECK(it->second != NULL);
14980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    return it->second;
14993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
15003320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
15013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1502a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesvoid Compiler::InsertInvokeStub(const std::string& key,
15030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                                const CompiledInvokeStub* compiled_invoke_stub) {
1504c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  MutexLock mu(compiled_invoke_stubs_lock_);
1505a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key);
1506a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  if (it != compiled_invoke_stubs_.end()) {
1507a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    // Someone else won the race.
1508a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    delete compiled_invoke_stub;
1509a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  } else {
1510a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    compiled_invoke_stubs_.Put(key, compiled_invoke_stub);
1511a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
15120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
15130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
15140755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const {
1515c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  MutexLock mu(compiled_classes_lock_);
15160755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  ClassTable::const_iterator it = compiled_classes_.find(ref);
15170755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  if (it == compiled_classes_.end()) {
15180755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    return NULL;
15190755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  }
15200755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  CHECK(it->second != NULL);
15210755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  return it->second;
15220755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom}
15230755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom
15240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const {
1525c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  MutexLock mu(compiled_methods_lock_);
15260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  MethodTable::const_iterator it = compiled_methods_.find(ref);
15270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (it == compiled_methods_.end()) {
15283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    return NULL;
15292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
15303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  CHECK(it->second != NULL);
15313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  return it->second;
15329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
15339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
1534e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) {
1535e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1536e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    const DexFile* dex_file = dex_files[i];
1537e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    CHECK(dex_file != NULL);
1538e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    SetGcMapsDexFile(class_loader, *dex_file);
1539e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  }
1540e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom}
1541e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom
1542e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
1543e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1544e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1545e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
1546e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1547e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    const char* descriptor = dex_file.GetClassDescriptor(class_def);
1548e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    Class* klass = class_linker->FindClass(descriptor, class_loader);
1549e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    if (klass == NULL || !klass->IsVerified()) {
1550e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      Thread::Current()->ClearException();
1551e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      continue;
1552e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    }
1553e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    const byte* class_data = dex_file.GetClassData(class_def);
1554e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    if (class_data == NULL) {
1555e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      // empty class such as a marker interface
1556e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      continue;
1557e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    }
1558e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    ClassDataItemIterator it(dex_file, class_data);
1559e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    while (it.HasNextStaticField()) {
1560e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      it.Next();
1561e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    }
1562e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    while (it.HasNextInstanceField()) {
1563e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      it.Next();
1564e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    }
1565e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    while (it.HasNextDirectMethod()) {
1566e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
1567e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                   class_loader, true);
1568e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      SetGcMapsMethod(dex_file, method);
1569e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      it.Next();
1570e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    }
1571e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    while (it.HasNextVirtualMethod()) {
1572e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
1573e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                                   class_loader, false);
1574e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      SetGcMapsMethod(dex_file, method);
1575e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom      it.Next();
1576e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    }
1577e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  }
1578e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom}
1579e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom
1580e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstromvoid Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) {
1581e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  if (method == NULL) {
1582e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    Thread::Current()->ClearException();
1583e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    return;
1584e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  }
1585e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  uint16_t method_idx = method->GetDexMethodIndex();
1586e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  MethodReference ref(&dex_file, method_idx);
1587e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  CompiledMethod* compiled_method = GetCompiledMethod(ref);
1588e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  if (compiled_method == NULL) {
1589e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    return;
1590e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  }
1591776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  const std::vector<uint8_t>* gc_map = verifier::MethodVerifier::GetGcMap(ref);
1592e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  if (gc_map == NULL) {
1593e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    return;
1594e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  }
1595e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  compiled_method->SetGcMap(*gc_map);
1596e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom}
1597e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom
15988b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#if defined(ART_USE_LLVM_COMPILER)
15998b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) {
1600106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  typedef void (*SetBitcodeFileNameFn)(Compiler&, std::string const&);
1601106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
1602106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  SetBitcodeFileNameFn set_bitcode_file_name =
1603106b2a03be66748a25b9019e4c222cee498d559fLogan Chien    FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(instruction_set_),
1604106b2a03be66748a25b9019e4c222cee498d559fLogan Chien                                       compiler_library_,
1605106b2a03be66748a25b9019e4c222cee498d559fLogan Chien                                       "compilerLLVMSetBitcodeFileName");
1606106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
1607106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  set_bitcode_file_name(*this, filename);
16088b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien}
1609f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
1610f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chienvoid Compiler::EnableAutoElfLoading() {
1611f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien  compiler_enable_auto_elf_loading_(*this);
1612f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien}
1613f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
1614f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chienconst void* Compiler::GetMethodCodeAddr(const CompiledMethod* cm,
1615f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien                                        const Method* method) const {
1616f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien  return compiler_get_method_code_addr_(*this, cm, method);
1617f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien}
1618f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
1619f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chienconst Method::InvokeStub* Compiler::GetMethodInvokeStubAddr(const CompiledInvokeStub* cm,
1620f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien                                                            const Method* method) const {
1621f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien  return compiler_get_method_invoke_stub_addr_(*this, cm, method);
1622f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien}
1623df57614aa99801a50202e284ee8e8497d8e92621Logan Chien
1624df57614aa99801a50202e284ee8e8497d8e92621Logan Chienstd::vector<ElfImage> Compiler::GetElfImages() const {
1625df57614aa99801a50202e284ee8e8497d8e92621Logan Chien  typedef std::vector<ElfImage> (*GetElfImagesFn)(const Compiler&);
1626df57614aa99801a50202e284ee8e8497d8e92621Logan Chien
1627df57614aa99801a50202e284ee8e8497d8e92621Logan Chien  GetElfImagesFn get_elf_images =
1628df57614aa99801a50202e284ee8e8497d8e92621Logan Chien    FindFunction<GetElfImagesFn>(MakeCompilerSoName(instruction_set_),
1629df57614aa99801a50202e284ee8e8497d8e92621Logan Chien                                 compiler_library_,
1630df57614aa99801a50202e284ee8e8497d8e92621Logan Chien                                 "compilerLLVMGetElfImages");
1631df57614aa99801a50202e284ee8e8497d8e92621Logan Chien
1632df57614aa99801a50202e284ee8e8497d8e92621Logan Chien  return get_elf_images(*this);
1633df57614aa99801a50202e284ee8e8497d8e92621Logan Chien}
16348b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien#endif
16358b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
16369ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}  // namespace art
1637