class_linker.h revision d601af8d9549ca95a911afb2fc67c4e562da661f
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>
216d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include <string>
220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <utility>
230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <vector>
240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
25caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers#include "dex_cache.h"
267e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "dex_file.h"
274a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom#include "heap.h"
28578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
298daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "mutex.h"
3058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom#include "oat_file.h"
31578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "object.h"
3240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom#include "stack_indirect_reference_table.h"
337e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "unordered_map.h"
34a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom#include "unordered_set.h"
357e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
36578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "gtest/gtest.h"
370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
40cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughesclass ClassLoader;
41cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughesclass InternTable;
42d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstromclass ObjectLock;
43cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes
44a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughestypedef bool (ClassVisitor)(Class* c, void* arg);
45a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes
460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass ClassLinker {
470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
4858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Creates the class linker by boot strapping from dex files.
494dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  static ClassLinker* Create(const std::string& boot_class_path, InternTable* intern_table);
5058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom
5158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Creates the class linker from one or more images.
524dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  static ClassLinker* Create(InternTable* intern_table);
539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  ~ClassLinker();
55565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
5664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes  // Finds a class by its descriptor, loading it if necessary.
5774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  // If class_loader is null, searches boot_class_path_.
58c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  Class* FindClass(const char* descriptor, const ClassLoader* class_loader);
59aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
60db7d5e96d3e4090e69fac7b4ec1fc1bdcc0b436cElliott Hughes  Class* FindSystemClass(const char* descriptor);
61aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
62aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // Define a new a class based on a ClassDef from a DexFile
63c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  Class* DefineClass(const StringPiece& descriptor, const ClassLoader* class_loader,
64aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom                     const DexFile& dex_file, const DexFile::ClassDef& dex_class_def);
6564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes
6664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes  // Finds a class by its descriptor, returning NULL if it isn't wasn't loaded
6764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes  // by the given 'class_loader'.
68c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  Class* LookupClass(const char* descriptor, const ClassLoader* class_loader);
690e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
706fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes  // Finds all the classes with the given descriptor, regardless of ClassLoader.
71c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  void LookupClasses(const char* descriptor, std::vector<Class*>& classes);
726fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes
73d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes  Class* FindPrimitiveClass(char type);
74d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
75ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // General class unloading is not supported, this is used to prune
76ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // unwanted classes during image writing.
77c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  bool RemoveClass(const char* descriptor, const ClassLoader* class_loader);
78ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
799d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  void DumpAllClasses(int flags) const;
809d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
81cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  void DumpForSigQuit(std::ostream& os) const;
82cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
83e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes  size_t NumLoadedClasses() const;
84e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
85b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a String with the given index from the DexFile, storing the
86aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // result in the DexCache. The referrer is used to identify the
87aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // target DexCache and ClassLoader to use for resolution.
88aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  String* ResolveString(uint32_t string_idx, const Method* referrer) {
89caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    String* resolved_string = referrer->GetDexCacheStrings()->Get(string_idx);
90caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_string == NULL)) {
91caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
92caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
93caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
94caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_string = ResolveString(dex_file, string_idx, dex_cache);
95caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
96caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_string;
97aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
98aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
99aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // Resolve a String with the given index from the DexFile, storing the
1009ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache.
1010cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  String* ResolveString(const DexFile& dex_file, uint32_t string_idx, DexCache* dex_cache);
1029ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
103b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
1049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache. The referrer is used to identity the
1059ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
1069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
1076d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers                     uint16_t type_idx,
1089ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const Class* referrer) {
1099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    return ResolveType(dex_file,
1109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       type_idx,
1119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetDexCache(),
1129ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetClassLoader());
1139ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
1149ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
115b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
1160cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // result in the DexCache. The referrer is used to identify the
117b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
1186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  Class* ResolveType(uint16_t type_idx, const Method* referrer) {
119caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Class* resolved_type = referrer->GetDexCacheResolvedTypes()->Get(type_idx);
120caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_type == NULL)) {
121caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
122caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
123caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
124caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
125caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
126caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
127caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_type;
1280cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
1290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
1306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  Class* ResolveType(uint16_t type_idx, const Field* referrer) {
1310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Class* declaring_class = referrer->GetDeclaringClass();
1320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DexCache* dex_cache = declaring_class->GetDexCache();
133caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Class* resolved_type = dex_cache->GetResolvedType(type_idx);
134caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_type == NULL)) {
135caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
136caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
137caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
138caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
139caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_type;
140b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  }
141b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom
1429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a type with the given ID from the DexFile, storing the
1439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLoader is used to search for the
1449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // type, since it may be referenced from but not contained within
1459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // the given DexFile.
1469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
1476d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers                     uint16_t type_idx,
1489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     DexCache* dex_cache,
1499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const ClassLoader* class_loader);
1509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
1519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a method with a given ID from the DexFile, storing the
1529ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
1539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the method type argument which
1549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // is used to determine if this method is a direct, static, or
1559ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // virtual method.
1569ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Method* ResolveMethod(const DexFile& dex_file,
1579ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        uint32_t method_idx,
1589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        DexCache* dex_cache,
1599ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        const ClassLoader* class_loader,
16020cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom                        bool is_direct);
1619ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
162161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  Method* ResolveMethod(uint32_t method_idx, const Method* referrer, bool is_direct) {
163caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Method* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(method_idx);
164caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_method == NULL)) {
165caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
166caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
167caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
168caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
169caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, is_direct);
170caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
171caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_method;
172161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  }
173161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
174845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  Field* ResolveField(uint32_t field_idx, const Method* referrer, bool is_static) {
175caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    Field* resolved_field = referrer->GetDexCacheResolvedFields()->Get(field_idx);
176caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    if (UNLIKELY(resolved_field == NULL)) {
177caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      Class* declaring_class = referrer->GetDeclaringClass();
178caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
179caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
180caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
181caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers      resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static);
182caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    }
183caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers    return resolved_field;
184b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  }
185b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom
186161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  // Resolve a field with a given ID from the DexFile, storing the
1879ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
1889ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the is_static argument which is
1899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // used to determine if we are resolving a static or non-static
1909ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // field.
1919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Field* ResolveField(const DexFile& dex_file,
1929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      uint32_t field_idx,
1939ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      DexCache* dex_cache,
1949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      const ClassLoader* class_loader,
1959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      bool is_static);
1969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
197b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  Field* ResolveFieldJLS(uint32_t field_idx, const Method* referrer) {
198b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers    Field* resolved_field = referrer->GetDexCacheResolvedFields()->Get(field_idx);
199b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers    if (UNLIKELY(resolved_field == NULL)) {
200b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers      Class* declaring_class = referrer->GetDeclaringClass();
201b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers      DexCache* dex_cache = declaring_class->GetDexCache();
202b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers      const ClassLoader* class_loader = declaring_class->GetClassLoader();
203b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers      const DexFile& dex_file = FindDexFile(dex_cache);
204b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers      resolved_field = ResolveFieldJLS(dex_file, field_idx, dex_cache, class_loader);
205b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers    }
206b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers    return resolved_field;
207b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  }
208b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers
209b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  // Resolve a field with a given ID from the DexFile, storing the
210b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  // result in DexCache. The ClassLinker and ClassLoader are used as
211b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  // in ResolveType. No is_static argument is provided so that Java
212b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  // field resolution semantics are followed.
213b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers  Field* ResolveFieldJLS(const DexFile& dex_file,
214b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers                         uint32_t field_idx,
215b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers                         DexCache* dex_cache,
216b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers                         const ClassLoader* class_loader);
217b067ac2fe225c76fc9eb9434ef62cbb797bfa425Ian Rogers
218ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  // Get shorty from method index without resolution. Used to do handlerization.
219ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  const char* MethodShorty(uint32_t method_idx, Method* referrer);
220ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
221f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  // Returns true on success, false if there's an exception pending.
22225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  // can_run_clinit=false allows the compiler to attempt to init a class,
22325c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  // given the restriction that no <clinit> execution is possible.
22425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  bool EnsureInitialized(Class* c, bool can_run_clinit);
2250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2262a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes  // Initializes classes that have instances in the image but that have
2272a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes  // <clinit> methods so they could not be initialized by the compiler.
2282a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes  void RunRootClinits();
2292a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes
2309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file);
23140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file, SirtRef<DexCache>& dex_cache);
2320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2338a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  const std::vector<const DexFile*>& GetBootClassPath() {
2348a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom    return boot_class_path_;
2358a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  }
2368a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom
237a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  void VisitClasses(ClassVisitor* visitor, void* arg) const;
238a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes
239410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
24075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
241c143c55718342519db5398e41dda31422cf16c79buzbee  const DexFile& FindDexFile(const DexCache* dex_cache) const;
2429ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* FindDexCache(const DexFile& dex_file) const;
243aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  bool IsDexFileRegistered(const DexFile& dex_file) const;
2441d9f52b7ca91c6d30b7acfac1c9ab24d93fff470Brian Carlstrom
245262bf46ddc91e5b4fbd367127ff21a1877d939f2jeffhao  // Generate an oat file from a dex file
246d601af8d9549ca95a911afb2fc67c4e562da661fBrian Carlstrom  bool GenerateOatFile(const std::string& dex_filename,
247d601af8d9549ca95a911afb2fc67c4e562da661fBrian Carlstrom                       int oat_fd,
248d601af8d9549ca95a911afb2fc67c4e562da661fBrian Carlstrom                       const std::string& oat_cache_filename);
249262bf46ddc91e5b4fbd367127ff21a1877d939f2jeffhao
2501d9f52b7ca91c6d30b7acfac1c9ab24d93fff470Brian Carlstrom  // Find, possibily opening, an OatFile corresponding to a DexFile
251ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  const OatFile* FindOatFileForDexFile(const DexFile& dex_file);
252ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  const OatFile* FindOatFileFromOatLocation(const std::string& location);
253c143c55718342519db5398e41dda31422cf16c79buzbee
254418d20fc407052d4152157f61e7453359f902383Elliott Hughes  // TODO: replace this with multiple methods that allocate the correct managed type.
2554417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  template <class T>
2564417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  ObjectArray<T>* AllocObjectArray(size_t length) {
2574417536522fd2a9d8215d8672331984769c9520bShih-wei Liao    return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
2584417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  }
2594417536522fd2a9d8215d8672331984769c9520bShih-wei Liao
260418d20fc407052d4152157f61e7453359f902383Elliott Hughes  ObjectArray<Class>* AllocClassArray(size_t length) {
261418d20fc407052d4152157f61e7453359f902383Elliott Hughes    return ObjectArray<Class>::Alloc(GetClassRoot(kClassArrayClass), length);
262418d20fc407052d4152157f61e7453359f902383Elliott Hughes  }
263418d20fc407052d4152157f61e7453359f902383Elliott Hughes
26455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao  ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length);
26555df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
26698eacac683b78e60799323e8c7d59e7214808639jeffhao  void VerifyClass(Class* klass);
26798eacac683b78e60799323e8c7d59e7214808639jeffhao
26895caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson  Class* CreateProxyClass(String* name, ObjectArray<Class>* interfaces, ClassLoader* loader,
2696d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers                          ObjectArray<Method>* methods, ObjectArray<ObjectArray<Class> >* throws);
2706d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  std::string GetDescriptorForProxy(const Class* proxy_class);
27195caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson
27247d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  pid_t GetClassesLockOwner(); // For SignalCatcher.
27347d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  pid_t GetDexLockOwner(); // For SignalCatcher.
27424a3c2e9924e8765c4a9b4d383cb8f3b922f9c9fBrian Carlstrom
2750e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
2764dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  explicit ClassLinker(InternTable*);
27761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
27858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Initialize class linker by bootstraping from dex files
27958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  void Init(const std::string& boot_class_path);
28061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
28158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // Initialize class linker from one or more images.
28258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  void InitFromImage();
28358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  OatFile* OpenOat(const Space* space);
28478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  static void InitFromImageCallback(Object* obj, void* arg);
285c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom  struct InitFromImageCallbackState;
286a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
287a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void FinishInit();
288a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
28975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // For early bootstrapping by Init
2904873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(Class* java_lang_Class, size_t class_size);
29175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
29275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // Alloc* convenience functions to avoid needing to pass in Class*
29375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // values that are known to the ClassLinker such as
29475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // kObjectArrayClass and kJavaLangString etc.
2954873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(size_t class_size);
2969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* AllocDexCache(const DexFile& dex_file);
29735baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson  Field* AllocField();
298bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
29975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Method* AllocMethod();
300bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
3019cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom  CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
3024b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom  InterfaceEntry* AllocInterfaceEntry(Class* interface);
30375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
3046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom  Class* CreatePrimitiveClass(const char* descriptor, Primitive::Type type) {
3055b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom    return InitializePrimitiveClass(AllocClass(sizeof(Class)), descriptor, type);
3065b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom  }
3075b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom  Class* InitializePrimitiveClass(Class* primitive_class,
3085b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom                                  const char* descriptor,
3096b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom                                  Primitive::Type type);
3105b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom
311a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom
312c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  Class* CreateArrayClass(const std::string& descriptor, const ClassLoader* class_loader);
313578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
3149ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file);
31540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file, SirtRef<DexCache>& dex_cache);
316578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
3175fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
3180571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                         Class* c, std::map<uint32_t, Field*>& field_map);
3195fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
3204873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  size_t SizeOfClass(const DexFile& dex_file,
3214873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                     const DexFile::ClassDef& dex_class_def);
3224873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
323f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadClass(const DexFile& dex_file,
324f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::ClassDef& dex_class_def,
32540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom                 SirtRef<Class>& klass,
3269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                 const ClassLoader* class_loader);
327565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
3280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it, SirtRef<Class>& klass,
32940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom                 SirtRef<Field>& dst);
330934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
3310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  void LoadMethod(const DexFile& dex_file, const ClassDataItemIterator& dex_method,
3320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers                  SirtRef<Class>& klass, SirtRef<Method>& dst);
333934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
3340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Inserts a class into the class table.  Returns true if the class
3350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // was inserted.
336c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes  bool InsertClass(const StringPiece& descriptor, Class* klass, bool image_class);
337aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
33840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<DexCache>& dex_cache);
339aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  bool IsDexFileRegisteredLocked(const DexFile& dex_file) const;
340aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
341d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstrom  bool InitializeClass(Class* klass, bool can_run_clinit);
342d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstrom  bool WaitForInitializeClass(Class* klass, Thread* self, ObjectLock& lock);
343d1422f81bf9b35cb2aad3fb5615d3f5209014709Brian Carlstrom  bool ValidateSuperClassDescriptors(const Class* klass);
34425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom  bool InitializeSuperClass(Class* klass, bool can_run_clinit);
3450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void InitializeStaticFields(Class* klass);
3460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameDescriptorClasses(const char* descriptor,
3480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass1,
3490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass2);
3500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameMethodDescriptorClasses(const Method* descriptor,
3520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass1,
3530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass2);
3540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
355c2b4447ae9c0c1e77595620acac6508999df6698Ian Rogers  bool LinkClass(SirtRef<Class>& klass, ObjectArray<Class>* interfaces);
3560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
35740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  bool LinkSuperClass(SirtRef<Class>& klass);
3580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
35940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  bool LoadSuperAndInterfaces(SirtRef<Class>& klass, const DexFile& dex_file);
3600e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3616d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  bool LinkMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfaces);
3620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
36340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  bool LinkVirtualMethods(SirtRef<Class>& klass);
3640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3656d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  bool LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfaces);
3660e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
36740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  bool LinkStaticFields(SirtRef<Class>& klass);
36840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  bool LinkInstanceFields(SirtRef<Class>& klass);
36940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  bool LinkFields(SirtRef<Class>& klass, bool is_static);
3700cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3714873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
37240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CreateReferenceInstanceOffsets(SirtRef<Class>& klass);
37340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CreateReferenceStaticOffsets(SirtRef<Class>& klass);
37440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void CreateReferenceOffsets(SirtRef<Class>& klass, bool is_static,
3750cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers                              uint32_t reference_offsets);
3760e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
37758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  // For use by ImageWriter to find DexCaches for its roots
37858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  const std::vector<DexCache*>& GetDexCaches() {
37958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    return dex_caches_;
38058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  }
38158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom
382ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  const OatFile* FindOpenedOatFileForDexFile(const DexFile& dex_file);
383ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location);
384fad714344ca81a21e775ef45ae09d9a035723cafBrian Carlstrom
3856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  Method* CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class);
3866d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  Method* CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& prototype);
38795caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson
3884a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
389578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
3904a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> dex_files_;
3917e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  std::vector<DexCache*> dex_caches_;
39247d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  std::vector<const OatFile*> oat_files_;
39347d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  // lock to protect concurrent access to dex_files_, dex_caches_, and oat_files_
39447d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  mutable Mutex dex_lock_;
39547d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom
3960e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
397aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  // multimap from a string hash code of a class descriptor to
3989cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class* instances. Results should be compared for a matching
3999cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class::descriptor_ and Class::class_loader_.
40047d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  // Protected by classes_lock_
4019cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  typedef std::tr1::unordered_multimap<size_t, Class*> Table;
4025d76c435082332ef79a22962386fa92a0870e378Ian Rogers  Table image_classes_;
4030e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Table classes_;
40447d237a4b1a41772005c60083e72fe75c0aa0743Brian Carlstrom  mutable Mutex classes_lock_;
4050e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
406a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // indexes into class_roots_.
407a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // needs to be kept in sync with class_roots_descriptors_.
40874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  enum ClassRoot {
40975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangClass,
41075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangObject,
411418d20fc407052d4152157f61e7453359f902383Elliott Hughes    kClassArrayClass,
41274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kObjectArrayClass,
41374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangString,
414bf61ba3dcd9d9895b86a05e88762ff034b09b263Elliott Hughes    kJavaLangRefReference,
4158060925c45cc2607ab92390d7366c6c0cfdfe4bbElliott Hughes    kJavaLangReflectConstructor,
41675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectField,
41775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectMethod,
418466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers    kJavaLangReflectProxy,
41974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangClassLoader,
42074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemBaseDexClassLoader,
42174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemPathClassLoader,
42255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElement,
42375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveBoolean,
424d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveByte,
42575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveChar,
42675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveDouble,
427d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveFloat,
42875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveInt,
42975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveLong,
430d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveShort,
43175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveVoid,
432d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kBooleanArrayClass,
433d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kByteArrayClass,
434d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kCharArrayClass,
435d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kDoubleArrayClass,
436d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kFloatArrayClass,
437d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kIntArrayClass,
438d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kLongArrayClass,
439d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kShortArrayClass,
44055df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElementArrayClass,
44175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kClassRootsMax,
44275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  };
44375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  ObjectArray<Class>* class_roots_;
444913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom
44574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  Class* GetClassRoot(ClassRoot class_root) {
446a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
44774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    Class* klass = class_roots_->Get(class_root);
44874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    DCHECK(klass != NULL);
44974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return klass;
45074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  }
45174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom
4526d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  void SetClassRoot(ClassRoot class_root, Class* klass);
453a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
45434f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom  ObjectArray<Class>* GetClassRoots() {
45534f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom    DCHECK(class_roots_ != NULL);
45634f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom    return class_roots_;
45734f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom  }
45834f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom
459418d20fc407052d4152157f61e7453359f902383Elliott Hughes  static const char* class_roots_descriptors_[];
460a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
461a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  const char* GetClassRootDescriptor(ClassRoot class_root) {
462a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    const char* descriptor = class_roots_descriptors_[class_root];
463a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    CHECK(descriptor != NULL);
464a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    return descriptor;
465a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
466a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
4674b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom  ObjectArray<InterfaceEntry>* array_iftable_;
468565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
46975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  bool init_done_;
47075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
471cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes  InternTable* intern_table_;
472cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes
473f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom  friend class CommonTest;
474ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  friend class ImageWriter;  // for GetClassRoots
47575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  friend class ObjectTest;
4766d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  FRIEND_TEST(ClassLinkerTest, ClassRootDescriptors);
477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  FRIEND_TEST(DexCacheTest, Open);
4781a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  FRIEND_TEST(ExceptionTest, FindExceptionHandler);
479ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  FRIEND_TEST(ObjectTest, AllocObjectArray);
4800e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(ClassLinker);
4810e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
4820e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4830e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
4840e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4850e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_CLASS_LINKER_H_
486