class_linker.h revision 95caa791e560da97363c0c0d22bfda4a7e7377c3
1418d20fc407052d4152157f61e7453359f902383Elliott Hughes/*
2418d20fc407052d4152157f61e7453359f902383Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
3418d20fc407052d4152157f61e7453359f902383Elliott Hughes *
4418d20fc407052d4152157f61e7453359f902383Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5418d20fc407052d4152157f61e7453359f902383Elliott Hughes * you may not use this file except in compliance with the License.
6418d20fc407052d4152157f61e7453359f902383Elliott Hughes * You may obtain a copy of the License at
7418d20fc407052d4152157f61e7453359f902383Elliott Hughes *
8418d20fc407052d4152157f61e7453359f902383Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9418d20fc407052d4152157f61e7453359f902383Elliott Hughes *
10418d20fc407052d4152157f61e7453359f902383Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11418d20fc407052d4152157f61e7453359f902383Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12418d20fc407052d4152157f61e7453359f902383Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13418d20fc407052d4152157f61e7453359f902383Elliott Hughes * See the License for the specific language governing permissions and
14418d20fc407052d4152157f61e7453359f902383Elliott Hughes * limitations under the License.
15418d20fc407052d4152157f61e7453359f902383Elliott Hughes */
160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_CLASS_LINKER_H_
180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_CLASS_LINKER_H_
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <map>
210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <utility>
220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <vector>
230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
24caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers#include "dex_cache.h"
257e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "dex_file.h"
264a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom#include "heap.h"
27578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
288daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "mutex.h"
2958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom#include "oat_file.h"
30578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "object.h"
317e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "unordered_map.h"
32a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom#include "unordered_set.h"
337e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
34578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "gtest/gtest.h"
350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
38cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughesclass ClassLoader;
39cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughesclass InternTable;
40d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstromclass ObjectLock;
41cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes
420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass ClassLinker {
430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
4458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Creates the class linker by boot strapping from dex files.
4558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  static ClassLinker* Create(const std::string& boot_class_path, InternTable* intern_table);
4658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom
4758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Creates the class linker from one or more images.
4858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  static ClassLinker* Create(InternTable* intern_table);
499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  ~ClassLinker();
51565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
5264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes  // Finds a class by its descriptor, loading it if necessary.
5374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  // If class_loader is null, searches boot_class_path_.
54aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  Class* FindClass(const std::string& descriptor, const ClassLoader* class_loader);
55aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
56aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  Class* FindSystemClass(const std::string& descriptor) {
57aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    return FindClass(descriptor, NULL);
58aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
59aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
60aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // Define a new a class based on a ClassDef from a DexFile
61aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  Class* DefineClass(const std::string& descriptor, const ClassLoader* class_loader,
62aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom                     const DexFile& dex_file, const DexFile::ClassDef& dex_class_def);
6364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes
6464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes  // Finds a class by its descriptor, returning NULL if it isn't wasn't loaded
6564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes  // by the given 'class_loader'.
66aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  Class* LookupClass(const std::string& descriptor, const ClassLoader* class_loader);
670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
68d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes  Class* FindPrimitiveClass(char type);
69d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  void DumpAllClasses(int flags) const;
719d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
72e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes  size_t NumLoadedClasses() const;
73e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
74b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a String with the given index from the DexFile, storing the
75aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // result in the DexCache. The referrer is used to identify the
76aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // target DexCache and ClassLoader to use for resolution.
77aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  String* ResolveString(uint32_t string_idx, const Method* referrer) {
78caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    String* resolved_string = referrer->GetDexCacheStrings()->Get(string_idx);
79caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_string == NULL)) {
80caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
81caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
82caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
83caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_string = ResolveString(dex_file, string_idx, dex_cache);
84caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
85caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_string;
86aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
87aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
88aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // Resolve a String with the given index from the DexFile, storing the
899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache.
900cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  String* ResolveString(const DexFile& dex_file, uint32_t string_idx, DexCache* dex_cache);
919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
92b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
939ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache. The referrer is used to identity the
949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     uint32_t type_idx,
979ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const Class* referrer) {
989ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    return ResolveType(dex_file,
999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       type_idx,
1009ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetDexCache(),
1019ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetClassLoader());
1029ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
1039ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
104b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
1050cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // result in the DexCache. The referrer is used to identify the
106b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
107b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  Class* ResolveType(uint32_t type_idx, const Method* referrer) {
108caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Class* resolved_type = referrer->GetDexCacheResolvedTypes()->Get(type_idx);
109caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_type == NULL)) {
110caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
111caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
112caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
113caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
114caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
115caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
116caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_type;
1170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
1180cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
1190cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Class* ResolveType(uint32_t type_idx, const Field* referrer) {
1200cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Class* declaring_class = referrer->GetDeclaringClass();
1210cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DexCache* dex_cache = declaring_class->GetDexCache();
122caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Class* resolved_type = dex_cache->GetResolvedType(type_idx);
123caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_type == NULL)) {
124caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
125caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
126caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
127caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
128caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_type;
129b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  }
130b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom
1319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a type with the given ID from the DexFile, storing the
1329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLoader is used to search for the
1339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // type, since it may be referenced from but not contained within
1349ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // the given DexFile.
1359ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
1369ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     uint32_t type_idx,
1379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     DexCache* dex_cache,
1389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const ClassLoader* class_loader);
1399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
1409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a method with a given ID from the DexFile, storing the
1419ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
1429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the method type argument which
1439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // is used to determine if this method is a direct, static, or
1449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // virtual method.
1459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Method* ResolveMethod(const DexFile& dex_file,
1469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        uint32_t method_idx,
1479ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        DexCache* dex_cache,
1489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        const ClassLoader* class_loader,
14920cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom                        bool is_direct);
1509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
151161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  Method* ResolveMethod(uint32_t method_idx, const Method* referrer, bool is_direct) {
152caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Method* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(method_idx);
153caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_method == NULL)) {
154caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
155caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
156caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
157caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
158caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, is_direct);
159caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
160caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_method;
161161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  }
162161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
163845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  Field* ResolveField(uint32_t field_idx, const Method* referrer, bool is_static) {
164caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Field* resolved_field = referrer->GetDexCacheResolvedFields()->Get(field_idx);
165caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_field == NULL)) {
166caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
167caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
168caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
169caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
170caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static);
171caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
172caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_field;
173b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  }
174b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom
175161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  // Resolve a field with a given ID from the DexFile, storing the
1769ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
1779ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the is_static argument which is
1789ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // used to determine if we are resolving a static or non-static
1799ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // field.
1809ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Field* ResolveField(const DexFile& dex_file,
1819ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      uint32_t field_idx,
1829ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      DexCache* dex_cache,
1839ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      const ClassLoader* class_loader,
1849ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      bool is_static);
1859ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
186ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  // Get shorty from method index without resolution. Used to do handlerization.
187ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  const char* MethodShorty(uint32_t method_idx, Method* referrer);
188ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
189f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  // Returns true on success, false if there's an exception pending.
19025c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  // can_run_clinit=false allows the compiler to attempt to init a class,
19125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  // given the restriction that no <clinit> execution is possible.
19225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  bool EnsureInitialized(Class* c, bool can_run_clinit);
1930e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1942a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes  // Initializes classes that have instances in the image but that have
1952a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes  // <clinit> methods so they could not be initialized by the compiler.
1962a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes  void RunRootClinits();
1972a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes
1989ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file);
1999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache);
2000e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2018a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  const std::vector<const DexFile*>& GetBootClassPath() {
2028a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom    return boot_class_path_;
2038a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  }
2048a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom
205410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
20675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
207c143c55718342519db5398e41dda31422cf16c79buzbee  const DexFile& FindDexFile(const DexCache* dex_cache) const;
2089ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* FindDexCache(const DexFile& dex_file) const;
209aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  bool IsDexFileRegistered(const DexFile& dex_file) const;
2101d9f52b7ca91c6d30b7acfac1c9ab24d93fff470Brian Carlstrom
2111d9f52b7ca91c6d30b7acfac1c9ab24d93fff470Brian Carlstrom  // Find, possibily opening, an OatFile corresponding to a DexFile
2121d9f52b7ca91c6d30b7acfac1c9ab24d93fff470Brian Carlstrom  const OatFile* FindOatFile(const DexFile& dex_file);
213aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  const OatFile* FindOatFile(const std::string& location);
214c143c55718342519db5398e41dda31422cf16c79buzbee
215418d20fc407052d4152157f61e7453359f902383Elliott Hughes  // TODO: replace this with multiple methods that allocate the correct managed type.
2164417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  template <class T>
2174417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  ObjectArray<T>* AllocObjectArray(size_t length) {
2184417536522fd2a9d8215d8672331984769c9520bShih-wei Liao    return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
2194417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  }
2204417536522fd2a9d8215d8672331984769c9520bShih-wei Liao
221418d20fc407052d4152157f61e7453359f902383Elliott Hughes  ObjectArray<Class>* AllocClassArray(size_t length) {
222418d20fc407052d4152157f61e7453359f902383Elliott Hughes    return ObjectArray<Class>::Alloc(GetClassRoot(kClassArrayClass), length);
223418d20fc407052d4152157f61e7453359f902383Elliott Hughes  }
224418d20fc407052d4152157f61e7453359f902383Elliott Hughes
22555df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao  ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length);
22655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
22798eacac683b78e60799323e8c7d59e7214808639jeffhao  void VerifyClass(Class* klass);
22898eacac683b78e60799323e8c7d59e7214808639jeffhao
22995caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson  Class* CreateProxyClass(String* name, ObjectArray<Class>* interfaces, ClassLoader* loader,
23095caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson      ObjectArray<Method>* methods, ObjectArray<Object>* throws);
23195caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson
2320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
233cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes  ClassLinker(InternTable*);
23461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
23558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Initialize class linker by bootstraping from dex files
23658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  void Init(const std::string& boot_class_path);
23761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
23858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Initialize class linker from one or more images.
23958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  void InitFromImage();
24058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  OatFile* OpenOat(const Space* space);
24178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  static void InitFromImageCallback(Object* obj, void* arg);
242c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom  struct InitFromImageCallbackState;
243a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
244a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void FinishInit();
245a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
24675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // For early bootstrapping by Init
2474873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(Class* java_lang_Class, size_t class_size);
24875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
24975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // Alloc* convenience functions to avoid needing to pass in Class*
25075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // values that are known to the ClassLinker such as
25175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // kObjectArrayClass and kJavaLangString etc.
2524873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(size_t class_size);
2539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* AllocDexCache(const DexFile& dex_file);
25435baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson  Field* AllocField();
255bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
25675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Method* AllocMethod();
257bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
2589cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom  CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
2594b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom  InterfaceEntry* AllocInterfaceEntry(Class* interface);
26075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
2610cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Class* CreatePrimitiveClass(const char* descriptor,
2625b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom                              Class::PrimitiveType type) {
2635b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom    return InitializePrimitiveClass(AllocClass(sizeof(Class)), descriptor, type);
2645b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom  }
2655b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom  Class* InitializePrimitiveClass(Class* primitive_class,
2665b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom                                  const char* descriptor,
2675b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom                                  Class::PrimitiveType type);
2685b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom
269a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom
270aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  Class* CreateArrayClass(const std::string& descriptor,
2719ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                          const ClassLoader* class_loader);
272578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2739ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file);
2749ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache);
275578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2765fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
2775fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes      Class* c, std::map<int, Field*>& field_map);
2785fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
2794873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  size_t SizeOfClass(const DexFile& dex_file,
2804873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                     const DexFile::ClassDef& dex_class_def);
2814873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
282f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadClass(const DexFile& dex_file,
283f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::ClassDef& dex_class_def,
28474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                 Class* klass,
2859ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                 const ClassLoader* class_loader);
286565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
287f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadInterfaces(const DexFile& dex_file,
288f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                      const DexFile::ClassDef& dex_class_def,
289578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                      Class *klass);
290934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
291f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadField(const DexFile& dex_file,
292f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::Field& dex_field,
293578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Class* klass,
294578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Field* dst);
295934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
296f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadMethod(const DexFile& dex_file,
297f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                  const DexFile::Method& dex_method,
298578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                  Class* klass,
2991f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom                  Method* dst);
300934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
3010e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Inserts a class into the class table.  Returns true if the class
3020e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // was inserted.
303aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  bool InsertClass(const std::string& descriptor, Class* klass);
304aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
305aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  void RegisterDexFileLocked(const DexFile& dex_file, DexCache* dex_cache);
306aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  bool IsDexFileRegisteredLocked(const DexFile& dex_file) const;
307aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
308d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstrom  bool InitializeClass(Class* klass, bool can_run_clinit);
309d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstrom  bool WaitForInitializeClass(Class* klass, Thread* self, ObjectLock& lock);
310d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstrom  bool ValidateSuperClassDescriptors(const Class* klass);
31125c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  bool InitializeSuperClass(Class* klass, bool can_run_clinit);
3120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void InitializeStaticFields(Class* klass);
3130e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3140e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameDescriptorClasses(const char* descriptor,
3150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass1,
3160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass2);
3170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameMethodDescriptorClasses(const Method* descriptor,
3190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass1,
3200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass2);
3210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3220cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  bool LinkClass(Class* klass);
3230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkSuperClass(Class* klass);
3250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
32674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file);
3270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkMethods(Class* klass);
3290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkVirtualMethods(Class* klass);
3310e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInterfaceMethods(Class* klass);
3330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3347833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson  bool LinkStaticFields(Class* klass);
3350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInstanceFields(Class* klass);
3363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  bool LinkFields(Class *klass, bool is_static);
3370cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3384873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
3394873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceInstanceOffsets(Class* klass);
3404873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceStaticOffsets(Class* klass);
3413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  void CreateReferenceOffsets(Class *klass, bool is_static,
3420cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers                              uint32_t reference_offsets);
3430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
34458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // For use by ImageWriter to find DexCaches for its roots
34558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  const std::vector<DexCache*>& GetDexCaches() {
34658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    return dex_caches_;
34758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  }
34858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom
34995caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson  Method* CreateProxyConstructor(Class* klass);
35095caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson  Method* CreateProxyMethod(Class* klass, Method* prototype, Object* throws);
35195caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson
352161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  // lock to protect ClassLinker state
353161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  mutable Mutex lock_;
354161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
35558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  std::vector<const OatFile*> oat_files_;
35658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom
3574a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
358578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
3594a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> dex_files_;
3607e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  std::vector<DexCache*> dex_caches_;
3610e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
362aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // multimap from a string hash code of a class descriptor to
3639cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class* instances. Results should be compared for a matching
3649cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class::descriptor_ and Class::class_loader_.
3659cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  typedef std::tr1::unordered_multimap<size_t, Class*> Table;
3660e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Table classes_;
3670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
368a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // indexes into class_roots_.
369a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // needs to be kept in sync with class_roots_descriptors_.
37074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  enum ClassRoot {
37175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangClass,
37275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangObject,
373418d20fc407052d4152157f61e7453359f902383Elliott Hughes    kClassArrayClass,
37474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kObjectArrayClass,
37574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangString,
376bf61ba3dcd9d9895b86a05e88762ff034b09b263Elliott Hughes    kJavaLangRefReference,
3778060925c45cc2607ab92390d7366c6c0cfdfe4bbElliott Hughes    kJavaLangReflectConstructor,
37875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectField,
37975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectMethod,
38074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangClassLoader,
38174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemBaseDexClassLoader,
38274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemPathClassLoader,
38355df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElement,
38475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveBoolean,
385d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveByte,
38675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveChar,
38775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveDouble,
388d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveFloat,
38975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveInt,
39075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveLong,
391d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveShort,
39275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveVoid,
393d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kBooleanArrayClass,
394d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kByteArrayClass,
395d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kCharArrayClass,
396d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kDoubleArrayClass,
397d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kFloatArrayClass,
398d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kIntArrayClass,
399d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kLongArrayClass,
400d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kShortArrayClass,
40155df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElementArrayClass,
40275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kClassRootsMax,
40375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  };
40475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  ObjectArray<Class>* class_roots_;
405913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom
40674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  Class* GetClassRoot(ClassRoot class_root) {
407a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
40874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    Class* klass = class_roots_->Get(class_root);
40974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    DCHECK(klass != NULL);
41074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return klass;
41174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  }
41274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom
413a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void SetClassRoot(ClassRoot class_root, Class* klass) {
414a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(!init_done_);
415a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
416a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(klass != NULL);
4170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(klass->GetClassLoader() == NULL);
4180cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(klass->GetDescriptor() != NULL);
4190cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(klass->GetDescriptor()->Equals(GetClassRootDescriptor(class_root)));
420a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
421a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
422a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_->Get(class_root) == NULL);
423a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    class_roots_->Set(class_root, klass);
424a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
425a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
42634f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom  ObjectArray<Class>* GetClassRoots() {
42734f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom    DCHECK(class_roots_ != NULL);
42834f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom    return class_roots_;
42934f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom  }
43034f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom
431418d20fc407052d4152157f61e7453359f902383Elliott Hughes  static const char* class_roots_descriptors_[];
432a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
433a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  const char* GetClassRootDescriptor(ClassRoot class_root) {
434a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    const char* descriptor = class_roots_descriptors_[class_root];
435a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    CHECK(descriptor != NULL);
436a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    return descriptor;
437a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
438a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
4394a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  ObjectArray<Class>* array_interfaces_;
4404b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom  ObjectArray<InterfaceEntry>* array_iftable_;
441565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
44275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  bool init_done_;
44375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
444cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes  InternTable* intern_table_;
445cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes
446f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom  friend class CommonTest;
44775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(DexCacheTest, Open);
44875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  friend class ObjectTest;
44975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(ObjectTest, AllocObjectArray);
4501a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  FRIEND_TEST(ExceptionTest, FindExceptionHandler);
45134f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom  friend class ImageWriter;  // for GetClassRoots
4520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(ClassLinker);
4530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
4540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
4560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_CLASS_LINKER_H_
458