class_linker.h revision 5fe594f576225dd7d333835e39c448a71ea9b433
10e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved.
20e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
30e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_CLASS_LINKER_H_
40e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_CLASS_LINKER_H_
50e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
60e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <map>
70e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <utility>
80e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <vector>
90e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
107e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "dex_file.h"
114a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom#include "heap.h"
12578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
13578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "object.h"
147e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "thread.h"
157e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "unordered_map.h"
16a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom#include "unordered_set.h"
177e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
18578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "gtest/gtest.h"
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
22cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughesclass ClassLoader;
23cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughesclass InternTable;
24cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes
250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass ClassLinker {
260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
27a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // Initializes the class linker using DexFile and an optional boot Space.
28cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes  static ClassLinker* Create(const std::vector<const DexFile*>& boot_class_path,
2969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom                             const std::vector<const DexFile*>& class_path,
3069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom                             InternTable* intern_table, Space* boot_space);
319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  ~ClassLinker();
33565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Finds a class by its descriptor name.
3574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  // If class_loader is null, searches boot_class_path_.
366cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom  Class* FindClass(const StringPiece& descriptor,
379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                   const ClassLoader* class_loader);
380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
39d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes  Class* FindPrimitiveClass(char type);
40d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
416cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom  Class* FindSystemClass(const StringPiece& descriptor) {
4274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return FindClass(descriptor, NULL);
43565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro  }
44565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
45e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes  size_t NumLoadedClasses() const;
46e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
47b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a String with the given index from the DexFile, storing the
489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache.
490cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  String* ResolveString(const DexFile& dex_file, uint32_t string_idx, DexCache* dex_cache);
509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
51b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
529ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache. The referrer is used to identity the
539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
559ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     uint32_t type_idx,
569ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const Class* referrer) {
579ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    return ResolveType(dex_file,
589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       type_idx,
599ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetDexCache(),
609ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetClassLoader());
619ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
629ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
63b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
640cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // result in the DexCache. The referrer is used to identify the
65b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
66b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  Class* ResolveType(uint32_t type_idx, const Method* referrer) {
67b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    Class* declaring_class = referrer->GetDeclaringClass();
68b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    DexCache* dex_cache = declaring_class->GetDexCache();
690cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: we could check for a dex cache hit here
700cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    const ClassLoader* class_loader = declaring_class->GetClassLoader();
710cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    const DexFile& dex_file = FindDexFile(dex_cache);
720cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    return ResolveType(dex_file, type_idx, dex_cache, class_loader);
730cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
740cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
750cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Class* ResolveType(uint32_t type_idx, const Field* referrer) {
760cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    Class* declaring_class = referrer->GetDeclaringClass();
770cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DexCache* dex_cache = declaring_class->GetDexCache();
780cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: we could check for a dex cache hit here
79b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    const ClassLoader* class_loader = declaring_class->GetClassLoader();
80b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    const DexFile& dex_file = FindDexFile(dex_cache);
81b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    return ResolveType(dex_file, type_idx, dex_cache, class_loader);
82b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  }
83b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom
849ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a type with the given ID from the DexFile, storing the
859ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLoader is used to search for the
869ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // type, since it may be referenced from but not contained within
879ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // the given DexFile.
889ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     uint32_t type_idx,
909ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     DexCache* dex_cache,
919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const ClassLoader* class_loader);
929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
93b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  static StaticStorageBase* InitializeStaticStorageFromCode(uint32_t type_idx,
94b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom                                                            const Method* referrer);
951caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom
969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a method with a given ID from the DexFile, storing the
979ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
989ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the method type argument which
999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // is used to determine if this method is a direct, static, or
1009ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // virtual method.
1019ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Method* ResolveMethod(const DexFile& dex_file,
1029ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        uint32_t method_idx,
1039ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        DexCache* dex_cache,
1049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        const ClassLoader* class_loader,
10520cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom                        bool is_direct);
1069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
107b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  Field* ResolveField(uint32_t field_idx, const Method* referrer) {
108b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    Class* declaring_class = referrer->GetDeclaringClass();
109b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    DexCache* dex_cache = declaring_class->GetDexCache();
1100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: we could check for a dex cache hit here
111b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    const ClassLoader* class_loader = declaring_class->GetClassLoader();
112b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    const DexFile& dex_file = FindDexFile(dex_cache);
113b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    return ResolveField(dex_file, field_idx, dex_cache, class_loader, true);
114b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  }
115b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom
1169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a method with a given ID from the DexFile, storing the
1179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
1189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the is_static argument which is
1199ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // used to determine if we are resolving a static or non-static
1209ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // field.
1219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Field* ResolveField(const DexFile& dex_file,
1229ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      uint32_t field_idx,
1239ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      DexCache* dex_cache,
1249ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      const ClassLoader* class_loader,
1259ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      bool is_static);
1269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
127f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  // Returns true on success, false if there's an exception pending.
128f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  bool EnsureInitialized(Class* c);
1290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file);
1319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache);
1320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1338a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  const std::vector<const DexFile*>& GetBootClassPath() {
1348a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom    return boot_class_path_;
1358a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom  }
1368a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom
137410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
13875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
139c143c55718342519db5398e41dda31422cf16c79buzbee  const DexFile& FindDexFile(const DexCache* dex_cache) const;
1409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* FindDexCache(const DexFile& dex_file) const;
141c143c55718342519db5398e41dda31422cf16c79buzbee
1424417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  template <class T>
1434417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  ObjectArray<T>* AllocObjectArray(size_t length) {
1444417536522fd2a9d8215d8672331984769c9520bShih-wei Liao    return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
1454417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  }
1464417536522fd2a9d8215d8672331984769c9520bShih-wei Liao
14755df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao  ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length);
14855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
1490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
150cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes  ClassLinker(InternTable*);
15161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
152a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // Initialize class linker from DexFile instances.
15369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  void Init(const std::vector<const DexFile*>& boot_class_path_,
15469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom            const std::vector<const DexFile*>& class_path_);
15561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
156a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // Initialize class linker from pre-initialized space.
15769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  void Init(const std::vector<const DexFile*>& boot_class_path_,
15869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom            const std::vector<const DexFile*>& class_path_,
15969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom            Space* space);
1604873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  static void InitCallback(Object* obj, void *arg);
161a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  struct InitCallbackState;
162a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
163a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void FinishInit();
164a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
165f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  bool InitializeClass(Class* klass);
166f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes
16775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // For early bootstrapping by Init
1684873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(Class* java_lang_Class, size_t class_size);
16975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
17075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // Alloc* convenience functions to avoid needing to pass in Class*
17175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // values that are known to the ClassLinker such as
17275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // kObjectArrayClass and kJavaLangString etc.
1734873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(size_t class_size);
1749ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* AllocDexCache(const DexFile& dex_file);
17535baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson  Field* AllocField();
17675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Method* AllocMethod();
1779cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom  CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
17875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
1790cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Class* CreatePrimitiveClass(const char* descriptor,
1800cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers                              Class::PrimitiveType type);
181a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom
182578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  Class* CreateArrayClass(const StringPiece& descriptor,
1839ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                          const ClassLoader* class_loader);
184578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
1859ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file);
1869ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache);
187578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
1885fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
1895fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes      Class* c, std::map<int, Field*>& field_map);
1905fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
1914873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  size_t SizeOfClass(const DexFile& dex_file,
1924873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                     const DexFile::ClassDef& dex_class_def);
1934873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
194f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadClass(const DexFile& dex_file,
195f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::ClassDef& dex_class_def,
19674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                 Class* klass,
1979ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                 const ClassLoader* class_loader);
198565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
199f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadInterfaces(const DexFile& dex_file,
200f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                      const DexFile::ClassDef& dex_class_def,
201578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                      Class *klass);
202934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
203f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadField(const DexFile& dex_file,
204f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::Field& dex_field,
205578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Class* klass,
206578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Field* dst);
207934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
208f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadMethod(const DexFile& dex_file,
209f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                  const DexFile::Method& dex_method,
210578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                  Class* klass,
2111f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom                  Method* dst);
212934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
2139ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader);
2147e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
2150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Inserts a class into the class table.  Returns true if the class
2160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // was inserted.
2179cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  bool InsertClass(const StringPiece& descriptor, Class* klass);
2180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool InitializeSuperClass(Class* klass);
2200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void InitializeStaticFields(Class* klass);
2220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool ValidateSuperClassDescriptors(const Class* klass);
2240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameDescriptorClasses(const char* descriptor,
2260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass1,
2270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass2);
2280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameMethodDescriptorClasses(const Method* descriptor,
2300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass1,
2310e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass2);
2320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2330cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  bool LinkClass(Class* klass);
2340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkSuperClass(Class* klass);
2360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
23774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file);
2380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkMethods(Class* klass);
2400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkVirtualMethods(Class* klass);
2420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInterfaceMethods(Class* klass);
2440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void LinkAbstractMethods(Class* klass);
2460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2477833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson  bool LinkStaticFields(Class* klass);
2480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInstanceFields(Class* klass);
2490cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  bool LinkFields(Class *klass, bool instance);
2500cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2514873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
2524873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceInstanceOffsets(Class* klass);
2534873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceStaticOffsets(Class* klass);
2540cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void CreateReferenceOffsets(Class *klass, bool instance,
2550cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers                              uint32_t reference_offsets);
2560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2574a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
258578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2594a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> dex_files_;
260578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2617e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  std::vector<DexCache*> dex_caches_;
2620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2639cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // multimap from a StringPiece hash code of a class descriptor to
2649cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class* instances. Results should be compared for a matching
2659cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class::descriptor_ and Class::class_loader_.
2669cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  typedef std::tr1::unordered_multimap<size_t, Class*> Table;
2670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Table classes_;
2680e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Mutex* classes_lock_;
2690e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
270a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // indexes into class_roots_.
271a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // needs to be kept in sync with class_roots_descriptors_.
27274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  enum ClassRoot {
27375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangClass,
27475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangObject,
27574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kObjectArrayClass,
27674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangString,
27775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectField,
27875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectMethod,
27974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangClassLoader,
28074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemBaseDexClassLoader,
28174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemPathClassLoader,
28255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElement,
28375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveBoolean,
284d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveByte,
28575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveChar,
28675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveDouble,
287d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveFloat,
28875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveInt,
28975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveLong,
290d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveShort,
29175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveVoid,
292d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kBooleanArrayClass,
293d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kByteArrayClass,
294d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kCharArrayClass,
295d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kDoubleArrayClass,
296d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kFloatArrayClass,
297d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kIntArrayClass,
298d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kLongArrayClass,
299d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kShortArrayClass,
30055df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElementArrayClass,
30175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kClassRootsMax,
30275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  };
30375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  ObjectArray<Class>* class_roots_;
304913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom
30574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  Class* GetClassRoot(ClassRoot class_root) {
306a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
30774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    Class* klass = class_roots_->Get(class_root);
30874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    DCHECK(klass != NULL);
30974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return klass;
31074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  }
31174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom
312a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void SetClassRoot(ClassRoot class_root, Class* klass) {
313a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(!init_done_);
314a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
315a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(klass != NULL);
3160cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(klass->GetClassLoader() == NULL);
3170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(klass->GetDescriptor() != NULL);
3180cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(klass->GetDescriptor()->Equals(GetClassRootDescriptor(class_root)));
319a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
320a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
321a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_->Get(class_root) == NULL);
322a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    class_roots_->Set(class_root, klass);
323a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
324a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
325a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  static const char* class_roots_descriptors_[kClassRootsMax];
326a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
327a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  const char* GetClassRootDescriptor(ClassRoot class_root) {
328a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    const char* descriptor = class_roots_descriptors_[class_root];
329a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    CHECK(descriptor != NULL);
330a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    return descriptor;
331a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
332a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
3334a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  ObjectArray<Class>* array_interfaces_;
334913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom  InterfaceEntry* array_iftable_;
335565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
33675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  bool init_done_;
33775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
338cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes  InternTable* intern_table_;
339cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes
340f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom  friend class CommonTest;
34175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(DexCacheTest, Open);
34275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  friend class ObjectTest;
34375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(ObjectTest, AllocObjectArray);
3441a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  FRIEND_TEST(ExceptionTest, FindExceptionHandler);
3450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(ClassLinker);
3460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
3470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
3490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_CLASS_LINKER_H_
351