compiler_driver.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
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>
22d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include <unistd.h>
2327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom
241aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h"
269baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h"
274dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien#include "oat_compilation_unit.h"
283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
2900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "oat/runtime/stub.h"
306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
311f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "gc/card_table-inl.h"
337469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h"
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/dex_cache.h"
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h"
382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h"
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h"
4200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h"
4450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#include "thread.h"
450e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier#include "thread_pool.h"
46601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes#include "timing_logger.h"
47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/method_verifier.h"
489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
49059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__)
50059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#include <mach-o/dyld.h>
51059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif
52059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art {
549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian 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:
68ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers  AOTCompilationStats()
69ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers      : stats_lock_("AOT compilation statistics lock"),
70ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers        types_in_dex_cache_(0), types_not_in_dex_cache_(0),
71ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers        strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
72ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers        resolved_types_(0), unresolved_types_(0),
73ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers        resolved_instance_fields_(0), unresolved_instance_fields_(0),
74ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers        resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0) {
752ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    for (size_t i = 0; i <= kMaxInvokeType; i++) {
76c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      resolved_methods_[i] = 0;
77c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      unresolved_methods_[i] = 0;
782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      virtual_made_direct_[i] = 0;
792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      direct_calls_to_boot_[i] = 0;
802ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      direct_methods_to_boot_[i] = 0;
81b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes    }
82c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
83c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
84c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void Dump() {
85c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_types_, unresolved_types_, "types resolved");
88c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
89c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
90c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers             "static fields resolved");
91c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_,
92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers             "static fields local to a class");
93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
942ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    for (size_t i = 0; i <= kMaxInvokeType; i++) {
95c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      std::ostringstream oss;
962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      oss << static_cast<InvokeType>(i) << " methods were AOT resolved";
97c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      if (virtual_made_direct_[i] > 0) {
992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        std::ostringstream oss2;
1002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        oss2 << static_cast<InvokeType>(i) << " methods made direct";
1012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        DumpStat(virtual_made_direct_[i],
1022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i],
1032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 oss2.str().c_str());
1042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      }
1052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      if (direct_calls_to_boot_[i] > 0) {
1062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        std::ostringstream oss2;
1072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot";
1082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        DumpStat(direct_calls_to_boot_[i],
1092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i],
1102ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 oss2.str().c_str());
1112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      }
1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      if (direct_methods_to_boot_[i] > 0) {
1132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        std::ostringstream oss2;
1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot";
1152ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        DumpStat(direct_methods_to_boot_[i],
1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i],
1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                 oss2.str().c_str());
1182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers      }
119c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    }
120c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
121996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
12250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers// Allow lossy statistics in non-debug builds.
123996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#ifndef NDEBUG
12450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_)
125996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#else
126996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#define STATS_LOCK()
127996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers#endif
128996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
129c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeInDexCache() {
130c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
131c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    types_in_dex_cache_++;
132c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
133996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
134c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeNotInDexCache() {
135c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
136c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    types_not_in_dex_cache_++;
137c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
138996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
139c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void StringInDexCache() {
140c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
141c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    strings_in_dex_cache_++;
142c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
143996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
144c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void StringNotInDexCache() {
145c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
146c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    strings_not_in_dex_cache_++;
147c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
148996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeDoesntNeedAccessCheck() {
150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
151c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_types_++;
152c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
153996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void TypeNeedsAccessCheck() {
155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
156c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_types_++;
157c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
158996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedInstanceField() {
160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
161c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_instance_fields_++;
162c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
163996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
164b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes  void UnresolvedInstanceField() {
165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
166c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_instance_fields_++;
167c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
168996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedLocalStaticField() {
170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
171c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_local_static_fields_++;
172c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
173996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
174c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedStaticField() {
175c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
176c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_static_fields_++;
177c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
178996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
179c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void UnresolvedStaticField() {
180c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
181c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_static_fields_++;
182c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  }
183996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
184c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void ResolvedMethod(InvokeType type) {
185c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DCHECK_LE(type, kMaxInvokeType);
186c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
187c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    resolved_methods_[type]++;
188996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
189996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
190c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void UnresolvedMethod(InvokeType type) {
191c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    DCHECK_LE(type, kMaxInvokeType);
192c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    STATS_LOCK();
193c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    unresolved_methods_[type]++;
194996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
195c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
1962ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  void VirtualMadeDirect(InvokeType type) {
1972ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    DCHECK_LE(type, kMaxInvokeType);
1982ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    STATS_LOCK();
1992ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    virtual_made_direct_[type]++;
2002ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
2012ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
2022ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  void DirectCallsToBoot(InvokeType type) {
2032ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    DCHECK_LE(type, kMaxInvokeType);
2042ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    STATS_LOCK();
2052ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    direct_calls_to_boot_[type]++;
2062ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
2072ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
2082ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  void DirectMethodsToBoot(InvokeType type) {
2092ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    DCHECK_LE(type, kMaxInvokeType);
210fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers    STATS_LOCK();
2112ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    direct_methods_to_boot_[type]++;
212fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers  }
2132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
214c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers private:
215c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  Mutex stats_lock_;
216c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
217c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t types_in_dex_cache_;
218c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t types_not_in_dex_cache_;
219c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
220c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t strings_in_dex_cache_;
221c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t strings_not_in_dex_cache_;
222c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
223c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_types_;
224c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_types_;
225c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
226c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_instance_fields_;
227c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_instance_fields_;
228c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
229c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_local_static_fields_;
230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_static_fields_;
231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_static_fields_;
232c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t resolved_methods_[kMaxInvokeType + 1];
234c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  size_t unresolved_methods_[kMaxInvokeType + 1];
2352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  size_t virtual_made_direct_[kMaxInvokeType + 1];
2362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  size_t direct_calls_to_boot_[kMaxInvokeType + 1];
2372ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  size_t direct_methods_to_boot_[kMaxInvokeType + 1];
238c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
239b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes  DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
240c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers};
241996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
2428c4bbb55d0d801e492d849ee636771c8b2840429buzbeestatic std::string MakeCompilerSoName(CompilerBackend compiler_backend) {
243059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
244059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Bad things happen if we pull in the libartd-compiler to a libart dex2oat or vice versa,
245059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // because we end up with both libart and libartd in the same address space!
24667d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes  const char* suffix = (kIsDebugBuild ? "d" : "");
247059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
248059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Work out the filename for the compiler library.
249c531cefbfb5394413122e9f57d211ba436cff012buzbee  std::string library_name;
250c531cefbfb5394413122e9f57d211ba436cff012buzbee  if ((compiler_backend == kPortable) || (compiler_backend == kIceland)) {
251c531cefbfb5394413122e9f57d211ba436cff012buzbee    library_name = StringPrintf("art%s-compiler-llvm", suffix);
252c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
2538c4bbb55d0d801e492d849ee636771c8b2840429buzbee    library_name = StringPrintf("art%s-compiler", suffix);
254c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
255059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str()));
256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
257059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__)
258059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find
259059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the
260059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // same work.
261059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  uint32_t executable_path_length = 0;
262448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  _NSGetExecutablePath(NULL, &executable_path_length);
263448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  std::string path(executable_path_length, static_cast<char>(0));
264448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0);
265059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Strip the "/dex2oat".
267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  size_t last_slash = path.find_last_of('/');
268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  CHECK_NE(last_slash, std::string::npos) << path;
269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  path.resize(last_slash);
270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Strip the "/bin".
272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  last_slash = path.find_last_of('/');
273059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  path.resize(last_slash);
274059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
275059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  filename = path + "/lib/" + filename;
276059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif
277059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  return filename;
278b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes}
279b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
28046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn>
28146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) {
28246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  Fn fn = reinterpret_cast<Fn>(dlsym(library, name));
28346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  if (fn == NULL) {
28446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes    LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror();
28546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  }
286059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn);
28746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  return fn;
28846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes}
28946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes
290c531cefbfb5394413122e9f57d211ba436cff012buzbeeCompiler::Compiler(CompilerBackend compiler_backend, InstructionSet instruction_set, bool image,
291c531cefbfb5394413122e9f57d211ba436cff012buzbee                   size_t thread_count, bool support_debugging, const std::set<std::string>* image_classes,
292ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                   bool dump_stats, bool dump_timings)
293c531cefbfb5394413122e9f57d211ba436cff012buzbee    : compiler_backend_(compiler_backend),
294c531cefbfb5394413122e9f57d211ba436cff012buzbee      instruction_set_(instruction_set),
295fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers      freezing_constructor_lock_("freezing constructor lock"),
296c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_classes_lock_("compiled classes lock"),
297c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_methods_lock_("compiled method lock"),
298c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_invoke_stubs_lock_("compiled invoke stubs lock"),
2997a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      compiled_proxy_stubs_lock_("compiled proxy stubs lock"),
300aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      image_(image),
3015523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      thread_count_(thread_count),
302de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes      support_debugging_(support_debugging),
30300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      start_ns_(0),
304c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      stats_(new AOTCompilationStats),
305ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom      dump_stats_(dump_stats),
306ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom      dump_timings_(dump_timings),
307b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes      image_classes_(image_classes),
308b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes      compiler_library_(NULL),
30946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes      compiler_(NULL),
3106f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes      compiler_context_(NULL),
31146f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes      jni_compiler_(NULL),
3122f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom      create_invoke_stub_(NULL)
313971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien{
3148c4bbb55d0d801e492d849ee636771c8b2840429buzbee  std::string compiler_so_name(MakeCompilerSoName(compiler_backend_));
315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY);
316b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (compiler_library_ == NULL) {
317b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror();
318b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
319b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_;
320b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
3214df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key");
3224df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee
323c531cefbfb5394413122e9f57d211ba436cff012buzbee  // TODO: more work needed to combine initializations and allow per-method backend selection
324106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  typedef void (*InitCompilerContextFn)(Compiler&);
325c531cefbfb5394413122e9f57d211ba436cff012buzbee  InitCompilerContextFn init_compiler_context;
326c531cefbfb5394413122e9f57d211ba436cff012buzbee  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){
327c531cefbfb5394413122e9f57d211ba436cff012buzbee    // Initialize compiler_context_
328c531cefbfb5394413122e9f57d211ba436cff012buzbee    init_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name,
329c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                  compiler_library_, "ArtInitCompilerContext");
330c531cefbfb5394413122e9f57d211ba436cff012buzbee    compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod");
331c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
332c531cefbfb5394413122e9f57d211ba436cff012buzbee    init_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name,
333c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                  compiler_library_, "ArtInitQuickCompilerContext");
334c531cefbfb5394413122e9f57d211ba436cff012buzbee    compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtQuickCompileMethod");
335c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
336692be80cb2278ae585a776a163bc4b3ef60cae88buzbee
337692be80cb2278ae585a776a163bc4b3ef60cae88buzbee  init_compiler_context(*this);
338106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
33946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtJniCompileMethod");
34002031b185b4653e6c72e21f7a51238b903f6d638buzbee  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){
34102031b185b4653e6c72e21f7a51238b903f6d638buzbee    create_invoke_stub_ =
34202031b185b4653e6c72e21f7a51238b903f6d638buzbee        FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateLLVMInvokeStub");
34302031b185b4653e6c72e21f7a51238b903f6d638buzbee  } else {
34402031b185b4653e6c72e21f7a51238b903f6d638buzbee    switch (instruction_set) {
34502031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kArm:
34602031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kThumb2:
34702031b185b4653e6c72e21f7a51238b903f6d638buzbee        create_invoke_stub_ =
34802031b185b4653e6c72e21f7a51238b903f6d638buzbee            FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateArmInvokeStub");
34902031b185b4653e6c72e21f7a51238b903f6d638buzbee        break;
35002031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kMips:
35102031b185b4653e6c72e21f7a51238b903f6d638buzbee        create_invoke_stub_ =
35202031b185b4653e6c72e21f7a51238b903f6d638buzbee            FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateMipsInvokeStub");
35302031b185b4653e6c72e21f7a51238b903f6d638buzbee        break;
35402031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kX86:
35502031b185b4653e6c72e21f7a51238b903f6d638buzbee        create_invoke_stub_ =
35602031b185b4653e6c72e21f7a51238b903f6d638buzbee            FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateX86InvokeStub");
35702031b185b4653e6c72e21f7a51238b903f6d638buzbee        break;
35802031b185b4653e6c72e21f7a51238b903f6d638buzbee      default:
35902031b185b4653e6c72e21f7a51238b903f6d638buzbee        LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
36002031b185b4653e6c72e21f7a51238b903f6d638buzbee    }
36102031b185b4653e6c72e21f7a51238b903f6d638buzbee  }
362b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
363c531cefbfb5394413122e9f57d211ba436cff012buzbee  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
364c531cefbfb5394413122e9f57d211ba436cff012buzbee    create_proxy_stub_ = FindFunction<CreateProxyStubFn>(
365c531cefbfb5394413122e9f57d211ba436cff012buzbee        compiler_so_name, compiler_library_, "ArtCreateProxyStub");
366c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
367f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
36825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  CHECK(!Runtime::Current()->IsStarted());
369ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (!image_) {
370ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    CHECK(image_classes_ == NULL);
371ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
372c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao}
373c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao
3743320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiler::~Compiler() {
37550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
376c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
37750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_classes_lock_);
378c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_classes_);
379c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  }
380c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
38150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_methods_lock_);
382c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_methods_);
383c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  }
384c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
38550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_invoke_stubs_lock_);
386c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_invoke_stubs_);
387bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
388f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  {
38950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_proxy_stubs_lock_);
3907a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    STLDeleteValues(&compiled_proxy_stubs_);
3917a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
3927a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  {
39350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_methods_lock_);
394f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    STLDeleteElements(&code_to_patch_);
395f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  }
396f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  {
39750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_methods_lock_);
398f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    STLDeleteElements(&methods_to_patch_);
399f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  }
400ed6d5ed3494648780b9e91422c90d6bc22c16b79Mathieu Chartier  CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key");
401971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien  typedef void (*UninitCompilerContextFn)(Compiler&);
4028c4bbb55d0d801e492d849ee636771c8b2840429buzbee  std::string compiler_so_name(MakeCompilerSoName(compiler_backend_));
403c531cefbfb5394413122e9f57d211ba436cff012buzbee  UninitCompilerContextFn uninit_compiler_context;
404692be80cb2278ae585a776a163bc4b3ef60cae88buzbee  // Uninitialize compiler_context_
405c531cefbfb5394413122e9f57d211ba436cff012buzbee  // TODO: rework to combine initialization/uninitialization
406c531cefbfb5394413122e9f57d211ba436cff012buzbee  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
407c531cefbfb5394413122e9f57d211ba436cff012buzbee    uninit_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name,
408c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                    compiler_library_, "ArtUnInitCompilerContext");
409c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
410c531cefbfb5394413122e9f57d211ba436cff012buzbee    uninit_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name,
411c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                    compiler_library_, "ArtUnInitQuickCompilerContext");
412c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
413692be80cb2278ae585a776a163bc4b3ef60cae88buzbee  uninit_compiler_context(*this);
414b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (compiler_library_ != NULL) {
415b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    VLOG(compiler) << "dlclose(" << compiler_library_ << ")";
416ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee    /*
417ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * FIXME: Temporary workaround
418ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * Apparently, llvm is adding dctors to atexit, but if we unload
419ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * the library here the code will no longer be around at exit time
420ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * and we die a flaming death in __cxa_finalize().  Apparently, some
421ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * dlclose() implementations will scan the atexit list on unload and
422ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * handle any associated with the soon-to-be-unloaded library.
423ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * However, this is not required by POSIX and we don't do it.
424ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * See: http://b/issue?id=4998315
425ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * What's the right thing to do here?
426ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     */
427b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    dlclose(compiler_library_);
428b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
4293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
4303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
4314df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbeeCompilerTls* Compiler::GetTls() {
4324df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  // Lazily create thread-local storage
4334df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_));
4344df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  if (res == NULL) {
4354df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee    res = new CompilerTls();
4364df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee    CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls");
4374df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  }
4384df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  return res;
4394df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee}
4404df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee
4412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set,
4421cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers                                          Runtime::TrampolineType type) {
4437fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  switch (instruction_set) {
4447fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kArm:
4457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kThumb2:
4467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return arm::ArmCreateResolutionTrampoline(type);
4477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kMips:
4487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return mips::MipsCreateResolutionTrampoline(type);
4497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kX86:
4507fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return x86::X86CreateResolutionTrampoline(type);
4517fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    default:
4527fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
4537fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return NULL;
454ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
455ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
456ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::ByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
458169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  switch (instruction_set) {
459169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kArm:
460169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kThumb2:
4618add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes      return arm::CreateJniDlsymLookupStub();
4627fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kMips:
4637fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return mips::CreateJniDlsymLookupStub();
464169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kX86:
4658add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes      return x86::CreateJniDlsymLookupStub();
466169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    default:
46749c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
468169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers      return NULL;
469169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  }
470169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers}
471169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers
4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
4737fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  switch (instruction_set) {
4747fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kArm:
4757fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kThumb2:
4767fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return arm::CreateAbstractMethodErrorStub();
4777fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kMips:
4787fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return mips::CreateAbstractMethodErrorStub();
4797fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kX86:
4807fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return x86::CreateAbstractMethodErrorStub();
4817fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    default:
4827fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
4837fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return NULL;
484ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
485ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
486ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
48700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::CompileAll(jobject class_loader,
488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                          const std::vector<const DexFile*>& dex_files) {
48925c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  DCHECK(!Runtime::Current()->IsStarted());
490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
49156edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_));
492601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  TimingLogger timings("compiler");
493601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
49456edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  PreCompile(class_loader, dex_files, *thread_pool.get(), timings);
495601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
49656edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  Compile(class_loader, dex_files, *thread_pool.get(), timings);
497601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
498ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) {
499601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes    timings.Dump();
500601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  }
501996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
502ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  if (dump_stats_) {
503ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom    stats_->Dump();
504ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  }
5058a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom}
5068a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom
5072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Compiler::CompileOne(const mirror::AbstractMethod* method) {
50825c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  DCHECK(!Runtime::Current()->IsStarted());
50900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
51000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject class_loader;
51100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile* dex_file;
512fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  uint32_t class_def_idx;
51300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  {
51400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccessUnchecked soa(self);
51500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedLocalRef<jobject>
51600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      local_class_loader(soa.Env(),
51700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
51800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    class_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
51900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Find the dex_file
520fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    MethodHelper mh(method);
521fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    dex_file = &mh.GetDexFile();
522fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    class_def_idx = mh.GetClassDefIndex();
52300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
52400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->TransitionFromRunnableToSuspended(kNative);
525ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
526ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  std::vector<const DexFile*> dex_files;
52700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  dex_files.push_back(dex_file);
528ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
52956edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  UniquePtr<ThreadPool> thread_pool(new ThreadPool(1U));
530601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  TimingLogger timings("CompileOne");
53156edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  PreCompile(class_loader, dex_files, *thread_pool.get(), timings);
532ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5330571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  uint32_t method_idx = method->GetDexMethodIndex();
53400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
53508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  CompileMethod(code_item, method->GetAccessFlags(), method->GetInvokeType(),
536fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                class_def_idx, method_idx, class_loader, *dex_file);
537ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
53800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->GetJniEnv()->DeleteGlobalRef(class_loader);
53900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
54000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->TransitionFromSuspendedToRunnable();
5419ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
5429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
54300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
5442f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                       ThreadPool& thread_pool, TimingLogger& timings) {
545ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
546ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
5479ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    CHECK(dex_file != NULL);
5482f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    ResolveDexFile(class_loader, *dex_file, thread_pool, timings);
5499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
5509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
5519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
55200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
5532f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                          ThreadPool& thread_pool, TimingLogger& timings) {
5542f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  Resolve(class_loader, dex_files, thread_pool, timings);
555601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
5562f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  Verify(class_loader, dex_files, thread_pool, timings);
557ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5582f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  InitializeClasses(class_loader, dex_files, thread_pool, timings);
559ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
561ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrombool Compiler::IsImageClass(const std::string& descriptor) const {
562ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_ == NULL) {
563ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
564ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
565ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  return image_classes_->find(descriptor) != image_classes_->end();
566ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
567ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5683d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) {
56950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), Compiler::compiled_classes_lock_);
5703d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  compiled_classes_.Put(ref, compiled_class);
5713d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers}
5723d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers
57300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool Compiler::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file,
574996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                                uint32_t type_idx) {
57500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
5762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
5776d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (!IsImage()) {
578c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
5796d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return false;
5806d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
5812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
5826d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (resolved_class == NULL) {
583c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
5846d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return false;
5856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
586996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor());
587996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
588c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeInDexCache();
589996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
590c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
591996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
592996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
5936d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
5946d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
59500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool Compiler::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
596996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                                  uint32_t string_idx) {
5971bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // See also Compiler::ResolveDexFile
5981bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
5995f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers  bool result = false;
6005f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers  if (IsImage()) {
6015f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers    // We resolve all const-string strings when building for the image.
60200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
6032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
6045f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers    Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache);
6055f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers    result = true;
60600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
607996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
608c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->StringInDexCache();
609996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
610c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->StringNotInDexCache();
611996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
612996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
6131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
61500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
61600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                          uint32_t type_idx) {
61700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
6182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
6191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Get type from dex cache assuming it was populated by the verifier
6202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
6211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_class == NULL) {
622c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Unknown class needs access checks.
6241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
6262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (referrer_class == NULL) {
628c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Incomplete referrer knowledge needs access check.
6301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Perform access check, will return true if access is ok or false if we're going to have to
6321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // check this at runtime (for example for class loaders).
633996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = referrer_class->CanAccess(resolved_class);
634996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
635c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeDoesntNeedAccessCheck();
636996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
637c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
638996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
639996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
6401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6421bddec3a6521f16df37499754000a3b1787a52e9Ian Rogersbool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
6431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers                                                      const DexFile& dex_file,
644996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                                      uint32_t type_idx) {
64500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
6462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
6471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Get type from dex cache assuming it was populated by the verifier.
6482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
6491bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_class == NULL) {
650c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Unknown class needs access checks.
6521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
6542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
6551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (referrer_class == NULL) {
656c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Incomplete referrer knowledge needs access check.
6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Perform access and instantiable checks, will return true if access is ok or false if we're
6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // going to have to check this at runtime (for example for class loaders).
661996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
662996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
663c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeDoesntNeedAccessCheck();
664996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
665c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
666996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
667996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
6681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6691bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
6712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                   OatCompilationUnit* mUnit)
672b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
6732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
6742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_);
67500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile::MethodId& referrer_method_id = mUnit->dex_file_->GetMethodId(mUnit->method_idx_);
67600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return mUnit->class_linker_->ResolveType(*mUnit->dex_file_, referrer_method_id.class_idx_,
67700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                           dex_cache, class_loader);
6784dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien}
679a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa,
6812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                OatCompilationUnit* mUnit,
6822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                uint32_t field_idx)
683b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
6842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
6852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_);
68600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return mUnit->class_linker_->ResolveField(*mUnit->dex_file_, field_idx, dex_cache,
68700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                            class_loader, false);
688a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
689a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa,
6912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                          OatCompilationUnit* mUnit,
6922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                          uint32_t method_idx,
6932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                          InvokeType type)
694b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
6952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
6962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_);
69700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return mUnit->class_linker_->ResolveMethod(*mUnit->dex_file_, method_idx, dex_cache,
698c0228b8f02c05ed58bea58490e0d8bdcaf8c5bb8jeffhao                                             class_loader, NULL, type);
699a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
700a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
7014dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
7028cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao                                        int& field_offset, bool& is_volatile, bool is_put) {
70300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
70408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Conservative defaults.
7051bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  field_offset = -1;
7061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_volatile = true;
70708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Try to resolve field and ignore if an Incompatible Class Change Error (ie is static).
7082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
70908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  if (resolved_field != NULL && !resolved_field->IsStatic()) {
7102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
711e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers    if (referrer_class != NULL) {
7122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* fields_class = resolved_field->GetDeclaringClass();
713e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      bool access_ok = referrer_class->CanAccess(fields_class) &&
714e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                       referrer_class->CanAccessMember(fields_class,
715e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                       resolved_field->GetAccessFlags());
716e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (!access_ok) {
717e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // The referring class can't access the resolved field, this may occur as a result of a
718e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // protected field being made public by a sub-class. Resort to the dex file to determine
719e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // the correct class for the access check.
7204445a7e3398a6143939168097a3aa275b734504dIan Rogers        const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
7212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        mirror::Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file,
722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         dex_file.GetFieldId(field_idx).class_idx_,
723e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         referrer_class);
724e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        access_ok = referrer_class->CanAccess(dex_fields_class) &&
725e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                    referrer_class->CanAccessMember(dex_fields_class,
726e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                    resolved_field->GetAccessFlags());
727e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
728e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() &&
729e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          fields_class != referrer_class;
730e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (access_ok && !is_write_to_final_from_wrong_class) {
731e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        field_offset = resolved_field->GetOffset().Int32Value();
732e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        is_volatile = resolved_field->IsVolatile();
733e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        stats_->ResolvedInstanceField();
734e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        return true;  // Fast path.
735e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
7361bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    }
7371bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
7381bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Clean up any exception left by field/type resolution
73900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (soa.Self()->IsExceptionPending()) {
74000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ClearException();
7411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
742c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedInstanceField();
7431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  return false;  // Incomplete knowledge needs slow path.
7441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
7451bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
7464dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chienbool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
7471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers                                      int& field_offset, int& ssb_index,
7488cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao                                      bool& is_referrers_class, bool& is_volatile, bool is_put) {
74900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
75008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Conservative defaults.
7511bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  field_offset = -1;
7521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  ssb_index = -1;
7531bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_referrers_class = false;
7541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_volatile = true;
75508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static).
7562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
75708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  if (resolved_field != NULL && resolved_field->IsStatic()) {
7582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
7591bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    if (referrer_class != NULL) {
7602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* fields_class = resolved_field->GetDeclaringClass();
7618cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao      if (fields_class == referrer_class) {
7621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        is_referrers_class = true;  // implies no worrying about class initialization
7631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        field_offset = resolved_field->GetOffset().Int32Value();
7641bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        is_volatile = resolved_field->IsVolatile();
765c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers        stats_->ResolvedLocalStaticField();
7661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        return true;  // fast path
7671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      } else {
768e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        bool access_ok = referrer_class->CanAccess(fields_class) &&
769e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                         referrer_class->CanAccessMember(fields_class,
770e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         resolved_field->GetAccessFlags());
771e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        if (!access_ok) {
772e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // The referring class can't access the resolved field, this may occur as a result of a
773e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // protected field being made public by a sub-class. Resort to the dex file to determine
774e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // the correct class for the access check. Don't change the field's class as that is
775e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // used to identify the SSB.
7764445a7e3398a6143939168097a3aa275b734504dIan Rogers          const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
7772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers          mirror::Class* dex_fields_class =
778e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers              mUnit->class_linker_->ResolveType(dex_file,
779e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                dex_file.GetFieldId(field_idx).class_idx_,
780e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                referrer_class);
781e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          access_ok = referrer_class->CanAccess(dex_fields_class) &&
782e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                      referrer_class->CanAccessMember(dex_fields_class,
783e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                      resolved_field->GetAccessFlags());
784e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        }
7858cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao        bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal();
786e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        if (access_ok && !is_write_to_final_from_wrong_class) {
7871bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          // We have the resolved field, we must make it into a ssbIndex for the referrer
7881bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          // in its static storage base (which may fail if it doesn't have a slot for it)
7894103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          // TODO: for images we can elide the static storage base null check
7904103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          // if we know there's a non-null entry in the image
7912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers          mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
79200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          if (fields_class->GetDexCache() == dex_cache) {
7934103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            // common case where the dex cache of both the referrer and the field are the same,
7944103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            // no need to search the dex file
7954103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            ssb_index = fields_class->GetDexTypeIndex();
7964103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            field_offset = resolved_field->GetOffset().Int32Value();
7974103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            is_volatile = resolved_field->IsVolatile();
798c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers            stats_->ResolvedStaticField();
7994103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            return true;
8004103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          }
801e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // Search dex file for localized ssb index, may fail if field's class is a parent
802e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // of the class mentioned in the dex file and there is no dex cache entry.
8031bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor());
8041bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          const DexFile::StringId* string_id =
8054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien          mUnit->dex_file_->FindStringId(descriptor);
8061bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          if (string_id != NULL) {
8071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers            const DexFile::TypeId* type_id =
8084dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien               mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id));
809b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes            if (type_id != NULL) {
8101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              // medium path, needs check of static storage base being initialized
8114dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien              ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id);
8121bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              field_offset = resolved_field->GetOffset().Int32Value();
8131bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              is_volatile = resolved_field->IsVolatile();
814c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers              stats_->ResolvedStaticField();
8151bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              return true;
8161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers            }
8171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          }
8181bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        }
8191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      }
8201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    }
8211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
8221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Clean up any exception left by field/type resolution
82300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (soa.Self()->IsExceptionPending()) {
82400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ClearException();
8251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
826c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedStaticField();
8271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  return false;  // Incomplete knowledge needs slow path.
8281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
8291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
8302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type,
8312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                             mirror::AbstractMethod* method,
8322ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                             uintptr_t& direct_code, uintptr_t& direct_method) {
833137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // For direct and static methods compute possible direct_code and direct_method values, ie
834137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // an address for the Method* being invoked and an address of the code for that Method*.
835137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // For interface calls compute a value for direct_method that is the interface method being
836137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // invoked, so this can be passed to the out-of-line runtime support code.
8372ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_code = 0;
8382ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_method = 0;
839c531cefbfb5394413122e9f57d211ba436cff012buzbee  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
840c531cefbfb5394413122e9f57d211ba436cff012buzbee    if (sharp_type != kStatic && sharp_type != kDirect) {
841c531cefbfb5394413122e9f57d211ba436cff012buzbee      return;
842c531cefbfb5394413122e9f57d211ba436cff012buzbee    }
843c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
844c531cefbfb5394413122e9f57d211ba436cff012buzbee    if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) {
845c531cefbfb5394413122e9f57d211ba436cff012buzbee      return;
846c531cefbfb5394413122e9f57d211ba436cff012buzbee    }
847b8404a7de94c109e3c17b4205b5f8aaae996eb33TDYa  }
8482ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL;
8492ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (!method_code_in_boot) {
8502ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
8512ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
8522ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized();
8532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (has_clinit_trampoline) {
8542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
8552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
856c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers  if (sharp_type != kInterface) {  // Interfaces always go via a trampoline.
857c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers    stats_->DirectCallsToBoot(type);
858c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers  }
8592ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  stats_->DirectMethodsToBoot(type);
8603fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
8613fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  if (compiling_boot) {
8620637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom    const bool kSupportBootImageFixup = true;
8633fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    if (kSupportBootImageFixup) {
8643fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      MethodHelper mh(method);
8653fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      if (IsImageClass(mh.GetDeclaringClassDescriptor())) {
8660637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        // We can only branch directly to Methods that are resolved in the DexCache.
8670637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        // Otherwise we won't invoke the resolution trampoline.
8683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers        direct_method = -1;
8690637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        direct_code = -1;
8703fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      }
8713fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    }
8723fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  } else {
873b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method)->IsImageSpace()) {
8743fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      direct_method = reinterpret_cast<uintptr_t>(method);
8753fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    }
8763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    direct_code = reinterpret_cast<uintptr_t>(method->GetCode());
8772ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
8782ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers}
8792ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
880fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogersbool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type,
8812ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                 int& vtable_idx, uintptr_t& direct_code,
8822ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers                                 uintptr_t& direct_method) {
88300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
884a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  vtable_idx = -1;
8852ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_code = 0;
8862ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_method = 0;
8872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::AbstractMethod* resolved_method =
88808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers      ComputeMethodReferencedFromCompilingMethod(soa, mUnit, method_idx, type);
889a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  if (resolved_method != NULL) {
89008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    // Don't try to fast-path if we don't understand the caller's class or this appears to be an
89108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    // Incompatible Class Change Error.
8922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
89308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    bool icce = resolved_method->CheckIncompatibleClassChange(type);
89408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    if (referrer_class != NULL && !icce) {
8952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* methods_class = resolved_method->GetDeclaringClass();
896a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      if (!referrer_class->CanAccess(methods_class) ||
897a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          !referrer_class->CanAccessMember(methods_class,
898996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                           resolved_method->GetAccessFlags())) {
899a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // The referring class can't access the resolved method, this may occur as a result of a
900a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // protected method being made public by implementing an interface that re-declares the
90108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers        // method public. Resort to the dex file to determine the correct class for the access
90208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers        // check.
9034445a7e3398a6143939168097a3aa275b734504dIan Rogers        const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
904a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        methods_class =
9054dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien            mUnit->class_linker_->ResolveType(dex_file,
9064dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien                                              dex_file.GetMethodId(method_idx).class_idx_,
9074dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien                                              referrer_class);
908a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      }
909a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      if (referrer_class->CanAccess(methods_class) &&
910137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers          referrer_class->CanAccessMember(methods_class, resolved_method->GetAccessFlags())) {
911a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        vtable_idx = resolved_method->GetMethodIndex();
912f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers        const bool kEnableSharpening = true;
9132ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        // Sharpen a virtual call into a direct call when the target is known.
9142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() ||
91508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            methods_class->IsFinal());
91608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers        // Ensure the vtable index will be correct to dispatch in the vtable of the super class.
9174155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao        can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class &&
91808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            referrer_class->IsSubClass(methods_class) &&
91908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            vtable_idx < methods_class->GetVTable()->GetLength() &&
92008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            methods_class->GetVTable()->Get(vtable_idx) == resolved_method);
9212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        if (kEnableSharpening && can_sharpen) {
9222ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          stats_->ResolvedMethod(type);
923fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          // Sharpen a virtual call into a direct call. The method_idx is into referrer's
924fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          // dex cache, check that this resolved method is where we expect it.
925fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method)
92608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers              << PrettyMethod(resolved_method);
9272ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          stats_->VirtualMadeDirect(type);
9282ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method);
929fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          type = kDirect;
930fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          return true;
9312ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        } else if (type == kSuper) {
93208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers          // Unsharpened super calls are suspicious so go slow-path.
9332ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        } else {
934c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers          stats_->ResolvedMethod(type);
9352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method);
936a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          return true;
937a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        }
938a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      }
939a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    }
940a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  }
941a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  // Clean up any exception left by method/type resolution
94200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (soa.Self()->IsExceptionPending()) {
94300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Self()->ClearException();
944a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  }
945c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedMethod(type);
946a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  return false;  // Incomplete knowledge needs slow path.
947a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
948a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
94900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::AddCodePatch(const DexFile* dex_file,
950f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t referrer_method_idx,
95108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                            InvokeType referrer_invoke_type,
952f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t target_method_idx,
95308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                            InvokeType target_invoke_type,
9543fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers                            size_t literal_offset) {
95550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_methods_lock_);
95600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  code_to_patch_.push_back(new PatchInformation(dex_file,
957f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                referrer_method_idx,
95808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                referrer_invoke_type,
959f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                target_method_idx,
96008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                target_invoke_type,
961f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                literal_offset));
9623fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers}
96300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::AddMethodPatch(const DexFile* dex_file,
964f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t referrer_method_idx,
96508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                              InvokeType referrer_invoke_type,
966f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t target_method_idx,
96708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                              InvokeType target_invoke_type,
9683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers                              size_t literal_offset) {
96950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_methods_lock_);
97000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  methods_to_patch_.push_back(new PatchInformation(dex_file,
971f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   referrer_method_idx,
97208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                   referrer_invoke_type,
973f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   target_method_idx,
97408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                   target_invoke_type,
975f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   literal_offset));
9763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers}
9773fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers
9780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass CompilationContext {
979731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public:
9800e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  typedef void Callback(const CompilationContext* context, size_t index);
9810e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier
9820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  CompilationContext(ClassLinker* class_linker,
98300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          jobject class_loader,
984731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom          Compiler* compiler,
9850e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          const DexFile* dex_file,
9862f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom          ThreadPool& thread_pool)
987731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    : class_linker_(class_linker),
988731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      class_loader_(class_loader),
989731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      compiler_(compiler),
9900e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      dex_file_(dex_file),
9912f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom      thread_pool_(&thread_pool) {}
992731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom
99300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ClassLinker* GetClassLinker() const {
994731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(class_linker_ != NULL);
995731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return class_linker_;
996731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
99700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
99800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject GetClassLoader() const {
999731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return class_loader_;
1000731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
100100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
100200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Compiler* GetCompiler() const {
1003731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(compiler_ != NULL);
1004731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return compiler_;
1005731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
100600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
100700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile* GetDexFile() const {
1008731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(dex_file_ != NULL);
1009731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return dex_file_;
1010731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
1011731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom
10120e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
10130e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    Thread* self = Thread::Current();
10140e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    self->AssertNoPendingException();
10150e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    CHECK_GT(work_units, 0U);
10169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
101702b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    std::vector<ForAllClosure*> closures(work_units);
10180e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    for (size_t i = 0; i < work_units; ++i) {
10190e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      closures[i] = new ForAllClosure(this, begin + i, end, callback, work_units);
10200e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      thread_pool_->AddTask(self, closures[i]);
10210e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    }
10220e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    thread_pool_->StartWorkers(self);
102300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
10240e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
10250e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    // thread destructor's called below perform join).
10260e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    CHECK_NE(self->GetState(), kRunnable);
1027d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
10280e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    // Wait for all the worker threads to finish.
10290e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    thread_pool_->Wait(self);
1030d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1031d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1032d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private:
1033d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
103402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  class ForAllClosure : public Task {
10350e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier   public:
10360e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    ForAllClosure(CompilationContext* context, size_t begin, size_t end, Callback* callback,
10370e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier                  size_t stripe)
10380e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier        : context_(context),
10390e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          begin_(begin),
10400e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          end_(end),
10410e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          callback_(callback),
10420e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          stripe_(stripe)
10430e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    {
10441e4092589f1400915e6213014da103aab8728ef6Elliott Hughes
1045aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
10469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
10470e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    virtual void Run(Thread* self) {
10480e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      for (size_t i = begin_; i < end_; i += stripe_) {
10490e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier        callback_(context_, i);
10500e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier        self->AssertNoPendingException();
10510e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      }
10520e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    }
105302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
105402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    virtual void Finalize() {
105502b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier      delete this;
105602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    }
10570e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier   private:
10580e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    CompilationContext* const context_;
10590e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const size_t begin_;
10600e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const size_t end_;
10610e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const Callback* callback_;
10620e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const size_t stripe_;
10630e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  };
10641e4092589f1400915e6213014da103aab8728ef6Elliott Hughes
10650e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  ClassLinker* const class_linker_;
10660e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  const jobject class_loader_;
10670e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  Compiler* const compiler_;
10680e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  const DexFile* const dex_file_;
10690e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  ThreadPool* thread_pool_;
1070d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes};
1071d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
107200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Return true if the class should be skipped during compilation. We
107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// never skip classes in the boot class loader. However, if we have a
107400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// non-boot class loader and we can resolve the class in the boot
107500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// class loader, we do skip the class. This happens if an app bundles
107600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// classes found in the boot classpath. Since at runtime we will
107700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// select the class from the boot classpath, do not attempt to resolve
107800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// or compile it now.
10792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool SkipClass(mirror::ClassLoader* class_loader,
108000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                      const DexFile& dex_file,
108100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                      const DexFile::ClassDef& class_def)
1082b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
108300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (class_loader == NULL) {
108400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return false;
108500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
108600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const char* descriptor = dex_file.GetClassDescriptor(class_def);
108700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
10882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass = class_linker->FindClass(descriptor, NULL);
108900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (klass == NULL) {
109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread* self = Thread::Current();
109100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    CHECK(self->IsExceptionPending());
109200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    self->ClearException();
109300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return false;
109400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
109500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return true;
109600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
109700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ResolveClassFieldsAndMethods(const CompilationContext* context, size_t class_def_index)
1099b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
110000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
11012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
1102731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile& dex_file = *context->GetDexFile();
1103d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1104845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // Method and Field are the worst. We can't resolve without either
1105845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // context from the code use (to disambiguate virtual vs direct
1106845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // method and instance vs static field) or from class
1107845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // definitions. While the compiler will resolve what it can as it
1108845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // needs it, here we try to resolve fields and methods used in class
1109845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // definitions, since many of them many never be referenced by
1110845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // generated code.
1111d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
111200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (SkipClass(class_loader, dex_file, class_def)) {
1113d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1114d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1115845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom
1116d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Note the class_data pointer advances through the headers,
1117d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // static fields, instance fields, direct methods, and virtual
1118d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // methods.
1119d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  const byte* class_data = dex_file.GetClassData(class_def);
1120d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (class_data == NULL) {
1121d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // empty class such as a marker interface
1122d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1123d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1124d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Thread* self = Thread::Current();
1125731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* class_linker = context->GetClassLinker();
11262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1127d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ClassDataItemIterator it(dex_file, class_data);
1128d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextStaticField()) {
11292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
11302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                      class_loader, true);
1131d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (field == NULL) {
1132d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1133d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
11340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    }
1135d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1136d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1137fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  // If an instance field is final then we need to have a barrier on the return, static final
1138fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  // fields are assigned within the lock held for class initialization.
1139fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  bool requires_constructor_barrier = false;
1140d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextInstanceField()) {
1141fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    if ((it.GetMemberAccessFlags() & kAccFinal) != 0) {
1142fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers      requires_constructor_barrier = true;
1143fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    }
1144fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
11452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
11462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                      class_loader, false);
1147d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (field == NULL) {
1148d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1149d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
115020cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom    }
1151d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1152d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1153fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  if (requires_constructor_barrier) {
1154fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    context->GetCompiler()->AddRequiresConstructorBarrier(soa.Self(), context->GetDexFile(),
1155fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                                          class_def_index);
1156fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  }
1157d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextDirectMethod()) {
11582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
11592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 dex_cache, class_loader, NULL,
11602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 it.GetMethodInvokeType(class_def));
1161d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (method == NULL) {
1162d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1163d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
1164845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom    }
1165d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1166d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1167d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextVirtualMethod()) {
11682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
11692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 dex_cache, class_loader, NULL,
11702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 it.GetMethodInvokeType(class_def));
1171d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (method == NULL) {
1172d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1173d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
1174845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom    }
1175d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1176d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1177d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  DCHECK(!it.HasNext());
1178d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1179d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
118000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ResolveType(const CompilationContext* context, size_t type_idx)
1181b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
1182d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Class derived values are more complicated, they require the linker and loader.
118300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
118400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ClassLinker* class_linker = context->GetClassLinker();
118500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile& dex_file = *context->GetDexFile();
11862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
11872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
11882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
118900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1190d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass == NULL) {
119100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    CHECK(soa.Self()->IsExceptionPending());
1192d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread::Current()->ClearException();
1193d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1194d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1195d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
119600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
11972f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                              ThreadPool& thread_pool, TimingLogger& timings) {
1198d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1199d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
120000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // TODO: we could resolve strings here, although the string table is largely filled with class
120100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  //       and method names.
1202d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12032f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  CompilationContext context(class_linker, class_loader, this, &dex_file, thread_pool);
12040e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
1205ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes  timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types");
1206d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12070e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
1208ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes  timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields");
12099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
12109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
12113d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
12122f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                      ThreadPool& thread_pool, TimingLogger& timings) {
1213ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1214ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
121598eacac683b78e60799323e8c7d59e7214808639jeffhao    CHECK(dex_file != NULL);
12162f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    VerifyDexFile(class_loader, *dex_file, thread_pool, timings);
121798eacac683b78e60799323e8c7d59e7214808639jeffhao  }
121898eacac683b78e60799323e8c7d59e7214808639jeffhao}
121998eacac683b78e60799323e8c7d59e7214808639jeffhao
122000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VerifyClass(const CompilationContext* context, size_t class_def_index)
1221b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
122200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
1223731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
1224731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def);
12252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass =
122600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      context->GetClassLinker()->FindClass(descriptor,
12272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                       soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()));
1228d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass == NULL) {
1229d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread* self = Thread::Current();
1230d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(self->IsExceptionPending());
1231d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    self->ClearException();
1232f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao
1233f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    /*
1234f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * At compile time, we can still structurally verify the class even if FindClass fails.
1235f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * This is to ensure the class is structurally sound for compilation. An unsound class
1236f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * will be rejected by the verifier and later skipped during compilation in the compiler.
1237f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     */
12382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::DexCache* dex_cache =  context->GetClassLinker()->FindDexCache(*context->GetDexFile());
1239f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    std::string error_msg;
124000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (verifier::MethodVerifier::VerifyClass(context->GetDexFile(),
124100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              dex_cache,
12422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                              soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()),
124300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              class_def_index, error_msg) ==
124400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                  verifier::MethodVerifier::kHardFailure) {
1245731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
1246f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao      LOG(ERROR) << "Verification failed on class "
1247731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom                 << PrettyDescriptor(context->GetDexFile()->GetClassDescriptor(class_def))
1248f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao                 << " because: " << error_msg;
1249f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    }
1250d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1251d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1252d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  CHECK(klass->IsResolved()) << PrettyClass(klass);
1253731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  context->GetClassLinker()->VerifyClass(klass);
1254d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1255d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass->IsErroneous()) {
1256d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1257d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(Thread::Current()->IsExceptionPending());
1258d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread::Current()->ClearException();
1259d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1260d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12619ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers  CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
12629ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers      << PrettyDescriptor(klass) << ": state=" << klass->GetStatus();
1263d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
1264d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1265d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12662f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstromvoid Compiler::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
12672f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                             ThreadPool& thread_pool, TimingLogger& timings) {
1268731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
12692f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  CompilationContext context(class_linker, class_loader, this, &dex_file, thread_pool);
12700e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
12713d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  timings.AddSplit("Verify " + dex_file.GetLocation());
1272a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom}
1273a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom
127464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic const char* class_initializer_black_list[] = {
127564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/app/ActivityThread;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
127664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/bluetooth/BluetoothAudioGateway;", // Calls android.bluetooth.BluetoothAudioGateway.classInitNative().
127764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/bluetooth/HeadsetBase;", // Calls android.bluetooth.HeadsetBase.classInitNative().
127864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/content/res/CompatibilityInfo;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
127964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/content/res/CompatibilityInfo$1;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
128064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/content/UriMatcher;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/CursorWindow;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
128264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteConnection;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteConnection$Operation;", // Requires SimpleDateFormat -> java.util.Locale.
128464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteDatabaseConfiguration;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteDebug;", // Calls android.util.Log.isLoggable.
128664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteOpenHelper;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex.
128764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteQueryBuilder;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/drm/DrmManagerClient;", // Calls System.loadLibrary.
128964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/AnimatedRotateDrawable;", // Sub-class of Drawable.
129064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/AnimationDrawable;", // Sub-class of Drawable.
129164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/BitmapDrawable;", // Sub-class of Drawable.
129264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ClipDrawable;", // Sub-class of Drawable.
129364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ColorDrawable;", // Sub-class of Drawable.
129464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/Drawable;", // Requires android.graphics.Rect.
129564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/DrawableContainer;", // Sub-class of Drawable.
129664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/GradientDrawable;", // Sub-class of Drawable.
129764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/LayerDrawable;", // Sub-class of Drawable.
129864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/NinePatchDrawable;", // Sub-class of Drawable.
129964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/RotateDrawable;", // Sub-class of Drawable.
130064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ScaleDrawable;", // Sub-class of Drawable.
130164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ShapeDrawable;", // Sub-class of Drawable.
130264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/StateListDrawable;", // Sub-class of Drawable.
130364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/TransitionDrawable;", // Sub-class of Drawable.
130464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Matrix;", // Calls android.graphics.Matrix.native_create.
130564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Matrix$1;", // Requires Matrix.
130664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/PixelFormat;", // Calls android.graphics.PixelFormat.nativeClassInit().
130764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Rect;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
130864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/SurfaceTexture;", // Calls android.graphics.SurfaceTexture.nativeClassInit().
130964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Typeface;", // Calls android.graphics.Typeface.nativeCreate.
131064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/inputmethodservice/ExtractEditText;", // Requires android.widget.TextView.
131164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/CameraProfile;", // Calls System.loadLibrary.
131264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/DecoderCapabilities;", // Calls System.loadLibrary.
131364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaFile;", // Requires DecoderCapabilities.
131464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaPlayer;", // Calls System.loadLibrary.
131564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaRecorder;", // Calls System.loadLibrary.
131664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaScanner;", // Calls System.loadLibrary.
131764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/NetworkInfo;", // Calls java.util.EnumMap.<init> -> java.lang.Enum.getSharedConstants -> System.identityHashCode.
131864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Proxy;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
131964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/SSLCertificateSocketFactory;", // Requires javax.net.ssl.HttpsURLConnection.
132064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex.
132164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$AbstractHierarchicalUri;", // Requires Uri.
132264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$HierarchicalUri;", // Requires Uri.
132364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$OpaqueUri;", // Requires Uri.
132464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$StringUri;", // Requires Uri.
132564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/WebAddress;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
132664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/nfc/NdefRecord;", // Calls String.getBytes -> java.nio.charset.Charset.
132764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES10;", // Calls android.opengl.GLES10._nativeClassInit.
132864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES10Ext;", // Calls android.opengl.GLES10Ext._nativeClassInit.
132964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES11;", // Requires GLES10.
133064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES11Ext;", // Calls android.opengl.GLES11Ext._nativeClassInit.
133164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES20;", // Calls android.opengl.GLES20._nativeClassInit.
133264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLUtils;", // Calls android.opengl.GLUtils.nativeClassInit.
133364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Build;", // Calls -..-> android.os.SystemProperties.native_get.
133464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Build$VERSION;", // Requires Build.
133564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Debug;", // Requires android.os.Environment.
133664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Environment;", // Calls System.getenv.
133764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/FileUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
133864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/StrictMode;", // Calls android.util.Log.isLoggable.
133964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/StrictMode$VmPolicy;", // Requires StrictMode.
134064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Trace;", // Calls android.os.Trace.nativeGetEnabledTags.
134164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/UEventObserver;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex.
134264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/provider/Settings$Secure;", // Requires android.net.Uri.
134364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/provider/Settings$System;", // Requires android.net.Uri.
134464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/renderscript/RenderScript;", // Calls System.loadLibrary.
134564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/server/BluetoothService;", // Calls android.server.BluetoothService.classInitNative.
134664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/server/BluetoothEventLoop;", // Calls android.server.BluetoothEventLoop.classInitNative.
134764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/telephony/PhoneNumberUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
134864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/AutoText;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
134964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/Layout;", // Calls com.android.internal.util.ArrayUtils.emptyArray -> System.identityHashCode.
135064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/BoringLayout;", // Requires Layout.
135164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/DynamicLayout;", // Requires Layout.
135264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/Html$HtmlParser;", // Calls -..-> String.toLowerCase -> java.util.Locale.
135364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/StaticLayout;", // Requires Layout.
135464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/TextUtils;", // Requires android.util.DisplayMetrics.
135564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/util/DisplayMetrics;", // Calls SystemProperties.native_get_int.
135664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/util/Patterns;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
135764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/animation/Animation;", // Calls SystemProperties.native_get_boolean.
135864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/animation/AlphaAnimation;", // Requires Animation.
135964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/Choreographer;", // Calls SystemProperties.native_get_boolean.
136064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/GLES20Canvas;", // Calls android.view.GLES20Canvas.nIsAvailable.
136164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/GLES20RecordingCanvas;", // Requires android.view.GLES20Canvas.
136264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/HardwareRenderer$GlRenderer;", // Requires SystemProperties.native_get.
136364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/HardwareRenderer$Gl20Renderer;", // Requires SystemProperties.native_get.
136464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/InputEventConsistencyVerifier;", // Requires android.os.Build.
136564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/Surface;", // Requires SystemProperties.native_get.
136664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/webkit/JniUtil;", // Calls System.loadLibrary.
136764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/webkit/WebViewCore;", // Calls System.loadLibrary.
136864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/AutoCompleteTextView;", // Requires TextView.
136964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/Button;", // Requires TextView.
137064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/CheckBox;", // Requires TextView.
137164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/CheckedTextView;", // Requires TextView.
137264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/CompoundButton;", // Requires TextView.
137364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/EditText;", // Requires TextView.
137464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/NumberPicker;", // Requires java.util.Locale.
137564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/ScrollBarDrawable;", // Sub-class of Drawable.
137664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/SearchView$SearchAutoComplete;", // Requires TextView.
137764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/Switch;", // Requires TextView.
137864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/TextView;", // Calls Paint.<init> -> Paint.native_init.
137964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
138064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/i18n/phonenumbers/PhoneNumberUtil;", // Requires java.util.logging.LogManager.
138164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/os/SamplingProfilerIntegration;", // Calls SystemProperties.native_get_int.
138264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/policy/impl/PhoneWindow;", // Calls android.os.Binder.init.
138364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/view/menu/ActionMenuItemView;", // Requires TextView.
138464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/widget/DialogTitle;", // Requires TextView.
138564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/asn1/StreamUtil;", // Calls Runtime.getRuntime().maxMemory().
138664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
138764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/crypto/engines/RSABlindedEngine;", // Calls native ... -> java.math.NativeBN.BN_new().
138864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/jce/provider/CertBlacklist;", // Calls System.getenv -> OsConstants.initConstants.
138964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi;", // Calls System.getenv -> OsConstants.initConstants.
139064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/google/android/gles_jni/EGLContextImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit.
139164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/google/android/gles_jni/EGLImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit.
139264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/google/android/gles_jni/GLImpl;", // Calls com.google.android.gles_jni.GLImpl._nativeClassInit.
139364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/Console;", // Has FileDescriptor(s).
139464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/File;", // Calls to Random.<init> -> System.currentTimeMillis -> OsConstants.initConstants.
139564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/FileDescriptor;", // Requires libcore.io.OsConstants.
139664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/ObjectInputStream;", // Requires java.lang.ClassLoader$SystemClassLoader.
139764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/ObjectStreamClass;",  // Calls to Class.forName -> java.io.FileDescriptor.
139864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/ObjectStreamConstants;", // Instance of non-image class SerializablePermission.
139964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/lang/ClassLoader$SystemClassLoader;", // Calls System.getProperty -> OsConstants.initConstants.
140064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/lang/Runtime;", // Calls System.getProperty -> OsConstants.initConstants.
140164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/lang/System;", // Calls OsConstants.initConstants.
140264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/math/BigDecimal;", // Calls native ... -> java.math.NativeBN.BN_new().
140364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/math/BigInteger;", // Calls native ... -> java.math.NativeBN.BN_new().
140464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/math/Multiplication;", // Calls native ... -> java.math.NativeBN.BN_new().
140564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/net/InetAddress;", // Requires libcore.io.OsConstants.
140664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/net/Inet4Address;", // Sub-class of InetAddress.
140764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/net/Inet6Address;", // Sub-class of InetAddress.
140864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/nio/charset/Charset;", // Calls Charset.getDefaultCharset -> System.getProperty -> OsConstants.initConstants.
140964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/nio/charset/CharsetICU;", // Sub-class of Charset.
141064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/nio/charset/Charsets;", // Calls Charset.forName.
141164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/security/Security;", // Tries to do disk IO for "security.properties".
141264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/Date;", // Calls Date.<init> -> System.currentTimeMillis -> OsConstants.initConstants.
141364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/Locale;", // Calls System.getProperty -> OsConstants.initConstants.
141464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/SimpleTimeZone;", // Sub-class of TimeZone.
141564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/TimeZone;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
141664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/concurrent/ConcurrentHashMap$Segment;", // Calls Runtime.getRuntime().availableProcessors().
141764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/logging/LogManager;", // Calls System.getProperty -> OsConstants.initConstants.
141864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljavax/microedition/khronos/egl/EGL10;", // Requires EGLContext.
141964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljavax/microedition/khronos/egl/EGLContext;", // Requires com.google.android.gles_jni.EGLImpl.
142064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljavax/net/ssl/HttpsURLConnection;", // Calls SSLSocketFactory.getDefault -> java.security.Security.getProperty.
142164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/icu/LocaleData;", // Requires java.util.Locale.
142264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/icu/TimeZones;", // Requires java.util.TimeZone.
142364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/io/OsConstants;", // Platform specific.
142464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/net/MimeUtils;", // Calls libcore.net.MimeUtils.getContentTypesPropertiesStream -> System.getProperty.
142564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/util/ZoneInfo;", // Sub-class of TimeZone.
142664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/util/ZoneInfoDB;", // Calls System.getenv -> OsConstants.initConstants.
142764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/commons/logging/LogFactory;", // Calls System.getProperty.
142864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/fortress/Services;", // Calls ClassLoader.getSystemClassLoader -> System.getProperty.
142964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/provider/cert/X509CertFactoryImpl;", // Requires java.nio.charsets.Charsets.
143064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/provider/crypto/RandomBitsSupplier;", // Requires java.io.File.
143164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/utils/AlgNameMapper;", // Requires java.util.Locale.
143264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x501/AttributeTypeAndValue;", // Calls IntegralToString.convertInt -> Thread.currentThread.
143364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x501/DirectoryString;", // Requires BigInteger.
143464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x501/Name;", // Requires org.apache.harmony.security.x501.AttributeTypeAndValue.
143564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/Certificate;", // Requires org.apache.harmony.security.x509.TBSCertificate.
143664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/TBSCertificate;",  // Requires org.apache.harmony.security.x501.Name.
143764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/EDIPartyName;", // Calls native ... -> java.math.NativeBN.BN_new().
143864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/GeneralName;", // Requires org.apache.harmony.security.x501.Name.
143964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/GeneralNames;", // Requires GeneralName.
144064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/Time;", // Calls native ... -> java.math.NativeBN.BN_new().
144164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/Validity;", // Requires x509.Time.
144264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xml/ExpatParser;", // Calls native ExpatParser.staticInitialize.
144364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto;", // Calls native NativeCrypto.clinit().
144464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$MD5;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
144564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
144664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA512;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
144764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/TrustedCertificateStore;", // Calls System.getenv -> OsConstants.initConstants.
144864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/http/conn/params/ConnRouteParams;", // Requires java.util.Locale.
144964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/http/conn/ssl/SSLSocketFactory;", // Calls java.security.Security.getProperty.
145064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/http/conn/util/InetAddressUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
145164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers};
145264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers
145364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic void InitializeClass(const CompilationContext* context, size_t class_def_index)
14543d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
14553d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
145600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
14572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
14583d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def);
14592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass = context->GetClassLinker()->FindClass(descriptor, class_loader);
14601f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  Thread* self = Thread::Current();
146164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
146264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  bool can_init_static_fields = compiling_boot &&
146364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers      context->GetCompiler()->IsImageClass(descriptor);
14643d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  if (klass != NULL) {
146564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // We don't want class initialization occurring on multiple threads due to deadlock problems.
146664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // For example, a parent class is initialized (holding its lock) that refers to a sub-class
146764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // in its static/class initializer causing it to try to acquire the sub-class' lock. While
146864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // on a second thread the sub-class is initialized (holding its lock) after first initializing
146964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent
147064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // lock ordering and consequent potential deadlock.
147164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    static Mutex lock1("Initializer lock", kMonitorLock);
147264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    MutexLock mu(self, lock1);
147364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // The lock required to initialize the class.
147464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    ObjectLock lock2(self, klass);
147564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // Only try to initialize classes that were successfully verified.
14763d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    if (klass->IsVerified()) {
14773d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      context->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields);
147864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers      if (!klass->IsInitialized()) {
147964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers        if (can_init_static_fields) {
148064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          bool is_black_listed = false;
148164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
148264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            if (StringPiece(descriptor) == class_initializer_black_list[i]) {
148364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              is_black_listed = true;
148464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              break;
148564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            }
148664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          }
148764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          if (!is_black_listed) {
148864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            LOG(INFO) << "Initializing: " << descriptor;
148964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            if (StringPiece(descriptor) == "Ljava/lang/Void;"){
149064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime.
14912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers              mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields();
149264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              CHECK_EQ(fields->GetLength(), 1);
149364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              fields->Get(0)->SetObj(klass, context->GetClassLinker()->FindPrimitiveClass('V'));
14942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers              klass->SetStatus(mirror::Class::kStatusInitialized);
149564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            } else {
149664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              context->GetClassLinker()->EnsureInitialized(klass, true, can_init_static_fields);
149764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            }
149864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
149964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          }
150064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers        }
150164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers      }
15023d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      // If successfully initialized place in SSB array.
15033d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      if (klass->IsInitialized()) {
15043d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers        klass->GetDexCache()->GetInitializedStaticStorage()->Set(klass->GetDexTypeIndex(), klass);
15050755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      }
150627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    }
15073d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    // Record the final class status if necessary.
15082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class::Status status = klass->GetStatus();
15093d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    Compiler::ClassReference ref(context->GetDexFile(), class_def_index);
15103d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    CompiledClass* compiled_class = context->GetCompiler()->GetCompiledClass(ref);
15113d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    if (compiled_class == NULL) {
15123d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      compiled_class = new CompiledClass(status);
15133d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      context->GetCompiler()->RecordClassStatus(ref, compiled_class);
15143d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    } else {
15153d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      DCHECK_EQ(status, compiled_class->GetStatus());
1516ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom    }
151798eacac683b78e60799323e8c7d59e7214808639jeffhao  }
15181f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  // Clear any class not found or verification exceptions.
15191f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  self->ClearException();
152098eacac683b78e60799323e8c7d59e7214808639jeffhao}
152198eacac683b78e60799323e8c7d59e7214808639jeffhao
152264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersvoid Compiler::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
15232f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                                 ThreadPool& thread_pool, TimingLogger& timings) {
152464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#ifndef NDEBUG
152564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
152664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    const char* descriptor = class_initializer_black_list[i];
152764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    CHECK(IsValidDescriptor(descriptor)) << descriptor;
152864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  }
152964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#endif
15303d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
15312f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  CompilationContext context(class_linker, jni_class_loader, this, &dex_file, thread_pool);
153264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count_);
15333d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  timings.AddSplit("InitializeNoClinit " + dex_file.GetLocation());
15343d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers}
153590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
153664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersvoid Compiler::InitializeClasses(jobject class_loader,
153764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers                                 const std::vector<const DexFile*>& dex_files,
15382f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                                 ThreadPool& thread_pool, TimingLogger& timings) {
15393d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  for (size_t i = 0; i != dex_files.size(); ++i) {
15403d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    const DexFile* dex_file = dex_files[i];
154190dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    CHECK(dex_file != NULL);
15422f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    InitializeClasses(class_loader, *dex_file, thread_pool, timings);
154300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
154490dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao}
154590dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
15463d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
15472f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                       ThreadPool& thread_pool, TimingLogger& timings) {
1548ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1549ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
155083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom    CHECK(dex_file != NULL);
15512f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    CompileDexFile(class_loader, *dex_file, thread_pool, timings);
155283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom  }
155383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom}
155483db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom
155500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Compiler::CompileClass(const CompilationContext* context, size_t class_def_index) {
155600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject class_loader = context->GetClassLoader();
1557731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  const DexFile& dex_file = *context->GetDexFile();
1558c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
155900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  {
156000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
15612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
156200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (SkipClass(class_loader, dex_file, class_def)) {
156300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return;
156400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
15655ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  }
1566d1224c79631bd1801b067a0f212b91afa961a362jeffhao  ClassReference ref(&dex_file, class_def_index);
1567d1224c79631bd1801b067a0f212b91afa961a362jeffhao  // Skip compiling classes with generic verifier failures since they will still fail at runtime
1568776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (verifier::MethodVerifier::IsClassRejected(ref)) {
1569d1224c79631bd1801b067a0f212b91afa961a362jeffhao    return;
1570d1224c79631bd1801b067a0f212b91afa961a362jeffhao  }
15710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const byte* class_data = dex_file.GetClassData(class_def);
15720571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (class_data == NULL) {
15730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    // empty class, probably a marker interface
15740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    return;
15750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
15760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  ClassDataItemIterator it(dex_file, class_data);
15770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Skip fields
15780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextStaticField()) {
15790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
15800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
15810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextInstanceField()) {
15820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
15830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
15840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Compile direct methods
158568adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom  int64_t previous_direct_method_idx = -1;
15860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextDirectMethod()) {
15876f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    uint32_t method_idx = it.GetMemberIndex();
15886f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    if (method_idx == previous_direct_method_idx) {
15896f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // smali can create dex files with two encoded_methods sharing the same method_idx
15906f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // http://code.google.com/p/smali/issues/detail?id=119
15916f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      it.Next();
15926f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      continue;
15936f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    }
15946f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    previous_direct_method_idx = method_idx;
1595731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1596fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          it.GetMethodInvokeType(class_def), class_def_index,
1597fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          method_idx, class_loader, dex_file);
15980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
15999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
16000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Compile virtual methods
160168adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom  int64_t previous_virtual_method_idx = -1;
16020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextVirtualMethod()) {
16036f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    uint32_t method_idx = it.GetMemberIndex();
16046f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    if (method_idx == previous_virtual_method_idx) {
16056f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // smali can create dex files with two encoded_methods sharing the same method_idx
16066f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // http://code.google.com/p/smali/issues/detail?id=119
16076f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      it.Next();
16086f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      continue;
16096f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    }
16106f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    previous_virtual_method_idx = method_idx;
1611731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1612fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          it.GetMethodInvokeType(class_def), class_def_index,
1613fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          method_idx, class_loader, dex_file);
16140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
16159ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
16160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  DCHECK(!it.HasNext());
16179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
16189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
16193d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogersvoid Compiler::CompileDexFile(jobject class_loader, const DexFile& dex_file,
16202f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                              ThreadPool& thread_pool, TimingLogger& timings) {
16212f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  CompilationContext context(NULL, class_loader, this, &dex_file, thread_pool);
16220e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_);
16233d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  timings.AddSplit("Compile " + dex_file.GetLocation());
1624c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes}
1625c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes
1626a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) {
1627a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  std::string key(shorty);
1628a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  if (is_static) {
1629a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    key += "$";  // Must not be a shorty type character.
1630a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
1631a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return key;
1632a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
1633a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
1634a3760aad59f41bb0b1d46733165a2d7219ecca73Ian Rogersvoid Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
1635fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                             InvokeType invoke_type, uint32_t class_def_idx, uint32_t method_idx,
1636fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                             jobject class_loader, const DexFile& dex_file) {
1637f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  CompiledMethod* compiled_method = NULL;
1638bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns = NanoTime();
16394dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien
1640169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  if ((access_flags & kAccNative) != 0) {
164157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file);
16423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_method != NULL);
1643169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  } else if ((access_flags & kAccAbstract) != 0) {
16442cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom  } else {
1645fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx,
1646fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                   method_idx, class_loader, dex_file);
1647bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes    CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
1648bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
16493bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers  uint64_t duration_ns = NanoTime() - start_ns;
16505354ec568ace1e117d5a93dcb802a612356200edIan Rogers#ifdef ART_USE_LLVM_COMPILER
16515354ec568ace1e117d5a93dcb802a612356200edIan Rogers  const uint64_t kWarnMilliSeconds = 1000;
16525354ec568ace1e117d5a93dcb802a612356200edIan Rogers#else
16535354ec568ace1e117d5a93dcb802a612356200edIan Rogers  const uint64_t kWarnMilliSeconds = 100;
16545354ec568ace1e117d5a93dcb802a612356200edIan Rogers#endif
16555354ec568ace1e117d5a93dcb802a612356200edIan Rogers  if (duration_ns > MsToNs(kWarnMilliSeconds)) {
1656bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes    LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
16573bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers                 << " took " << PrettyDuration(duration_ns);
1658f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  }
1659f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes
166050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
1661f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  if (compiled_method != NULL) {
16620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    MethodReference ref(&dex_file, method_idx);
16630755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file);
166400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    {
166550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers      MutexLock mu(self, compiled_methods_lock_);
166600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      compiled_methods_.Put(ref, compiled_method);
166700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
16680755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file);
16692cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom  }
16709baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
167145619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers  uint32_t shorty_len;
167245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers  const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len);
1673169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  bool is_static = (access_flags & kAccStatic) != 0;
1674a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  std::string key(MakeInvokeStubKey(is_static, shorty));
1675a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key);
16760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (compiled_invoke_stub == NULL) {
1677c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao    compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len);
16780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    CHECK(compiled_invoke_stub != NULL);
1679a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    InsertInvokeStub(key, compiled_invoke_stub);
16803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
16817a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
1682c531cefbfb5394413122e9f57d211ba436cff012buzbee  if (((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) && !is_static) {
16837a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    const CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty);
16847a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    if (compiled_proxy_stub == NULL) {
16857a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len);
16867a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      CHECK(compiled_proxy_stub != NULL);
16877a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      InsertProxyStub(shorty, compiled_proxy_stub);
16887a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    }
16897a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
16907a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
169150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  if (self->IsExceptionPending()) {
169250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    ScopedObjectAccess soa(self);
169300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
169450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers        << self->GetException()->Dump();
169500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
16960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
169728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers
1698a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const {
1699a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const std::string key(MakeInvokeStubKey(is_static, shorty));
1700a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return FindInvokeStub(key);
17013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
17023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1703a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesconst CompiledInvokeStub* Compiler::FindInvokeStub(const std::string& key) const {
170450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
17050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
17060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (it == compiled_invoke_stubs_.end()) {
17073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    return NULL;
17080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  } else {
17090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    DCHECK(it->second != NULL);
17100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    return it->second;
17113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
17123320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
17133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1714a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesvoid Compiler::InsertInvokeStub(const std::string& key,
17150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                                const CompiledInvokeStub* compiled_invoke_stub) {
171650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
1717a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key);
1718a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  if (it != compiled_invoke_stubs_.end()) {
1719a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    // Someone else won the race.
1720a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    delete compiled_invoke_stub;
1721a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  } else {
1722a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    compiled_invoke_stubs_.Put(key, compiled_invoke_stub);
1723a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
17240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
17250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
17267a2a23a44d27f769718e28327af671f4e486c49aLogan Chienconst CompiledInvokeStub* Compiler::FindProxyStub(const char* shorty) const {
172750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
17287a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty);
17297a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  if (it == compiled_proxy_stubs_.end()) {
17307a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    return NULL;
17317a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  } else {
17327a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    DCHECK(it->second != NULL);
17337a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    return it->second;
17347a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
17357a2a23a44d27f769718e28327af671f4e486c49aLogan Chien}
17367a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
17377a2a23a44d27f769718e28327af671f4e486c49aLogan Chienvoid Compiler::InsertProxyStub(const char* shorty,
17387a2a23a44d27f769718e28327af671f4e486c49aLogan Chien                               const CompiledInvokeStub* compiled_proxy_stub) {
173950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
17407a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty);
17417a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  if (it != compiled_proxy_stubs_.end()) {
17427a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    // Someone else won the race.
17437a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    delete compiled_proxy_stub;
17447a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  } else {
17457a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    compiled_proxy_stubs_.Put(shorty, compiled_proxy_stub);
17467a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
17477a2a23a44d27f769718e28327af671f4e486c49aLogan Chien}
17487a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
17490755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian CarlstromCompiledClass* Compiler::GetCompiledClass(ClassReference ref) const {
175050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_classes_lock_);
17510755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  ClassTable::const_iterator it = compiled_classes_.find(ref);
17520755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  if (it == compiled_classes_.end()) {
17530755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    return NULL;
17540755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  }
17550755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  CHECK(it->second != NULL);
17560755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  return it->second;
17570755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom}
17580755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom
17590571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersCompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const {
176050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_methods_lock_);
17610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  MethodTable::const_iterator it = compiled_methods_.find(ref);
17620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (it == compiled_methods_.end()) {
17633320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    return NULL;
17642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
17653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  CHECK(it->second != NULL);
17663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  return it->second;
17679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
17689ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
17698b977d38483aaa08abcbdaa5fa888076c1142169Logan Chienvoid Compiler::SetBitcodeFileName(std::string const& filename) {
1770106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  typedef void (*SetBitcodeFileNameFn)(Compiler&, std::string const&);
1771106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
1772106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  SetBitcodeFileNameFn set_bitcode_file_name =
17738c4bbb55d0d801e492d849ee636771c8b2840429buzbee    FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(compiler_backend_), compiler_library_,
1774106b2a03be66748a25b9019e4c222cee498d559fLogan Chien                                       "compilerLLVMSetBitcodeFileName");
1775106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
1776106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  set_bitcode_file_name(*this, filename);
17778b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien}
1778f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
1779fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
1780fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogersvoid Compiler::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
1781fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                             size_t class_def_index) {
1782fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  MutexLock mu(self, freezing_constructor_lock_);
1783fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
1784fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers}
1785fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
1786fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogersbool Compiler::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
1787fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          size_t class_def_index) {
1788fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  MutexLock mu(self, freezing_constructor_lock_);
1789fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
1790fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers}
1791fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
1792700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrombool Compiler::WriteElf(std::vector<uint8_t>& oat_contents, File* file) {
1793700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  typedef bool (*WriteElfFn)(Compiler&, std::vector<uint8_t>&, File*);
1794700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  WriteElfFn WriteElf =
1795700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf");
1796700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  return WriteElf(*this, oat_contents, file);
1797700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
1798700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1799700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrombool Compiler::FixupElf(File* file, uintptr_t oat_data_begin) const {
1800700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  typedef bool (*FixupElfFn)(File*, uintptr_t oat_data_begin);
1801700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  FixupElfFn FixupElf =
1802700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    FindFunction<FixupElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "FixupElf");
1803700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  return FixupElf(file, oat_data_begin);
1804700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
1805700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1806700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromvoid Compiler::GetOatElfInformation(File* file,
1807700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                    size_t& oat_loaded_size,
1808700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                    size_t& oat_data_offset) const {
1809700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  typedef bool (*GetOatElfInformationFn)(File*, size_t& oat_loaded_size, size_t& oat_data_offset);
1810700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  GetOatElfInformationFn GetOatElfInformation =
1811700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    FindFunction<GetOatElfInformationFn>(MakeCompilerSoName(compiler_backend_), compiler_library_,
1812700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                         "GetOatElfInformation");
1813700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  GetOatElfInformation(file, oat_loaded_size, oat_data_offset);
1814700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
1815700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1816700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromvoid Compiler::InstructionSetToLLVMTarget(InstructionSet instruction_set,
1817700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                          std::string& target_triple,
1818700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                          std::string& target_cpu,
1819700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                          std::string& target_attr) {
1820700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    switch (instruction_set) {
1821700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kThumb2:
1822700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "thumb-none-linux-gnueabi";
1823700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_cpu = "cortex-a9";
1824700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db";
1825700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1826700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1827700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kArm:
1828700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "armv7-none-linux-gnueabi";
1829700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // TODO: Fix for Nexus S.
1830700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_cpu = "cortex-a9";
1831700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // TODO: Fix for Xoom.
1832700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "+v7,+neon,+neonfp,+vfp3,+db";
1833700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1834700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1835700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kX86:
1836700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "i386-pc-linux-gnu";
1837700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "";
1838700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1839700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1840700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kMips:
1841700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "mipsel-unknown-linux";
1842700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "mips32r2";
1843700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1844700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1845700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    default:
1846700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(FATAL) << "Unknown instruction set: " << instruction_set;
1847700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
1848700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
18499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}  // namespace art
1850