compiler_driver.cc revision 265091e581c9f643b37e7966890911f09e223269
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
171212a022fa5f8ef9585d765b1809521812af882cIan Rogers#include "compiler_driver.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"
25a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal#include "base/timing_logger.h"
269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h"
2789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers#include "dex_compilation_unit.h"
289baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h"
293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "oat_file.h"
3000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "oat/runtime/stub.h"
316d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
321f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h"
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "gc/card_table-inl.h"
347469ebf3888b8037421cb6834f37f946646265ecMathieu Chartier#include "gc/space.h"
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/dex_cache.h"
382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h"
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h"
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h"
4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
4400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h"
4550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers#include "thread.h"
460e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier#include "thread_pool.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.
24900bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom  std::string library_name(StringPrintf("art%s-compiler", suffix));
250059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  std::string filename(StringPrintf(OS_SHARED_LIB_FORMAT_STR, library_name.c_str()));
251059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
252059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#if defined(__APPLE__)
253059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // On Linux, dex2oat will have been built with an RPATH of $ORIGIN/../lib, so dlopen(3) will find
254059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // the .so by itself. On Mac OS, there isn't really an equivalent, so we have to manually do the
255059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // same work.
256059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  uint32_t executable_path_length = 0;
257448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  _NSGetExecutablePath(NULL, &executable_path_length);
258448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  std::string path(executable_path_length, static_cast<char>(0));
259448e93c728b352729afde3c8e95e902c08b1d929Elliott Hughes  CHECK_EQ(_NSGetExecutablePath(&path[0], &executable_path_length), 0);
260059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
261059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Strip the "/dex2oat".
262059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  size_t last_slash = path.find_last_of('/');
263059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  CHECK_NE(last_slash, std::string::npos) << path;
264059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  path.resize(last_slash);
265059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
266059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  // Strip the "/bin".
267059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  last_slash = path.find_last_of('/');
268059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  path.resize(last_slash);
269059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes
270059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  filename = path + "/lib/" + filename;
271059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes#endif
272059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  return filename;
273b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes}
274b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
27546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughestemplate<typename Fn>
27646f060a53fffc14333096f0a48f95730ee4768eeElliott Hughesstatic Fn FindFunction(const std::string& compiler_so_name, void* library, const char* name) {
27746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  Fn fn = reinterpret_cast<Fn>(dlsym(library, name));
27846f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  if (fn == NULL) {
27946f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes    LOG(FATAL) << "Couldn't find \"" << name << "\" in compiler library " << compiler_so_name << ": " << dlerror();
28046f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  }
281059d5c142b0ef1fa421153cdcc2326c5c56fd530Elliott Hughes  VLOG(compiler) << "Found \"" << name << "\" at " << reinterpret_cast<void*>(fn);
28246f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes  return fn;
28346f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes}
28446f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes
2851212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set,
2861212a022fa5f8ef9585d765b1809521812af882cIan Rogers                               bool image, size_t thread_count, bool support_debugging,
2871212a022fa5f8ef9585d765b1809521812af882cIan Rogers                               const std::set<std::string>* image_classes, bool dump_stats,
2881212a022fa5f8ef9585d765b1809521812af882cIan Rogers                               bool dump_timings)
289c531cefbfb5394413122e9f57d211ba436cff012buzbee    : compiler_backend_(compiler_backend),
290c531cefbfb5394413122e9f57d211ba436cff012buzbee      instruction_set_(instruction_set),
291fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers      freezing_constructor_lock_("freezing constructor lock"),
292c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_classes_lock_("compiled classes lock"),
293c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_methods_lock_("compiled method lock"),
294c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes      compiled_invoke_stubs_lock_("compiled invoke stubs lock"),
2957a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      compiled_proxy_stubs_lock_("compiled proxy stubs lock"),
296aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom      image_(image),
2975523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      thread_count_(thread_count),
298de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes      support_debugging_(support_debugging),
29900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      start_ns_(0),
300c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers      stats_(new AOTCompilationStats),
301ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom      dump_stats_(dump_stats),
302ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom      dump_timings_(dump_timings),
303b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes      image_classes_(image_classes),
304b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes      compiler_library_(NULL),
30546f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes      compiler_(NULL),
3066f4976c1a9fdaf108974143cd11e6b46037fd24eElliott Hughes      compiler_context_(NULL),
30746f060a53fffc14333096f0a48f95730ee4768eeElliott Hughes      jni_compiler_(NULL),
3081212a022fa5f8ef9585d765b1809521812af882cIan Rogers      create_invoke_stub_(NULL),
3091212a022fa5f8ef9585d765b1809521812af882cIan Rogers      compiler_get_method_code_addr_(NULL),
3101212a022fa5f8ef9585d765b1809521812af882cIan Rogers      compiler_get_method_invoke_stub_addr_(NULL)
311971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien{
3128c4bbb55d0d801e492d849ee636771c8b2840429buzbee  std::string compiler_so_name(MakeCompilerSoName(compiler_backend_));
313b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY);
314b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (compiler_library_ == NULL) {
315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    LOG(FATAL) << "Couldn't find compiler library " << compiler_so_name << ": " << dlerror();
316b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
317b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  VLOG(compiler) << "dlopen(\"" << compiler_so_name << "\", RTLD_LAZY) returned " << compiler_library_;
318b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
3194df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key");
3204df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee
321c531cefbfb5394413122e9f57d211ba436cff012buzbee  // TODO: more work needed to combine initializations and allow per-method backend selection
3221212a022fa5f8ef9585d765b1809521812af882cIan Rogers  typedef void (*InitCompilerContextFn)(CompilerDriver&);
323c531cefbfb5394413122e9f57d211ba436cff012buzbee  InitCompilerContextFn init_compiler_context;
324c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if (compiler_backend_ == kPortable){
325c531cefbfb5394413122e9f57d211ba436cff012buzbee    // Initialize compiler_context_
3261212a022fa5f8ef9585d765b1809521812af882cIan Rogers    init_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name,
327c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                  compiler_library_, "ArtInitCompilerContext");
328c531cefbfb5394413122e9f57d211ba436cff012buzbee    compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod");
329c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
3301212a022fa5f8ef9585d765b1809521812af882cIan Rogers    init_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name,
331c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                  compiler_library_, "ArtInitQuickCompilerContext");
332c531cefbfb5394413122e9f57d211ba436cff012buzbee    compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtQuickCompileMethod");
333c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
334692be80cb2278ae585a776a163bc4b3ef60cae88buzbee
335692be80cb2278ae585a776a163bc4b3ef60cae88buzbee  init_compiler_context(*this);
336106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
337c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if (compiler_backend_ == kPortable) {
33800bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom    jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtLLVMJniCompileMethod");
33900bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom  } else {
34000bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom    jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtQuickJniCompileMethod");
34100bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom  }
34200bc1dc4f81268d78d7dfeb298b85c56876425a9Brian Carlstrom
343c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if (compiler_backend_ == kPortable) {
34402031b185b4653e6c72e21f7a51238b903f6d638buzbee    create_invoke_stub_ =
34502031b185b4653e6c72e21f7a51238b903f6d638buzbee        FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateLLVMInvokeStub");
34602031b185b4653e6c72e21f7a51238b903f6d638buzbee  } else {
34702031b185b4653e6c72e21f7a51238b903f6d638buzbee    switch (instruction_set) {
34802031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kArm:
34902031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kThumb2:
35002031b185b4653e6c72e21f7a51238b903f6d638buzbee        create_invoke_stub_ =
35102031b185b4653e6c72e21f7a51238b903f6d638buzbee            FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateArmInvokeStub");
35202031b185b4653e6c72e21f7a51238b903f6d638buzbee        break;
35302031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kMips:
35402031b185b4653e6c72e21f7a51238b903f6d638buzbee        create_invoke_stub_ =
35502031b185b4653e6c72e21f7a51238b903f6d638buzbee            FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateMipsInvokeStub");
35602031b185b4653e6c72e21f7a51238b903f6d638buzbee        break;
35702031b185b4653e6c72e21f7a51238b903f6d638buzbee      case kX86:
35802031b185b4653e6c72e21f7a51238b903f6d638buzbee        create_invoke_stub_ =
35902031b185b4653e6c72e21f7a51238b903f6d638buzbee            FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateX86InvokeStub");
36002031b185b4653e6c72e21f7a51238b903f6d638buzbee        break;
36102031b185b4653e6c72e21f7a51238b903f6d638buzbee      default:
36202031b185b4653e6c72e21f7a51238b903f6d638buzbee        LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
36302031b185b4653e6c72e21f7a51238b903f6d638buzbee    }
36402031b185b4653e6c72e21f7a51238b903f6d638buzbee  }
365b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes
366c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if (compiler_backend_ == kPortable) {
367c531cefbfb5394413122e9f57d211ba436cff012buzbee    create_proxy_stub_ = FindFunction<CreateProxyStubFn>(
368c531cefbfb5394413122e9f57d211ba436cff012buzbee        compiler_so_name, compiler_library_, "ArtCreateProxyStub");
369c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
370f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
37125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  CHECK(!Runtime::Current()->IsStarted());
372ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (!image_) {
373ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    CHECK(image_classes_ == NULL);
374ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
375c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao}
376c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao
3771212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerDriver::~CompilerDriver() {
37850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
379c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
38050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_classes_lock_);
381c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_classes_);
382c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  }
383c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
38450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_methods_lock_);
385c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_methods_);
386c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  }
387c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  {
38850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_invoke_stubs_lock_);
389c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes    STLDeleteValues(&compiled_invoke_stubs_);
390bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
391f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  {
39250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_proxy_stubs_lock_);
3937a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    STLDeleteValues(&compiled_proxy_stubs_);
3947a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
3957a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  {
39650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_methods_lock_);
397f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    STLDeleteElements(&code_to_patch_);
398f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  }
399f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  {
40050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, compiled_methods_lock_);
401f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    STLDeleteElements(&methods_to_patch_);
402f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  }
403ed6d5ed3494648780b9e91422c90d6bc22c16b79Mathieu Chartier  CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key");
4041212a022fa5f8ef9585d765b1809521812af882cIan Rogers  typedef void (*UninitCompilerContextFn)(CompilerDriver&);
4058c4bbb55d0d801e492d849ee636771c8b2840429buzbee  std::string compiler_so_name(MakeCompilerSoName(compiler_backend_));
406c531cefbfb5394413122e9f57d211ba436cff012buzbee  UninitCompilerContextFn uninit_compiler_context;
407692be80cb2278ae585a776a163bc4b3ef60cae88buzbee  // Uninitialize compiler_context_
408c531cefbfb5394413122e9f57d211ba436cff012buzbee  // TODO: rework to combine initialization/uninitialization
409c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if (compiler_backend_ == kPortable) {
4101212a022fa5f8ef9585d765b1809521812af882cIan Rogers    uninit_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name,
411c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                    compiler_library_, "ArtUnInitCompilerContext");
412c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
4131212a022fa5f8ef9585d765b1809521812af882cIan Rogers    uninit_compiler_context = FindFunction<void (*)(CompilerDriver&)>(compiler_so_name,
414c531cefbfb5394413122e9f57d211ba436cff012buzbee                                                    compiler_library_, "ArtUnInitQuickCompilerContext");
415c531cefbfb5394413122e9f57d211ba436cff012buzbee  }
416692be80cb2278ae585a776a163bc4b3ef60cae88buzbee  uninit_compiler_context(*this);
417b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  if (compiler_library_ != NULL) {
418b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    VLOG(compiler) << "dlclose(" << compiler_library_ << ")";
419ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee    /*
420ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * FIXME: Temporary workaround
421ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * Apparently, llvm is adding dctors to atexit, but if we unload
422ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * the library here the code will no longer be around at exit time
423ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * and we die a flaming death in __cxa_finalize().  Apparently, some
424ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * dlclose() implementations will scan the atexit list on unload and
425ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * handle any associated with the soon-to-be-unloaded library.
426ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * However, this is not required by POSIX and we don't do it.
427ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * See: http://b/issue?id=4998315
428ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     * What's the right thing to do here?
429ca7a5e484ac02927247cc77ad40f291bf6613ed5buzbee     */
430b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes    dlclose(compiler_library_);
431b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes  }
4323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
4333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
4341212a022fa5f8ef9585d765b1809521812af882cIan RogersCompilerTls* CompilerDriver::GetTls() {
4354df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  // Lazily create thread-local storage
4364df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_));
4374df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  if (res == NULL) {
4384df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee    res = new CompilerTls();
4394df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee    CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls");
4404df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  }
4414df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee  return res;
4424df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee}
4434df2bbdfe6602ce5f141b7b44028b95faa0bd8efbuzbee
4441212a022fa5f8ef9585d765b1809521812af882cIan Rogersmirror::ByteArray* CompilerDriver::CreateResolutionStub(InstructionSet instruction_set,
4451212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                        Runtime::TrampolineType type) {
4467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  switch (instruction_set) {
4477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kArm:
4487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kThumb2:
4497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return arm::ArmCreateResolutionTrampoline(type);
4507fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kMips:
4517fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return mips::MipsCreateResolutionTrampoline(type);
4527fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kX86:
4537fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return x86::X86CreateResolutionTrampoline(type);
4547fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    default:
4557fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
4567fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return NULL;
457ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
458ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
459ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
4601212a022fa5f8ef9585d765b1809521812af882cIan Rogersmirror::ByteArray* CompilerDriver::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
461169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  switch (instruction_set) {
462169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kArm:
463169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kThumb2:
4648add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes      return arm::CreateJniDlsymLookupStub();
4657fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kMips:
4667fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return mips::CreateJniDlsymLookupStub();
467169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    case kX86:
4688add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes      return x86::CreateJniDlsymLookupStub();
469169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers    default:
47049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
471169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers      return NULL;
472169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  }
473169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers}
474169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers
4751212a022fa5f8ef9585d765b1809521812af882cIan Rogersmirror::ByteArray* CompilerDriver::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
4767fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  switch (instruction_set) {
4777fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kArm:
4787fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kThumb2:
4797fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return arm::CreateAbstractMethodErrorStub();
4807fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kMips:
4817fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return mips::CreateAbstractMethodErrorStub();
4827fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    case kX86:
4837fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return x86::CreateAbstractMethodErrorStub();
4847fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    default:
4857fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
4867fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao      return NULL;
487ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
488ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
489ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
4901212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileAll(jobject class_loader,
4911212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                const std::vector<const DexFile*>& dex_files) {
49225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  DCHECK(!Runtime::Current()->IsStarted());
493ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
49456edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_));
495a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal  TimingLogger timings("compiler", false);
496601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
49756edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  PreCompile(class_loader, dex_files, *thread_pool.get(), timings);
498601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
49956edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  Compile(class_loader, dex_files, *thread_pool.get(), timings);
500601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
501ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  if (dump_timings_ && timings.GetTotalNs() > MsToNs(1000)) {
502a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal    LOG(INFO) << Dumpable<TimingLogger>(timings);
503601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes  }
504996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers
505ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  if (dump_stats_) {
506ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom    stats_->Dump();
507ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom  }
5088a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom}
5098a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom
5101212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileOne(const mirror::AbstractMethod* method) {
51125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  DCHECK(!Runtime::Current()->IsStarted());
51200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
51300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject class_loader;
51400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile* dex_file;
515fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  uint32_t class_def_idx;
51600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  {
51700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccessUnchecked soa(self);
51800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedLocalRef<jobject>
51900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      local_class_loader(soa.Env(),
52000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
52100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    class_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
52200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Find the dex_file
523fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    MethodHelper mh(method);
524fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    dex_file = &mh.GetDexFile();
525fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    class_def_idx = mh.GetClassDefIndex();
52600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
52700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->TransitionFromRunnableToSuspended(kNative);
528ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
529ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  std::vector<const DexFile*> dex_files;
53000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  dex_files.push_back(dex_file);
531ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
53256edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  UniquePtr<ThreadPool> thread_pool(new ThreadPool(1U));
533a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal  TimingLogger timings("CompileOne", false);
53456edc432fa914f7ccfa87ce443e64f5ef475666dIan Rogers  PreCompile(class_loader, dex_files, *thread_pool.get(), timings);
535ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  uint32_t method_idx = method->GetDexMethodIndex();
53700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
53808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  CompileMethod(code_item, method->GetAccessFlags(), method->GetInvokeType(),
539fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                class_def_idx, method_idx, class_loader, *dex_file);
540ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
54100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->GetJniEnv()->DeleteGlobalRef(class_loader);
54200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
54300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->TransitionFromSuspendedToRunnable();
5449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
5459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
5461212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
5471212a022fa5f8ef9585d765b1809521812af882cIan Rogers                             ThreadPool& thread_pool, TimingLogger& timings) {
548ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
549ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
5509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    CHECK(dex_file != NULL);
5512f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    ResolveDexFile(class_loader, *dex_file, thread_pool, timings);
5529ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
5539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
5549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
5551212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
5561212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                ThreadPool& thread_pool, TimingLogger& timings) {
5572f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  Resolve(class_loader, dex_files, thread_pool, timings);
558601a12302407d8199503d2cc6cc0829d5996696dElliott Hughes
5592f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  Verify(class_loader, dex_files, thread_pool, timings);
560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5612f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom  InitializeClasses(class_loader, dex_files, thread_pool, timings);
562ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
563ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5641212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::IsImageClass(const std::string& descriptor) const {
565ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_ == NULL) {
566ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
567ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
568ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  return image_classes_->find(descriptor) != image_classes_->end();
569ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}
570ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
5711212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) {
5721212a022fa5f8ef9585d765b1809521812af882cIan Rogers  MutexLock mu(Thread::Current(), CompilerDriver::compiled_classes_lock_);
5733d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  compiled_classes_.Put(ref, compiled_class);
5743d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers}
5753d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers
5761212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file,
5771212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                      uint32_t type_idx) {
57800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
5792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
5806d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (!IsImage()) {
581c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
5826d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return false;
5836d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
5842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
5856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  if (resolved_class == NULL) {
586c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
5876d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    return false;
5886d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  }
589996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor());
590996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
591c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeInDexCache();
592996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
593c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNotInDexCache();
594996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
595996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
5966d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers}
5976d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers
5981212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
5991212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                        uint32_t string_idx) {
6001bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // See also Compiler::ResolveDexFile
6011bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6025f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers  bool result = false;
6035f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers  if (IsImage()) {
6045f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers    // We resolve all const-string strings when building for the image.
60500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
6062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
6075f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers    Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache);
6085f7fa551162b9e755fdaf054ffc89411a0e135e3Ian Rogers    result = true;
60900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
610996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
611c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->StringInDexCache();
612996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
613c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->StringNotInDexCache();
614996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
615996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
6161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6181212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
6191212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                uint32_t type_idx) {
62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
6212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
6221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Get type from dex cache assuming it was populated by the verifier
6232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
6241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_class == NULL) {
625c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Unknown class needs access checks.
6271bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6281bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
6292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
6301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (referrer_class == NULL) {
631c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Incomplete referrer knowledge needs access check.
6331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6341bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Perform access check, will return true if access is ok or false if we're going to have to
6351bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // check this at runtime (for example for class loaders).
636996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = referrer_class->CanAccess(resolved_class);
637996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
638c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeDoesntNeedAccessCheck();
639996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
640c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
641996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
642996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
6431bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6451212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
6461212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                            const DexFile& dex_file,
6471212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                            uint32_t type_idx) {
64800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
6492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
6501bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Get type from dex cache assuming it was populated by the verifier.
6512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
6521bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (resolved_class == NULL) {
653c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6541bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Unknown class needs access checks.
6551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
6572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
6581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  if (referrer_class == NULL) {
659c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
6601bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    return false;  // Incomplete referrer knowledge needs access check.
6611bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
6621bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Perform access and instantiable checks, will return true if access is ok or false if we're
6631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // going to have to check this at runtime (for example for class loaders).
664996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
665996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  if (result) {
666c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeDoesntNeedAccessCheck();
667996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  } else {
668c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    stats_->TypeNeedsAccessCheck();
669996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  }
670996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers  return result;
6711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
6721bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
6732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
67489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                   const DexCompilationUnit* mUnit)
675b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
67689756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
67789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader());
67889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex());
67989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  return mUnit->GetClassLinker()->ResolveType(*mUnit->GetDexFile(), referrer_method_id.class_idx_,
68089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                              dex_cache, class_loader);
6814dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien}
682a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa,
68489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                                const DexCompilationUnit* mUnit,
6852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                uint32_t field_idx)
686b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
68789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
68889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader());
68989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  return mUnit->GetClassLinker()->ResolveField(*mUnit->GetDexFile(), field_idx, dex_cache,
69089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                               class_loader, false);
691a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
692a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
6932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic mirror::AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa,
69489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                                          const DexCompilationUnit* mUnit,
6952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                          uint32_t method_idx,
6962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                          InvokeType type)
697b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
69889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
69989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader());
70089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers  return mUnit->GetClassLinker()->ResolveMethod(*mUnit->GetDexFile(), method_idx, dex_cache,
70189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                class_loader, NULL, type);
702a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
703a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
70489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
7051212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                              int& field_offset, bool& is_volatile, bool is_put) {
70600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
70708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Conservative defaults.
7081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  field_offset = -1;
7091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_volatile = true;
71008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Try to resolve field and ignore if an Incompatible Class Change Error (ie is static).
7112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
71208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  if (resolved_field != NULL && !resolved_field->IsStatic()) {
7132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
714e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers    if (referrer_class != NULL) {
7152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* fields_class = resolved_field->GetDeclaringClass();
716e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      bool access_ok = referrer_class->CanAccess(fields_class) &&
717e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                       referrer_class->CanAccessMember(fields_class,
718e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                       resolved_field->GetAccessFlags());
719e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (!access_ok) {
720e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // The referring class can't access the resolved field, this may occur as a result of a
721e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // protected field being made public by a sub-class. Resort to the dex file to determine
722e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        // the correct class for the access check.
7234445a7e3398a6143939168097a3aa275b734504dIan Rogers        const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
72489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers        mirror::Class* dex_fields_class = mUnit->GetClassLinker()->ResolveType(dex_file,
725e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         dex_file.GetFieldId(field_idx).class_idx_,
726e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         referrer_class);
727e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        access_ok = referrer_class->CanAccess(dex_fields_class) &&
728e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                    referrer_class->CanAccessMember(dex_fields_class,
729e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                    resolved_field->GetAccessFlags());
730e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
731e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() &&
732e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          fields_class != referrer_class;
733e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      if (access_ok && !is_write_to_final_from_wrong_class) {
734e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        field_offset = resolved_field->GetOffset().Int32Value();
735e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        is_volatile = resolved_field->IsVolatile();
736e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        stats_->ResolvedInstanceField();
737e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        return true;  // Fast path.
738e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers      }
7391bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    }
7401bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
7411bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Clean up any exception left by field/type resolution
74200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (soa.Self()->IsExceptionPending()) {
74300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ClearException();
7441bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
745c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedInstanceField();
7461bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  return false;  // Incomplete knowledge needs slow path.
7471bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
7481bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
74989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
7501212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                            int& field_offset, int& ssb_index,
7511212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                            bool& is_referrers_class, bool& is_volatile,
7521212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                            bool is_put) {
75300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
75408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Conservative defaults.
7551bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  field_offset = -1;
7561bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  ssb_index = -1;
7571bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_referrers_class = false;
7581bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  is_volatile = true;
75908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  // Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static).
7602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
76108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  if (resolved_field != NULL && resolved_field->IsStatic()) {
7622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
7631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    if (referrer_class != NULL) {
7642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* fields_class = resolved_field->GetDeclaringClass();
7658cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao      if (fields_class == referrer_class) {
7661bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        is_referrers_class = true;  // implies no worrying about class initialization
7671bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        field_offset = resolved_field->GetOffset().Int32Value();
7681bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        is_volatile = resolved_field->IsVolatile();
769c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers        stats_->ResolvedLocalStaticField();
7701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        return true;  // fast path
7711bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      } else {
772e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        bool access_ok = referrer_class->CanAccess(fields_class) &&
773e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                         referrer_class->CanAccessMember(fields_class,
774e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                         resolved_field->GetAccessFlags());
775e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        if (!access_ok) {
776e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // The referring class can't access the resolved field, this may occur as a result of a
777e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // protected field being made public by a sub-class. Resort to the dex file to determine
778e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // the correct class for the access check. Don't change the field's class as that is
779e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // used to identify the SSB.
7804445a7e3398a6143939168097a3aa275b734504dIan Rogers          const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
7812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers          mirror::Class* dex_fields_class =
78289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers              mUnit->GetClassLinker()->ResolveType(dex_file,
78389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                   dex_file.GetFieldId(field_idx).class_idx_,
78489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                   referrer_class);
785e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          access_ok = referrer_class->CanAccess(dex_fields_class) &&
786e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                      referrer_class->CanAccessMember(dex_fields_class,
787e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers                                                      resolved_field->GetAccessFlags());
788e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        }
7898cd6ddaeb78cc904e13bac88753654a04b2e15b8jeffhao        bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal();
790e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers        if (access_ok && !is_write_to_final_from_wrong_class) {
7911bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          // We have the resolved field, we must make it into a ssbIndex for the referrer
7921bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          // in its static storage base (which may fail if it doesn't have a slot for it)
7934103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          // TODO: for images we can elide the static storage base null check
7944103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          // if we know there's a non-null entry in the image
79589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers          mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
79600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          if (fields_class->GetDexCache() == dex_cache) {
7974103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            // common case where the dex cache of both the referrer and the field are the same,
7984103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            // no need to search the dex file
7994103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            ssb_index = fields_class->GetDexTypeIndex();
8004103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            field_offset = resolved_field->GetOffset().Int32Value();
8014103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            is_volatile = resolved_field->IsVolatile();
802c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers            stats_->ResolvedStaticField();
8034103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers            return true;
8044103ad2ab59488fe4eb36b88259e402e8878878bIan Rogers          }
805e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // Search dex file for localized ssb index, may fail if field's class is a parent
806e2645d3e2db211bfd75775a2185c135ff387161aIan Rogers          // of the class mentioned in the dex file and there is no dex cache entry.
8071bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor());
8081bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          const DexFile::StringId* string_id =
80989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers          mUnit->GetDexFile()->FindStringId(descriptor);
8101bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          if (string_id != NULL) {
8111bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers            const DexFile::TypeId* type_id =
81289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers               mUnit->GetDexFile()->FindTypeId(mUnit->GetDexFile()->GetIndexForStringId(*string_id));
813b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes            if (type_id != NULL) {
8141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              // medium path, needs check of static storage base being initialized
81589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers              ssb_index = mUnit->GetDexFile()->GetIndexForTypeId(*type_id);
8161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              field_offset = resolved_field->GetOffset().Int32Value();
8171bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              is_volatile = resolved_field->IsVolatile();
818c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers              stats_->ResolvedStaticField();
8191bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers              return true;
8201bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers            }
8211bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers          }
8221bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers        }
8231bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers      }
8241bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    }
8251bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
8261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  // Clean up any exception left by field/type resolution
82700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (soa.Self()->IsExceptionPending()) {
82800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ClearException();
8291bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  }
830c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedStaticField();
8311bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers  return false;  // Incomplete knowledge needs slow path.
8321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers}
8331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
8341212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type,
8351212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                   mirror::AbstractMethod* method,
8361212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                   uintptr_t& direct_code,
8371212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                   uintptr_t& direct_method) {
838137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // For direct and static methods compute possible direct_code and direct_method values, ie
839137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // an address for the Method* being invoked and an address of the code for that Method*.
840137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // For interface calls compute a value for direct_method that is the interface method being
841137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  // invoked, so this can be passed to the out-of-line runtime support code.
8422ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_code = 0;
8432ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_method = 0;
844c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if (compiler_backend_ == kPortable) {
845c531cefbfb5394413122e9f57d211ba436cff012buzbee    if (sharp_type != kStatic && sharp_type != kDirect) {
846c531cefbfb5394413122e9f57d211ba436cff012buzbee      return;
847c531cefbfb5394413122e9f57d211ba436cff012buzbee    }
848c531cefbfb5394413122e9f57d211ba436cff012buzbee  } else {
849c531cefbfb5394413122e9f57d211ba436cff012buzbee    if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) {
850c531cefbfb5394413122e9f57d211ba436cff012buzbee      return;
851c531cefbfb5394413122e9f57d211ba436cff012buzbee    }
852b8404a7de94c109e3c17b4205b5f8aaae996eb33TDYa  }
8532ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  bool method_code_in_boot = method->GetDeclaringClass()->GetClassLoader() == NULL;
8542ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (!method_code_in_boot) {
8552ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
8562ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
8572ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  bool has_clinit_trampoline = method->IsStatic() && !method->GetDeclaringClass()->IsInitialized();
8582ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  if (has_clinit_trampoline) {
8592ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers    return;
8602ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
861c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers  if (sharp_type != kInterface) {  // Interfaces always go via a trampoline.
862c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers    stats_->DirectCallsToBoot(type);
863c468e92d1e18305a5053c8a4a7c88cb297e525afIan Rogers  }
8642ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  stats_->DirectMethodsToBoot(type);
8653fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
8663fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  if (compiling_boot) {
8670637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom    const bool kSupportBootImageFixup = true;
8683fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    if (kSupportBootImageFixup) {
8693fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      MethodHelper mh(method);
8703fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      if (IsImageClass(mh.GetDeclaringClassDescriptor())) {
8710637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        // We can only branch directly to Methods that are resolved in the DexCache.
8720637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        // Otherwise we won't invoke the resolution trampoline.
8733fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers        direct_method = -1;
8740637e27af8e54f39634024dc77e8b094f21782f9Brian Carlstrom        direct_code = -1;
8753fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      }
8763fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    }
8773fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers  } else {
878b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    if (Runtime::Current()->GetHeap()->FindSpaceFromObject(method)->IsImageSpace()) {
8793fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers      direct_method = reinterpret_cast<uintptr_t>(method);
8803fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    }
8813fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers    direct_code = reinterpret_cast<uintptr_t>(method->GetCode());
8822ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  }
8832ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers}
8842ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers
88589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool CompilerDriver::ComputeInvokeInfo(uint32_t method_idx, const DexCompilationUnit* mUnit,
8861212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                       InvokeType& type, int& vtable_idx, uintptr_t& direct_code,
8871212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                       uintptr_t& direct_method) {
88800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
889a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  vtable_idx = -1;
8902ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_code = 0;
8912ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers  direct_method = 0;
8922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::AbstractMethod* resolved_method =
89308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers      ComputeMethodReferencedFromCompilingMethod(soa, mUnit, method_idx, type);
894a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  if (resolved_method != NULL) {
89508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    // Don't try to fast-path if we don't understand the caller's class or this appears to be an
89608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    // Incompatible Class Change Error.
8972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
89808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    bool icce = resolved_method->CheckIncompatibleClassChange(type);
89908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers    if (referrer_class != NULL && !icce) {
9002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* methods_class = resolved_method->GetDeclaringClass();
901a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      if (!referrer_class->CanAccess(methods_class) ||
902a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          !referrer_class->CanAccessMember(methods_class,
903996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers                                           resolved_method->GetAccessFlags())) {
904a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // The referring class can't access the resolved method, this may occur as a result of a
905a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        // protected method being made public by implementing an interface that re-declares the
90608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers        // method public. Resort to the dex file to determine the correct class for the access
90708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers        // check.
9084445a7e3398a6143939168097a3aa275b734504dIan Rogers        const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
909a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        methods_class =
91089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers            mUnit->GetClassLinker()->ResolveType(dex_file,
91189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                 dex_file.GetMethodId(method_idx).class_idx_,
91289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers                                                 referrer_class);
913a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      }
914a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      if (referrer_class->CanAccess(methods_class) &&
915137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers          referrer_class->CanAccessMember(methods_class, resolved_method->GetAccessFlags())) {
916a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        vtable_idx = resolved_method->GetMethodIndex();
917f320b639eee1ec0e9d99e8d6c2a805892d016807Ian Rogers        const bool kEnableSharpening = true;
9182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        // Sharpen a virtual call into a direct call when the target is known.
9192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        bool can_sharpen = type == kVirtual && (resolved_method->IsFinal() ||
92008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            methods_class->IsFinal());
92108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers        // Ensure the vtable index will be correct to dispatch in the vtable of the super class.
9224155fcd385bebe869e04c50ff99f4d3d608097bbjeffhao        can_sharpen = can_sharpen || (type == kSuper && referrer_class != methods_class &&
92308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            referrer_class->IsSubClass(methods_class) &&
92408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            vtable_idx < methods_class->GetVTable()->GetLength() &&
92508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers            methods_class->GetVTable()->Get(vtable_idx) == resolved_method);
9262ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        if (kEnableSharpening && can_sharpen) {
9272ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          stats_->ResolvedMethod(type);
928fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          // Sharpen a virtual call into a direct call. The method_idx is into referrer's
929fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          // dex cache, check that this resolved method is where we expect it.
930fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method)
93108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers              << PrettyMethod(resolved_method);
9322ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          stats_->VirtualMadeDirect(type);
9332ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          GetCodeAndMethodForDirectCall(type, kDirect, resolved_method, direct_code, direct_method);
934fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          type = kDirect;
935fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers          return true;
9362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        } else if (type == kSuper) {
93708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers          // Unsharpened super calls are suspicious so go slow-path.
9382ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers        } else {
939c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers          stats_->ResolvedMethod(type);
9402ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers          GetCodeAndMethodForDirectCall(type, type, resolved_method, direct_code, direct_method);
941a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers          return true;
942a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers        }
943a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers      }
944a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    }
945a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  }
946a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  // Clean up any exception left by method/type resolution
94700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (soa.Self()->IsExceptionPending()) {
94800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Self()->ClearException();
949a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  }
950c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  stats_->UnresolvedMethod(type);
951a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  return false;  // Incomplete knowledge needs slow path.
952a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers}
953a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
9541212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddCodePatch(const DexFile* dex_file,
955f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t referrer_method_idx,
95608f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                            InvokeType referrer_invoke_type,
957f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                            uint32_t target_method_idx,
95808f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                            InvokeType target_invoke_type,
9593fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers                            size_t literal_offset) {
96050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_methods_lock_);
96100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  code_to_patch_.push_back(new PatchInformation(dex_file,
962f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                referrer_method_idx,
96308f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                referrer_invoke_type,
964f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                target_method_idx,
96508f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                target_invoke_type,
966f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                literal_offset));
9673fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers}
9681212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddMethodPatch(const DexFile* dex_file,
969f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t referrer_method_idx,
97008f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                              InvokeType referrer_invoke_type,
971f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                              uint32_t target_method_idx,
97208f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                              InvokeType target_invoke_type,
9733fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers                              size_t literal_offset) {
97450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_methods_lock_);
97500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  methods_to_patch_.push_back(new PatchInformation(dex_file,
976f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   referrer_method_idx,
97708f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                   referrer_invoke_type,
978f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   target_method_idx,
97908f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers                                                   target_invoke_type,
980f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                   literal_offset));
9813fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers}
9823fa13791c51985d9956d01bc465de6d36c3390d3Ian Rogers
983219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersclass ParallelCompilationManager {
984731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom public:
985219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  typedef void Callback(const ParallelCompilationManager* manager, size_t index);
9860e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier
987219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ParallelCompilationManager(ClassLinker* class_linker,
988219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                             jobject class_loader,
989219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                             CompilerDriver* compiler,
990219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                             const DexFile* dex_file,
991219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                             ThreadPool& thread_pool)
992731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    : class_linker_(class_linker),
993731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      class_loader_(class_loader),
994731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom      compiler_(compiler),
9950e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      dex_file_(dex_file),
9962f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom      thread_pool_(&thread_pool) {}
997731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom
99800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ClassLinker* GetClassLinker() const {
999731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(class_linker_ != NULL);
1000731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return class_linker_;
1001731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
100200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
100300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jobject GetClassLoader() const {
1004731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return class_loader_;
1005731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
100600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
10071212a022fa5f8ef9585d765b1809521812af882cIan Rogers  CompilerDriver* GetCompiler() const {
1008731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(compiler_ != NULL);
1009731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return compiler_;
1010731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
101100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
101200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const DexFile* GetDexFile() const {
1013731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    CHECK(dex_file_ != NULL);
1014731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom    return dex_file_;
1015731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  }
1016731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom
10170e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
10180e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    Thread* self = Thread::Current();
10190e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    self->AssertNoPendingException();
10200e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    CHECK_GT(work_units, 0U);
10219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
102202b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    std::vector<ForAllClosure*> closures(work_units);
10230e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    for (size_t i = 0; i < work_units; ++i) {
10240e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      closures[i] = new ForAllClosure(this, begin + i, end, callback, work_units);
10250e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      thread_pool_->AddTask(self, closures[i]);
10260e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    }
10270e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    thread_pool_->StartWorkers(self);
102800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
10290e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
10300e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    // thread destructor's called below perform join).
10310e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    CHECK_NE(self->GetState(), kRunnable);
1032d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
10330e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    // Wait for all the worker threads to finish.
10340e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    thread_pool_->Wait(self);
1035d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1036d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1037d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes private:
1038d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
103902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  class ForAllClosure : public Task {
10400e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier   public:
1041219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    ForAllClosure(ParallelCompilationManager* manager, size_t begin, size_t end, Callback* callback,
10420e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier                  size_t stripe)
1043219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers        : manager_(manager),
10440e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          begin_(begin),
10450e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          end_(end),
10460e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          callback_(callback),
10470e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier          stripe_(stripe)
10480e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    {
10491e4092589f1400915e6213014da103aab8728ef6Elliott Hughes
1050aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    }
10519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
10520e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    virtual void Run(Thread* self) {
10530e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      for (size_t i = begin_; i < end_; i += stripe_) {
1054219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers        callback_(manager_, i);
10550e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier        self->AssertNoPendingException();
10560e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier      }
10570e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    }
105802b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
105902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    virtual void Finalize() {
106002b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier      delete this;
106102b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    }
10620e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier   private:
1063219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    const ParallelCompilationManager* const manager_;
10640e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const size_t begin_;
10650e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const size_t end_;
1066219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    const Callback* const callback_;
10670e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier    const size_t stripe_;
10680e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  };
10691e4092589f1400915e6213014da103aab8728ef6Elliott Hughes
10700e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  ClassLinker* const class_linker_;
10710e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  const jobject class_loader_;
10721212a022fa5f8ef9585d765b1809521812af882cIan Rogers  CompilerDriver* const compiler_;
10730e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  const DexFile* const dex_file_;
1074219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ThreadPool* const thread_pool_;
1075d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes};
1076d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
107700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Return true if the class should be skipped during compilation. We
107800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// never skip classes in the boot class loader. However, if we have a
107900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// non-boot class loader and we can resolve the class in the boot
108000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// class loader, we do skip the class. This happens if an app bundles
108100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// classes found in the boot classpath. Since at runtime we will
108200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// select the class from the boot classpath, do not attempt to resolve
108300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// or compile it now.
10842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool SkipClass(mirror::ClassLoader* class_loader,
108500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                      const DexFile& dex_file,
108600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                      const DexFile::ClassDef& class_def)
1087b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
108800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (class_loader == NULL) {
108900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return false;
109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
109100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const char* descriptor = dex_file.GetClassDescriptor(class_def);
109200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
10932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass = class_linker->FindClass(descriptor, NULL);
109400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (klass == NULL) {
109500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread* self = Thread::Current();
109600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    CHECK(self->IsExceptionPending());
109700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    self->ClearException();
109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return false;
109900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
110000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return true;
110100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
110200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1103219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager, size_t class_def_index)
1104b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
110500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
1106219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
1107219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const DexFile& dex_file = *manager->GetDexFile();
1108d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1109845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // Method and Field are the worst. We can't resolve without either
1110845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // context from the code use (to disambiguate virtual vs direct
1111845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // method and instance vs static field) or from class
1112845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // definitions. While the compiler will resolve what it can as it
1113845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // needs it, here we try to resolve fields and methods used in class
1114845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // definitions, since many of them many never be referenced by
1115845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  // generated code.
1116d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
111700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (SkipClass(class_loader, dex_file, class_def)) {
1118d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1119d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1120845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom
1121d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Note the class_data pointer advances through the headers,
1122d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // static fields, instance fields, direct methods, and virtual
1123d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // methods.
1124d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  const byte* class_data = dex_file.GetClassData(class_def);
1125d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (class_data == NULL) {
1126d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // empty class such as a marker interface
1127d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1128d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1129d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  Thread* self = Thread::Current();
1130219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ClassLinker* class_linker = manager->GetClassLinker();
11312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1132d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ClassDataItemIterator it(dex_file, class_data);
1133d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextStaticField()) {
11342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
11352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                      class_loader, true);
1136d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (field == NULL) {
1137d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1138d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
11390571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    }
1140d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1141d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1142fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  // If an instance field is final then we need to have a barrier on the return, static final
1143fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  // fields are assigned within the lock held for class initialization.
1144fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  bool requires_constructor_barrier = false;
1145d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextInstanceField()) {
1146fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    if ((it.GetMemberAccessFlags() & kAccFinal) != 0) {
1147fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers      requires_constructor_barrier = true;
1148fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    }
1149fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
11502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
11512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                      class_loader, false);
1152d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (field == NULL) {
1153d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1154d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
115520cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom    }
1156d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1157d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1158fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  if (requires_constructor_barrier) {
1159219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    manager->GetCompiler()->AddRequiresConstructorBarrier(soa.Self(), manager->GetDexFile(),
1160fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                                          class_def_index);
1161fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  }
1162d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextDirectMethod()) {
11632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
11642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 dex_cache, class_loader, NULL,
11652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 it.GetMethodInvokeType(class_def));
1166d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (method == NULL) {
1167d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1168d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
1169845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom    }
1170d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1171d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1172d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  while (it.HasNextVirtualMethod()) {
11732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
11742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 dex_cache, class_loader, NULL,
11752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                 it.GetMethodInvokeType(class_def));
1176d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    if (method == NULL) {
1177d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      CHECK(self->IsExceptionPending());
1178d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes      self->ClearException();
1179845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom    }
1180d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    it.Next();
1181d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1182d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  DCHECK(!it.HasNext());
1183d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1184d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1185219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
1186b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
1187d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  // Class derived values are more complicated, they require the linker and loader.
118800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
1189219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ClassLinker* class_linker = manager->GetClassLinker();
1190219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const DexFile& dex_file = *manager->GetDexFile();
11912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1192219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
11932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
119400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1195d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass == NULL) {
119600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    CHECK(soa.Self()->IsExceptionPending());
1197d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread::Current()->ClearException();
1198d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1199d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1200d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12011212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
12021212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                    ThreadPool& thread_pool, TimingLogger& timings) {
1203d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1204d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
120500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // TODO: we could resolve strings here, although the string table is largely filled with class
120600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  //       and method names.
1207d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1208219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
12090e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
1210ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes  timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types");
1211d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12120e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
1213ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes  timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields");
12149ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
12159ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
12161212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
12171212a022fa5f8ef9585d765b1809521812af882cIan Rogers                            ThreadPool& thread_pool, TimingLogger& timings) {
1218ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1219ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
122098eacac683b78e60799323e8c7d59e7214808639jeffhao    CHECK(dex_file != NULL);
12212f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    VerifyDexFile(class_loader, *dex_file, thread_pool, timings);
122298eacac683b78e60799323e8c7d59e7214808639jeffhao  }
122398eacac683b78e60799323e8c7d59e7214808639jeffhao}
122498eacac683b78e60799323e8c7d59e7214808639jeffhao
1225219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index)
1226b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
122700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
1228219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index);
1229219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def);
12302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Class* klass =
1231219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers      manager->GetClassLinker()->FindClass(descriptor,
1232219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                                           soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()));
1233d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass == NULL) {
1234d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread* self = Thread::Current();
1235d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(self->IsExceptionPending());
1236d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    self->ClearException();
1237f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao
1238f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    /*
1239f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * At compile time, we can still structurally verify the class even if FindClass fails.
1240f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * This is to ensure the class is structurally sound for compilation. An unsound class
1241f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     * will be rejected by the verifier and later skipped during compilation in the compiler.
1242f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao     */
1243219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    mirror::DexCache* dex_cache =  manager->GetClassLinker()->FindDexCache(*manager->GetDexFile());
1244f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    std::string error_msg;
1245219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    if (verifier::MethodVerifier::VerifyClass(manager->GetDexFile(),
124600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              dex_cache,
1247219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                                              soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()),
124800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              class_def_index, error_msg) ==
124900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                  verifier::MethodVerifier::kHardFailure) {
1250219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers      const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index);
1251f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao      LOG(ERROR) << "Verification failed on class "
1252219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers                 << PrettyDescriptor(manager->GetDexFile()->GetClassDescriptor(class_def))
1253f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao                 << " because: " << error_msg;
1254f56197c5519395fcf8226a7148cc87367e0a7ad4jeffhao    }
1255d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    return;
1256d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1257d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  CHECK(klass->IsResolved()) << PrettyClass(klass);
1258219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  manager->GetClassLinker()->VerifyClass(klass);
1259d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
1260d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  if (klass->IsErroneous()) {
1261d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1262d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    CHECK(Thread::Current()->IsExceptionPending());
1263d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes    Thread::Current()->ClearException();
1264d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  }
1265d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12669ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers  CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
12679ffb039a548996bdc136ae0b2eb42b709d64f1ccIan Rogers      << PrettyDescriptor(klass) << ": state=" << klass->GetStatus();
1268d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes  CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
1269d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes}
1270d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes
12711212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
12721212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                   ThreadPool& thread_pool, TimingLogger& timings) {
1273731b2abfccd8704d129e3b8e46a086660161fef3Brian Carlstrom  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1274219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
12750e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
12763d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  timings.AddSplit("Verify " + dex_file.GetLocation());
1277a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom}
1278a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom
127964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersstatic const char* class_initializer_black_list[] = {
128064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/app/ActivityThread;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/bluetooth/BluetoothAudioGateway;", // Calls android.bluetooth.BluetoothAudioGateway.classInitNative().
128264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/bluetooth/HeadsetBase;", // Calls android.bluetooth.HeadsetBase.classInitNative().
128364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/content/res/CompatibilityInfo;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
128464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/content/res/CompatibilityInfo$1;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
128564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/content/UriMatcher;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/CursorWindow;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
128764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteConnection;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
128864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteConnection$Operation;", // Requires SimpleDateFormat -> java.util.Locale.
128964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteDatabaseConfiguration;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
129064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteDebug;", // Calls android.util.Log.isLoggable.
129164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteOpenHelper;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex.
129264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/database/sqlite/SQLiteQueryBuilder;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
129364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/drm/DrmManagerClient;", // Calls System.loadLibrary.
129464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/AnimatedRotateDrawable;", // Sub-class of Drawable.
129564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/AnimationDrawable;", // Sub-class of Drawable.
129664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/BitmapDrawable;", // Sub-class of Drawable.
129764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ClipDrawable;", // Sub-class of Drawable.
129864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ColorDrawable;", // Sub-class of Drawable.
129964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/Drawable;", // Requires android.graphics.Rect.
130064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/DrawableContainer;", // Sub-class of Drawable.
130164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/GradientDrawable;", // Sub-class of Drawable.
130264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/LayerDrawable;", // Sub-class of Drawable.
130364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/NinePatchDrawable;", // Sub-class of Drawable.
130464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/RotateDrawable;", // Sub-class of Drawable.
130564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ScaleDrawable;", // Sub-class of Drawable.
130664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/ShapeDrawable;", // Sub-class of Drawable.
130764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/StateListDrawable;", // Sub-class of Drawable.
130864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/drawable/TransitionDrawable;", // Sub-class of Drawable.
130964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Matrix;", // Calls android.graphics.Matrix.native_create.
131064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Matrix$1;", // Requires Matrix.
131164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/PixelFormat;", // Calls android.graphics.PixelFormat.nativeClassInit().
131264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Rect;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
131364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/SurfaceTexture;", // Calls android.graphics.SurfaceTexture.nativeClassInit().
131464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/graphics/Typeface;", // Calls android.graphics.Typeface.nativeCreate.
131564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/inputmethodservice/ExtractEditText;", // Requires android.widget.TextView.
131664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/CameraProfile;", // Calls System.loadLibrary.
131764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/DecoderCapabilities;", // Calls System.loadLibrary.
131864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaFile;", // Requires DecoderCapabilities.
131964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaPlayer;", // Calls System.loadLibrary.
132064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaRecorder;", // Calls System.loadLibrary.
132164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/media/MediaScanner;", // Calls System.loadLibrary.
132264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/NetworkInfo;", // Calls java.util.EnumMap.<init> -> java.lang.Enum.getSharedConstants -> System.identityHashCode.
132364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Proxy;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
132464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/SSLCertificateSocketFactory;", // Requires javax.net.ssl.HttpsURLConnection.
132564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex.
132664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$AbstractHierarchicalUri;", // Requires Uri.
132764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$HierarchicalUri;", // Requires Uri.
132864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$OpaqueUri;", // Requires Uri.
132964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/Uri$StringUri;", // Requires Uri.
133064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/net/WebAddress;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
133164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/nfc/NdefRecord;", // Calls String.getBytes -> java.nio.charset.Charset.
133264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES10;", // Calls android.opengl.GLES10._nativeClassInit.
133364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES10Ext;", // Calls android.opengl.GLES10Ext._nativeClassInit.
133464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES11;", // Requires GLES10.
133564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES11Ext;", // Calls android.opengl.GLES11Ext._nativeClassInit.
133664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLES20;", // Calls android.opengl.GLES20._nativeClassInit.
133764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/opengl/GLUtils;", // Calls android.opengl.GLUtils.nativeClassInit.
133864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Build;", // Calls -..-> android.os.SystemProperties.native_get.
133964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Build$VERSION;", // Requires Build.
134064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Debug;", // Requires android.os.Environment.
134164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Environment;", // Calls System.getenv.
134264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/FileUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
134364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/StrictMode;", // Calls android.util.Log.isLoggable.
134464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/StrictMode$VmPolicy;", // Requires StrictMode.
134564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/Trace;", // Calls android.os.Trace.nativeGetEnabledTags.
134664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/os/UEventObserver;", // Calls Class.getSimpleName -> Class.isAnonymousClass -> Class.getDex.
134764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/provider/Settings$Secure;", // Requires android.net.Uri.
134864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/provider/Settings$System;", // Requires android.net.Uri.
134964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/renderscript/RenderScript;", // Calls System.loadLibrary.
135064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/server/BluetoothService;", // Calls android.server.BluetoothService.classInitNative.
135164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/server/BluetoothEventLoop;", // Calls android.server.BluetoothEventLoop.classInitNative.
135264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/telephony/PhoneNumberUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
135364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/AutoText;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int.
135464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/Layout;", // Calls com.android.internal.util.ArrayUtils.emptyArray -> System.identityHashCode.
135564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/BoringLayout;", // Requires Layout.
135664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/DynamicLayout;", // Requires Layout.
135764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/Html$HtmlParser;", // Calls -..-> String.toLowerCase -> java.util.Locale.
135864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/StaticLayout;", // Requires Layout.
135964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/text/TextUtils;", // Requires android.util.DisplayMetrics.
136064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/util/DisplayMetrics;", // Calls SystemProperties.native_get_int.
136164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/util/Patterns;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
136264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/animation/Animation;", // Calls SystemProperties.native_get_boolean.
136364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/animation/AlphaAnimation;", // Requires Animation.
136464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/Choreographer;", // Calls SystemProperties.native_get_boolean.
136564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/GLES20Canvas;", // Calls android.view.GLES20Canvas.nIsAvailable.
136664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/GLES20RecordingCanvas;", // Requires android.view.GLES20Canvas.
136764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/HardwareRenderer$GlRenderer;", // Requires SystemProperties.native_get.
136864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/HardwareRenderer$Gl20Renderer;", // Requires SystemProperties.native_get.
136964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/InputEventConsistencyVerifier;", // Requires android.os.Build.
137064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/view/Surface;", // Requires SystemProperties.native_get.
137164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/webkit/JniUtil;", // Calls System.loadLibrary.
137264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/webkit/WebViewCore;", // Calls System.loadLibrary.
137364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/AutoCompleteTextView;", // Requires TextView.
137464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/Button;", // Requires TextView.
137564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/CheckBox;", // Requires TextView.
137664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/CheckedTextView;", // Requires TextView.
137764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/CompoundButton;", // Requires TextView.
137864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/EditText;", // Requires TextView.
137964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/NumberPicker;", // Requires java.util.Locale.
138064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/ScrollBarDrawable;", // Sub-class of Drawable.
138164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/SearchView$SearchAutoComplete;", // Requires TextView.
138264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/Switch;", // Requires TextView.
138364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Landroid/widget/TextView;", // Calls Paint.<init> -> Paint.native_init.
138464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
138564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/i18n/phonenumbers/PhoneNumberUtil;", // Requires java.util.logging.LogManager.
138664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/os/SamplingProfilerIntegration;", // Calls SystemProperties.native_get_int.
138764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/policy/impl/PhoneWindow;", // Calls android.os.Binder.init.
138864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/view/menu/ActionMenuItemView;", // Requires TextView.
138964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/internal/widget/DialogTitle;", // Requires TextView.
139064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/asn1/StreamUtil;", // Calls Runtime.getRuntime().maxMemory().
139164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
139264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/crypto/engines/RSABlindedEngine;", // Calls native ... -> java.math.NativeBN.BN_new().
139364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/jce/provider/CertBlacklist;", // Calls System.getenv -> OsConstants.initConstants.
139464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi;", // Calls System.getenv -> OsConstants.initConstants.
139564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/google/android/gles_jni/EGLContextImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit.
139664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/google/android/gles_jni/EGLImpl;", // Calls com.google.android.gles_jni.EGLImpl._nativeClassInit.
139764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lcom/google/android/gles_jni/GLImpl;", // Calls com.google.android.gles_jni.GLImpl._nativeClassInit.
139864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/Console;", // Has FileDescriptor(s).
139964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/File;", // Calls to Random.<init> -> System.currentTimeMillis -> OsConstants.initConstants.
140064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/FileDescriptor;", // Requires libcore.io.OsConstants.
140164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/ObjectInputStream;", // Requires java.lang.ClassLoader$SystemClassLoader.
140264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/ObjectStreamClass;",  // Calls to Class.forName -> java.io.FileDescriptor.
140364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/io/ObjectStreamConstants;", // Instance of non-image class SerializablePermission.
140464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/lang/ClassLoader$SystemClassLoader;", // Calls System.getProperty -> OsConstants.initConstants.
140564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/lang/Runtime;", // Calls System.getProperty -> OsConstants.initConstants.
140664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/lang/System;", // Calls OsConstants.initConstants.
140764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/math/BigDecimal;", // Calls native ... -> java.math.NativeBN.BN_new().
140864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/math/BigInteger;", // Calls native ... -> java.math.NativeBN.BN_new().
140964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/math/Multiplication;", // Calls native ... -> java.math.NativeBN.BN_new().
141064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/net/InetAddress;", // Requires libcore.io.OsConstants.
141164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/net/Inet4Address;", // Sub-class of InetAddress.
141264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/net/Inet6Address;", // Sub-class of InetAddress.
141364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/nio/charset/Charset;", // Calls Charset.getDefaultCharset -> System.getProperty -> OsConstants.initConstants.
141464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/nio/charset/CharsetICU;", // Sub-class of Charset.
141564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/nio/charset/Charsets;", // Calls Charset.forName.
141664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/security/Security;", // Tries to do disk IO for "security.properties".
141764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/Date;", // Calls Date.<init> -> System.currentTimeMillis -> OsConstants.initConstants.
141864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/Locale;", // Calls System.getProperty -> OsConstants.initConstants.
141964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/SimpleTimeZone;", // Sub-class of TimeZone.
142064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/TimeZone;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
142164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/concurrent/ConcurrentHashMap$Segment;", // Calls Runtime.getRuntime().availableProcessors().
142264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljava/util/logging/LogManager;", // Calls System.getProperty -> OsConstants.initConstants.
142364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljavax/microedition/khronos/egl/EGL10;", // Requires EGLContext.
142464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljavax/microedition/khronos/egl/EGLContext;", // Requires com.google.android.gles_jni.EGLImpl.
142564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Ljavax/net/ssl/HttpsURLConnection;", // Calls SSLSocketFactory.getDefault -> java.security.Security.getProperty.
142664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/icu/LocaleData;", // Requires java.util.Locale.
142764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/icu/TimeZones;", // Requires java.util.TimeZone.
142864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/io/OsConstants;", // Platform specific.
142964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/net/MimeUtils;", // Calls libcore.net.MimeUtils.getContentTypesPropertiesStream -> System.getProperty.
143064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/util/ZoneInfo;", // Sub-class of TimeZone.
143164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Llibcore/util/ZoneInfoDB;", // Calls System.getenv -> OsConstants.initConstants.
143264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/commons/logging/LogFactory;", // Calls System.getProperty.
143364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/fortress/Services;", // Calls ClassLoader.getSystemClassLoader -> System.getProperty.
143464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/provider/cert/X509CertFactoryImpl;", // Requires java.nio.charsets.Charsets.
143564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/provider/crypto/RandomBitsSupplier;", // Requires java.io.File.
143664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/utils/AlgNameMapper;", // Requires java.util.Locale.
143764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x501/AttributeTypeAndValue;", // Calls IntegralToString.convertInt -> Thread.currentThread.
143864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x501/DirectoryString;", // Requires BigInteger.
143964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x501/Name;", // Requires org.apache.harmony.security.x501.AttributeTypeAndValue.
144064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/Certificate;", // Requires org.apache.harmony.security.x509.TBSCertificate.
144164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/TBSCertificate;",  // Requires org.apache.harmony.security.x501.Name.
144264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/EDIPartyName;", // Calls native ... -> java.math.NativeBN.BN_new().
144364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/GeneralName;", // Requires org.apache.harmony.security.x501.Name.
144464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/GeneralNames;", // Requires GeneralName.
144564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/Time;", // Calls native ... -> java.math.NativeBN.BN_new().
144664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/security/x509/Validity;", // Requires x509.Time.
144764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xml/ExpatParser;", // Calls native ExpatParser.staticInitialize.
144864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto;", // Calls native NativeCrypto.clinit().
144964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$MD5;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
145064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA1;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
145164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK$SHA512;", // Requires org.apache.harmony.xnet.provider.jsse.NativeCrypto.
145264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/harmony/xnet/provider/jsse/TrustedCertificateStore;", // Calls System.getenv -> OsConstants.initConstants.
145364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/http/conn/params/ConnRouteParams;", // Requires java.util.Locale.
145464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/http/conn/ssl/SSLSocketFactory;", // Calls java.security.Security.getProperty.
145564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  "Lorg/apache/http/conn/util/InetAddressUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
145664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers};
145764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers
1458219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersstatic void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
14593d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
1460219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index);
146100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
1462219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
1463219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const char* descriptor = manager->GetDexFile()->GetClassDescriptor(class_def);
1464219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  mirror::Class* klass = manager->GetClassLinker()->FindClass(descriptor, class_loader);
14651f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  Thread* self = Thread::Current();
146664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
146764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  bool can_init_static_fields = compiling_boot &&
1468219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers      manager->GetCompiler()->IsImageClass(descriptor);
14693d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  if (klass != NULL) {
147064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // We don't want class initialization occurring on multiple threads due to deadlock problems.
147164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // For example, a parent class is initialized (holding its lock) that refers to a sub-class
147264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // in its static/class initializer causing it to try to acquire the sub-class' lock. While
147364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // on a second thread the sub-class is initialized (holding its lock) after first initializing
147464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // its parents, whose locks are acquired. This leads to a parent-to-child and a child-to-parent
147564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // lock ordering and consequent potential deadlock.
147664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    static Mutex lock1("Initializer lock", kMonitorLock);
147764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    MutexLock mu(self, lock1);
147864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // The lock required to initialize the class.
147964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    ObjectLock lock2(self, klass);
148064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // Only try to initialize classes that were successfully verified.
14813d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    if (klass->IsVerified()) {
1482219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers      manager->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields);
148364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers      if (!klass->IsInitialized()) {
148464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers        if (can_init_static_fields) {
148564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          bool is_black_listed = false;
148664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
148764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            if (StringPiece(descriptor) == class_initializer_black_list[i]) {
148864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              is_black_listed = true;
148964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              break;
149064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            }
149164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          }
149264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          if (!is_black_listed) {
149364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            LOG(INFO) << "Initializing: " << descriptor;
149464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            if (StringPiece(descriptor) == "Ljava/lang/Void;"){
149564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime.
14962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers              mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields();
149764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers              CHECK_EQ(fields->GetLength(), 1);
1498219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers              fields->Get(0)->SetObj(klass, manager->GetClassLinker()->FindPrimitiveClass('V'));
14992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers              klass->SetStatus(mirror::Class::kStatusInitialized);
150064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            } else {
1501219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers              manager->GetClassLinker()->EnsureInitialized(klass, true, can_init_static_fields);
150264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            }
150364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers            CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
150464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers          }
150564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers        }
150664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers      }
15073d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      // If successfully initialized place in SSB array.
15083d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      if (klass->IsInitialized()) {
15093d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers        klass->GetDexCache()->GetInitializedStaticStorage()->Set(klass->GetDexTypeIndex(), klass);
15100755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom      }
151127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom    }
15123d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    // Record the final class status if necessary.
15132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class::Status status = klass->GetStatus();
1514219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    CompilerDriver::ClassReference ref(manager->GetDexFile(), class_def_index);
1515219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    CompiledClass* compiled_class = manager->GetCompiler()->GetCompiledClass(ref);
15163d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    if (compiled_class == NULL) {
15173d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      compiled_class = new CompiledClass(status);
1518219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers      manager->GetCompiler()->RecordClassStatus(ref, compiled_class);
15193d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    } else {
15203d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers      DCHECK_EQ(status, compiled_class->GetStatus());
1521ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom    }
152298eacac683b78e60799323e8c7d59e7214808639jeffhao  }
15231f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  // Clear any class not found or verification exceptions.
15241f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  self->ClearException();
152598eacac683b78e60799323e8c7d59e7214808639jeffhao}
152698eacac683b78e60799323e8c7d59e7214808639jeffhao
15271212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
15281212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                       ThreadPool& thread_pool, TimingLogger& timings) {
152964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#ifndef NDEBUG
153064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  for (size_t i = 0; i < arraysize(class_initializer_black_list); ++i) {
153164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    const char* descriptor = class_initializer_black_list[i];
153264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    CHECK(IsValidDescriptor(descriptor)) << descriptor;
153364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  }
153464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#endif
15353d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1536219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, thread_pool);
153764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count_);
15383d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  timings.AddSplit("InitializeNoClinit " + dex_file.GetLocation());
15393d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers}
154090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
15411212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InitializeClasses(jobject class_loader,
15421212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                       const std::vector<const DexFile*>& dex_files,
15431212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                       ThreadPool& thread_pool, TimingLogger& timings) {
15443d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  for (size_t i = 0; i != dex_files.size(); ++i) {
15453d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers    const DexFile* dex_file = dex_files[i];
154690dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao    CHECK(dex_file != NULL);
15472f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    InitializeClasses(class_loader, *dex_file, thread_pool, timings);
154800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
154990dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao}
155090dc30f4b9967e850d0594e57dfa8e7cb0369575Shih-wei Liao
15511212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
15522f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom                       ThreadPool& thread_pool, TimingLogger& timings) {
1553ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  for (size_t i = 0; i != dex_files.size(); ++i) {
1554ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    const DexFile* dex_file = dex_files[i];
155583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom    CHECK(dex_file != NULL);
15562f66382fdb5e98537f724eba43ef1c7162c71b0eBrian Carlstrom    CompileDexFile(class_loader, *dex_file, thread_pool, timings);
155783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom  }
155883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom}
155983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom
1560219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogersvoid CompilerDriver::CompileClass(const ParallelCompilationManager* manager, size_t class_def_index) {
1561219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  jobject class_loader = manager->GetClassLoader();
1562219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  const DexFile& dex_file = *manager->GetDexFile();
1563c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
156400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  {
156500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(Thread::Current());
1566219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader());
156700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (SkipClass(class_loader, dex_file, class_def)) {
156800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return;
156900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
15705ead0950c661761e90e04aefd6ea2205532ce874Brian Carlstrom  }
1571d1224c79631bd1801b067a0f212b91afa961a362jeffhao  ClassReference ref(&dex_file, class_def_index);
1572d1224c79631bd1801b067a0f212b91afa961a362jeffhao  // Skip compiling classes with generic verifier failures since they will still fail at runtime
1573776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (verifier::MethodVerifier::IsClassRejected(ref)) {
1574d1224c79631bd1801b067a0f212b91afa961a362jeffhao    return;
1575d1224c79631bd1801b067a0f212b91afa961a362jeffhao  }
15760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  const byte* class_data = dex_file.GetClassData(class_def);
15770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (class_data == NULL) {
15780571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    // empty class, probably a marker interface
15790571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    return;
15800571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
15810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  ClassDataItemIterator it(dex_file, class_data);
15820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Skip fields
15830571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextStaticField()) {
15840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
15850571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
15860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextInstanceField()) {
15870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
15880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
15890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Compile direct methods
159068adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom  int64_t previous_direct_method_idx = -1;
15910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextDirectMethod()) {
15926f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    uint32_t method_idx = it.GetMemberIndex();
15936f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    if (method_idx == previous_direct_method_idx) {
15946f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // smali can create dex files with two encoded_methods sharing the same method_idx
15956f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // http://code.google.com/p/smali/issues/detail?id=119
15966f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      it.Next();
15976f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      continue;
15986f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    }
15996f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    previous_direct_method_idx = method_idx;
1600219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1601fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          it.GetMethodInvokeType(class_def), class_def_index,
1602fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          method_idx, class_loader, dex_file);
16030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
16049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
16050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Compile virtual methods
160668adbe41c7d9295da2bfc521d737ba6dabd36c98Brian Carlstrom  int64_t previous_virtual_method_idx = -1;
16070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  while (it.HasNextVirtualMethod()) {
16086f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    uint32_t method_idx = it.GetMemberIndex();
16096f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    if (method_idx == previous_virtual_method_idx) {
16106f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // smali can create dex files with two encoded_methods sharing the same method_idx
16116f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      // http://code.google.com/p/smali/issues/detail?id=119
16126f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      it.Next();
16136f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom      continue;
16146f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    }
16156f29d0e6d5444ff84157c922c23c221567dcc6c5Brian Carlstrom    previous_virtual_method_idx = method_idx;
1616219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers    manager->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1617fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          it.GetMethodInvokeType(class_def), class_def_index,
1618fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          method_idx, class_loader, dex_file);
16190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
16209ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
16210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  DCHECK(!it.HasNext());
16229ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
16239ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
16241212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
16251212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                    ThreadPool& thread_pool, TimingLogger& timings) {
1626219b5a847ef74be5d3de4c16a29ec6413cc42af1Ian Rogers  ParallelCompilationManager context(NULL, class_loader, this, &dex_file, thread_pool);
16271212a022fa5f8ef9585d765b1809521812af882cIan Rogers  context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
16283d1548debdaf8a1915fa432a4d267f7c0145654dIan Rogers  timings.AddSplit("Compile " + dex_file.GetLocation());
1629c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes}
1630c225caa9715eeaeff87f27d5b6a3e7d4f6b7efadElliott Hughes
1631a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesstatic std::string MakeInvokeStubKey(bool is_static, const char* shorty) {
1632a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  std::string key(shorty);
1633a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  if (is_static) {
1634a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    key += "$";  // Must not be a shorty type character.
1635a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
1636a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return key;
1637a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
1638a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
16391212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
16401212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                   InvokeType invoke_type, uint32_t class_def_idx,
16411212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                   uint32_t method_idx, jobject class_loader,
16421212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                   const DexFile& dex_file) {
1643f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  CompiledMethod* compiled_method = NULL;
1644bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns = NanoTime();
16454dd96f56909ec35c83a3d468b0e47769988c1a1dLogan Chien
1646169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  if ((access_flags & kAccNative) != 0) {
164757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    compiled_method = (*jni_compiler_)(*this, access_flags, method_idx, dex_file);
16483320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    CHECK(compiled_method != NULL);
1649169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  } else if ((access_flags & kAccAbstract) != 0) {
16502cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom  } else {
1651fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers    compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx,
1652fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                   method_idx, class_loader, dex_file);
1653bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes    CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
1654bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
16553bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers  uint64_t duration_ns = NanoTime() - start_ns;
1656c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers#ifdef ART_USE_PORTABLE_COMPILER
16575354ec568ace1e117d5a93dcb802a612356200edIan Rogers  const uint64_t kWarnMilliSeconds = 1000;
16585354ec568ace1e117d5a93dcb802a612356200edIan Rogers#else
16595354ec568ace1e117d5a93dcb802a612356200edIan Rogers  const uint64_t kWarnMilliSeconds = 100;
16605354ec568ace1e117d5a93dcb802a612356200edIan Rogers#endif
16615354ec568ace1e117d5a93dcb802a612356200edIan Rogers  if (duration_ns > MsToNs(kWarnMilliSeconds)) {
1662bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes    LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
16633bb17a644e2945c3913cfbde245d2f520d62a3ffIan Rogers                 << " took " << PrettyDuration(duration_ns);
1664f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  }
1665f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes
166650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
1667f09afe8fbd78943df6a8b10f03c36dcd190dd054Elliott Hughes  if (compiled_method != NULL) {
16680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    MethodReference ref(&dex_file, method_idx);
16690755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file);
167000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    {
167150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers      MutexLock mu(self, compiled_methods_lock_);
167200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      compiled_methods_.Put(ref, compiled_method);
167300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
16740755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file);
16752cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom  }
16769baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom
167745619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers  uint32_t shorty_len;
167845619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers  const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len);
1679169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers  bool is_static = (access_flags & kAccStatic) != 0;
1680a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  std::string key(MakeInvokeStubKey(is_static, shorty));
1681265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key);
16820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (compiled_invoke_stub == NULL) {
1683c4c9881e5d22432f3f1a30eeec5aa109dfc08a7dShih-wei Liao    compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len);
16840571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    CHECK(compiled_invoke_stub != NULL);
1685a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    InsertInvokeStub(key, compiled_invoke_stub);
16863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
16877a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
1688c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers  if ((compiler_backend_ == kPortable) && !is_static) {
1689265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty);
16907a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    if (compiled_proxy_stub == NULL) {
16917a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len);
16927a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      CHECK(compiled_proxy_stub != NULL);
16937a2a23a44d27f769718e28327af671f4e486c49aLogan Chien      InsertProxyStub(shorty, compiled_proxy_stub);
16947a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    }
16957a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
16967a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
169750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  if (self->IsExceptionPending()) {
169850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    ScopedObjectAccess soa(self);
169900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
170050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers        << self->GetException()->Dump();
170100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
17020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
170328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers
1704265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub* CompilerDriver::FindInvokeStub(bool is_static, const char* shorty) const {
1705a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const std::string key(MakeInvokeStubKey(is_static, shorty));
1706a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return FindInvokeStub(key);
17073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
17083320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1709265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub* CompilerDriver::FindInvokeStub(const std::string& key) const {
171050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
17110571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
17120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (it == compiled_invoke_stubs_.end()) {
17133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    return NULL;
17140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  } else {
17150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    DCHECK(it->second != NULL);
17160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    return it->second;
17173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  }
17183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
17193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1720265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompilerDriver::InsertInvokeStub(const std::string& key, CompiledInvokeStub* compiled_invoke_stub) {
172150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
1722a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key);
1723a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  if (it != compiled_invoke_stubs_.end()) {
1724a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    // Someone else won the race.
1725a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    delete compiled_invoke_stub;
1726a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  } else {
1727a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    compiled_invoke_stubs_.Put(key, compiled_invoke_stub);
1728a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
17290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
17300571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
1731265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub* CompilerDriver::FindProxyStub(const char* shorty) const {
173250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
17337a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty);
17347a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  if (it == compiled_proxy_stubs_.end()) {
17357a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    return NULL;
17367a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  } else {
17377a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    DCHECK(it->second != NULL);
17387a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    return it->second;
17397a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
17407a2a23a44d27f769718e28327af671f4e486c49aLogan Chien}
17417a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
1742265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompilerDriver::InsertProxyStub(const char* shorty, CompiledInvokeStub* compiled_proxy_stub) {
174350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
17447a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty);
17457a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  if (it != compiled_proxy_stubs_.end()) {
17467a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    // Someone else won the race.
17477a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    delete compiled_proxy_stub;
17487a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  } else {
17497a2a23a44d27f769718e28327af671f4e486c49aLogan Chien    compiled_proxy_stubs_.Put(shorty, compiled_proxy_stub);
17507a2a23a44d27f769718e28327af671f4e486c49aLogan Chien  }
17517a2a23a44d27f769718e28327af671f4e486c49aLogan Chien}
17527a2a23a44d27f769718e28327af671f4e486c49aLogan Chien
17531212a022fa5f8ef9585d765b1809521812af882cIan RogersCompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const {
175450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_classes_lock_);
17550755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  ClassTable::const_iterator it = compiled_classes_.find(ref);
17560755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  if (it == compiled_classes_.end()) {
17570755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    return NULL;
17580755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  }
17590755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  CHECK(it->second != NULL);
17600755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom  return it->second;
17610755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom}
17620755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom
17631212a022fa5f8ef9585d765b1809521812af882cIan RogersCompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const {
176450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), compiled_methods_lock_);
17650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  MethodTable::const_iterator it = compiled_methods_.find(ref);
17660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  if (it == compiled_methods_.end()) {
17673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom    return NULL;
17682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
17693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  CHECK(it->second != NULL);
17703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  return it->second;
17719ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}
17729ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
17731212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::SetBitcodeFileName(std::string const& filename) {
17741212a022fa5f8ef9585d765b1809521812af882cIan Rogers  typedef void (*SetBitcodeFileNameFn)(CompilerDriver&, std::string const&);
1775106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
1776106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  SetBitcodeFileNameFn set_bitcode_file_name =
17778c4bbb55d0d801e492d849ee636771c8b2840429buzbee    FindFunction<SetBitcodeFileNameFn>(MakeCompilerSoName(compiler_backend_), compiler_library_,
1778106b2a03be66748a25b9019e4c222cee498d559fLogan Chien                                       "compilerLLVMSetBitcodeFileName");
1779106b2a03be66748a25b9019e4c222cee498d559fLogan Chien
1780106b2a03be66748a25b9019e4c222cee498d559fLogan Chien  set_bitcode_file_name(*this, filename);
17818b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien}
1782f7015fd55a8dc969ac2440ffc829a6b4d942fb5aLogan Chien
1783fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
17841212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
1785fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                             size_t class_def_index) {
1786fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  MutexLock mu(self, freezing_constructor_lock_);
1787fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
1788fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers}
1789fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
17901212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
1791fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers                                          size_t class_def_index) {
1792fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  MutexLock mu(self, freezing_constructor_lock_);
1793fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers  return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
1794fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers}
1795fffdb023275613612a22ec62b3421ffe4d2b73feIan Rogers
1796265091e581c9f643b37e7966890911f09e223269Brian Carlstrombool CompilerDriver::WriteElf(const std::string* host_prefix,
1797265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                              bool is_host,
1798265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                              const std::vector<const DexFile*>& dex_files,
1799265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                              std::vector<uint8_t>& oat_contents,
1800265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                              File* file) {
1801265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  typedef bool (*WriteElfFn)(CompilerDriver&,
1802265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                             const std::string* host_prefix,
1803265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                             bool is_host,
1804265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                             const std::vector<const DexFile*>& dex_files,
1805265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                             std::vector<uint8_t>&,
1806265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                             File*);
1807700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  WriteElfFn WriteElf =
1808700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf");
1809265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
1810265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return WriteElf(*this, host_prefix, is_host, dex_files, oat_contents, file);
1811700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
1812700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
18131212a022fa5f8ef9585d765b1809521812af882cIan Rogersbool CompilerDriver::FixupElf(File* file, uintptr_t oat_data_begin) const {
1814700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  typedef bool (*FixupElfFn)(File*, uintptr_t oat_data_begin);
1815700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  FixupElfFn FixupElf =
1816700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    FindFunction<FixupElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "FixupElf");
1817700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  return FixupElf(file, oat_data_begin);
1818700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
1819700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
18201212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::GetOatElfInformation(File* file,
18211212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                          size_t& oat_loaded_size,
18221212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                          size_t& oat_data_offset) const {
1823700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  typedef bool (*GetOatElfInformationFn)(File*, size_t& oat_loaded_size, size_t& oat_data_offset);
1824700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  GetOatElfInformationFn GetOatElfInformation =
1825700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    FindFunction<GetOatElfInformationFn>(MakeCompilerSoName(compiler_backend_), compiler_library_,
1826700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                                         "GetOatElfInformation");
1827700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  GetOatElfInformation(file, oat_loaded_size, oat_data_offset);
1828700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
1829700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1830265091e581c9f643b37e7966890911f09e223269Brian Carlstrombool CompilerDriver::StripElf(File* file) const {
1831265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  typedef bool (*StripElfFn)(File*);
1832265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  StripElfFn StripElf =
1833265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    FindFunction<StripElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "StripElf");
1834265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return StripElf(file);
1835265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
1836265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
18371212a022fa5f8ef9585d765b1809521812af882cIan Rogersvoid CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set,
18381212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                std::string& target_triple,
18391212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                std::string& target_cpu,
18401212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                std::string& target_attr) {
1841265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  switch (instruction_set) {
1842700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kThumb2:
1843700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "thumb-none-linux-gnueabi";
1844700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_cpu = "cortex-a9";
1845700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db";
1846700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1847700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1848700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kArm:
1849700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "armv7-none-linux-gnueabi";
1850700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // TODO: Fix for Nexus S.
1851700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_cpu = "cortex-a9";
1852700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // TODO: Fix for Xoom.
1853700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "+v7,+neon,+neonfp,+vfp3,+db";
1854700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1855700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1856700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kX86:
1857700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "i386-pc-linux-gnu";
1858700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "";
1859700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1860700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1861700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    case kMips:
1862700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_triple = "mipsel-unknown-linux";
1863700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      target_attr = "mips32r2";
1864700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      break;
1865700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
1866700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    default:
1867700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(FATAL) << "Unknown instruction set: " << instruction_set;
1868700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
1869700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  }
18709ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom}  // namespace art
1871