class_linker.h revision 4417536522fd2a9d8215d8672331984769c9520b
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"
127e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "intern_table.h"
13578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
14578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "object.h"
157e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "thread.h"
167e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom#include "unordered_map.h"
17a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom#include "unordered_set.h"
187e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
19578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "gtest/gtest.h"
200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass ClassLinker {
240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
25a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // Initializes the class linker using DexFile and an optional boot Space.
269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  static ClassLinker* Create(const std::vector<const DexFile*>& boot_class_path, Space* boot_space);
279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
289ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  ~ClassLinker();
29565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Finds a class by its descriptor name.
3174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  // If class_loader is null, searches boot_class_path_.
326cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom  Class* FindClass(const StringPiece& descriptor,
339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                   const ClassLoader* class_loader);
340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
35d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes  Class* FindPrimitiveClass(char type);
36d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
376cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom  Class* FindSystemClass(const StringPiece& descriptor) {
3874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return FindClass(descriptor, NULL);
39565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro  }
40565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
41e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes  size_t NumLoadedClasses() const;
42e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
43b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a String with the given index from the DexFile, storing the
449ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache.
459ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  String* ResolveString(const DexFile& dex_file,
469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        uint32_t string_idx,
479ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        DexCache* dex_cache);
489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
49b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in the DexCache. The referrer is used to identity the
519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
529ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     uint32_t type_idx,
549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const Class* referrer) {
559ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom    return ResolveType(dex_file,
569ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       type_idx,
579ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetDexCache(),
589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                       referrer->GetClassLoader());
599ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  }
609ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
61b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // Resolve a Type with the given index from the DexFile, storing the
62b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // result in the DexCache. The referrer is used to identity the
63b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  // target DexCache and ClassLoader to use for resolution.
64b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  Class* ResolveType(uint32_t type_idx, const Method* referrer) {
65b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    Class* declaring_class = referrer->GetDeclaringClass();
66b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    DexCache* dex_cache = declaring_class->GetDexCache();
67b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    const ClassLoader* class_loader = declaring_class->GetClassLoader();
68b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    const DexFile& dex_file = FindDexFile(dex_cache);
69b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom    return ResolveType(dex_file, type_idx, dex_cache, class_loader);
70b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom  }
71b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom
729ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a type with the given ID from the DexFile, storing the
739ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLoader is used to search for the
749ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // type, since it may be referenced from but not contained within
759ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // the given DexFile.
769ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* ResolveType(const DexFile& dex_file,
779ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     uint32_t type_idx,
789ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     DexCache* dex_cache,
799ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                     const ClassLoader* class_loader);
809ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
81b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  static StaticStorageBase* InitializeStaticStorageFromCode(uint32_t type_idx,
82b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom                                                            const Method* referrer);
831caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom
849ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a method with a given ID from the DexFile, storing the
859ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
869ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the method type argument which
879ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // is used to determine if this method is a direct, static, or
889ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // virtual method.
899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Method* ResolveMethod(const DexFile& dex_file,
909ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        uint32_t method_idx,
919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        DexCache* dex_cache,
929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                        const ClassLoader* class_loader,
9320cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom                        bool is_direct);
949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
95b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  Field* ResolveField(uint32_t field_idx, const Method* referrer) {
96b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    Class* declaring_class = referrer->GetDeclaringClass();
97b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    DexCache* dex_cache = declaring_class->GetDexCache();
98b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    const ClassLoader* class_loader = declaring_class->GetClassLoader();
99b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    const DexFile& dex_file = FindDexFile(dex_cache);
100b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom    return ResolveField(dex_file, field_idx, dex_cache, class_loader, true);
101b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom  }
102b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom
1039ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // Resolve a method with a given ID from the DexFile, storing the
1049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // result in DexCache. The ClassLinker and ClassLoader are used as
1059ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // in ResolveType. What is unique is the is_static argument which is
1069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // used to determine if we are resolving a static or non-static
1079ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  // field.
1089ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Field* ResolveField(const DexFile& dex_file,
1099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      uint32_t field_idx,
1109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      DexCache* dex_cache,
1119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      const ClassLoader* class_loader,
1129ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                      bool is_static);
1139ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom
114f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  // Returns true on success, false if there's an exception pending.
115f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  bool EnsureInitialized(Class* c);
1160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1179ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file);
1189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache);
1190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
120a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  const InternTable& GetInternTable() {
121a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    return intern_table_;
122a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
123a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
124a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void VisitRoots(Heap::RootVistor* root_visitor, void* arg) const;
12575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
126c143c55718342519db5398e41dda31422cf16c79buzbee  const DexFile& FindDexFile(const DexCache* dex_cache) const;
1279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* FindDexCache(const DexFile& dex_file) const;
128c143c55718342519db5398e41dda31422cf16c79buzbee
1294417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  template <class T>
1304417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  ObjectArray<T>* AllocObjectArray(size_t length) {
1314417536522fd2a9d8215d8672331984769c9520bShih-wei Liao    return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
1324417536522fd2a9d8215d8672331984769c9520bShih-wei Liao  }
1334417536522fd2a9d8215d8672331984769c9520bShih-wei Liao
13455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao  ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length);
13555df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
1360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
1379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  ClassLinker();
13861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
139a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // Initialize class linker from DexFile instances.
1409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void Init(const std::vector<const DexFile*>& boot_class_path_);
14161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
142a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // Initialize class linker from pre-initialized space.
1439ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void Init(const std::vector<const DexFile*>& boot_class_path_, Space* space);
1444873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  static void InitCallback(Object* obj, void *arg);
145a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  struct InitCallbackState;
146a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
147a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void FinishInit();
148a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
149f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  bool InitializeClass(Class* klass);
150f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes
15175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // For early bootstrapping by Init
1524873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(Class* java_lang_Class, size_t class_size);
15375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
15475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // Alloc* convenience functions to avoid needing to pass in Class*
15575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // values that are known to the ClassLinker such as
15675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // kObjectArrayClass and kJavaLangString etc.
1574873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  Class* AllocClass(size_t class_size);
1589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  DexCache* AllocDexCache(const DexFile& dex_file);
15935baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson  Field* AllocField();
16075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Method* AllocMethod();
1619cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom  CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
16275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
1639cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  Class* CreatePrimitiveClass(const char* descriptor);
164a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom
165578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  Class* CreateArrayClass(const StringPiece& descriptor,
1669ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                          const ClassLoader* class_loader);
167578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
1689ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file);
1699ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache);
170578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
1714873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  size_t SizeOfClass(const DexFile& dex_file,
1724873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                     const DexFile::ClassDef& dex_class_def);
1734873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
174f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadClass(const DexFile& dex_file,
175f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::ClassDef& dex_class_def,
17674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                 Class* klass,
1779ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom                 const ClassLoader* class_loader);
178565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
179f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadInterfaces(const DexFile& dex_file,
180f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                      const DexFile::ClassDef& dex_class_def,
181578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                      Class *klass);
182934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
183f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadField(const DexFile& dex_file,
184f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::Field& dex_field,
185578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Class* klass,
186578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Field* dst);
187934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
188f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadMethod(const DexFile& dex_file,
189f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                  const DexFile::Method& dex_method,
190578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                  Class* klass,
1919cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom                  Method* dst,
1929cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom                  bool is_direct);
193934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
1949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom  Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader);
1957e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
1960e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Inserts a class into the class table.  Returns true if the class
1970e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // was inserted.
1989cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  bool InsertClass(const StringPiece& descriptor, Class* klass);
1990e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2000e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool InitializeSuperClass(Class* klass);
2010e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2020e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void InitializeStaticFields(Class* klass);
2030e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2040e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool ValidateSuperClassDescriptors(const Class* klass);
2050e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2060e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameDescriptorClasses(const char* descriptor,
2070e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass1,
2080e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass2);
2090e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2100e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameMethodDescriptorClasses(const Method* descriptor,
2110e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass1,
2120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass2);
2130e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
21474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  bool LinkClass(Class* klass, const DexFile& dex_file);
2150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkSuperClass(Class* klass);
2170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
21874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file);
2190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkMethods(Class* klass);
2210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkVirtualMethods(Class* klass);
2230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInterfaceMethods(Class* klass);
2250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void LinkAbstractMethods(Class* klass);
2270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2287833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson  bool LinkStaticFields(Class* klass);
2290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInstanceFields(Class* klass);
2304873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  bool LinkFields(size_t field_offset,
2314873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                  size_t& num_reference_fields,
2324873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                  size_t num_fields,
2334873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                  ObjectArray<Field>* fields,
2344873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                  size_t& size);
2354873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom
2364873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceInstanceOffsets(Class* klass);
2374873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceStaticOffsets(Class* klass);
2384873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom  void CreateReferenceOffsets(uint32_t& reference_offsets,
2394873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                              size_t num_reference_fields,
2404873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom                              const ObjectArray<Field>* fields);
2410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2424a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
243578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2444a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> dex_files_;
245578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
2467e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  std::vector<DexCache*> dex_caches_;
2470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2489cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // multimap from a StringPiece hash code of a class descriptor to
2499cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class* instances. Results should be compared for a matching
2509cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class::descriptor_ and Class::class_loader_.
2519cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  typedef std::tr1::unordered_multimap<size_t, Class*> Table;
2520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Table classes_;
2530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Mutex* classes_lock_;
2540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2557e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  InternTable intern_table_;
2560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
257a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // indexes into class_roots_.
258a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  // needs to be kept in sync with class_roots_descriptors_.
25974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  enum ClassRoot {
26075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangClass,
26175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangObject,
26274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kObjectArrayClass,
26374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangString,
26475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectField,
26575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectMethod,
26674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangClassLoader,
26774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemBaseDexClassLoader,
26874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemPathClassLoader,
26955df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElement,
27075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveBoolean,
271d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveByte,
27275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveChar,
27375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveDouble,
274d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveFloat,
27575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveInt,
27675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveLong,
277d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveShort,
27875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveVoid,
279d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kBooleanArrayClass,
280d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kByteArrayClass,
281d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kCharArrayClass,
282d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kDoubleArrayClass,
283d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kFloatArrayClass,
284d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kIntArrayClass,
285d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kLongArrayClass,
286d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kShortArrayClass,
28755df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao    kJavaLangStackTraceElementArrayClass,
28875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kClassRootsMax,
28975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  };
29075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  ObjectArray<Class>* class_roots_;
291913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom
29274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  Class* GetClassRoot(ClassRoot class_root) {
293a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
29474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    Class* klass = class_roots_->Get(class_root);
29574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    DCHECK(klass != NULL);
29674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return klass;
29774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  }
29874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom
299a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  void SetClassRoot(ClassRoot class_root, Class* klass) {
300a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(!init_done_);
301a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
302a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(klass != NULL);
303a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(klass->class_loader_ == NULL);
304a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(klass->descriptor_ != NULL);
305a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(klass->descriptor_->Equals(GetClassRootDescriptor(class_root)));
306a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
307a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_ != NULL);
308a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    DCHECK(class_roots_->Get(class_root) == NULL);
309a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    class_roots_->Set(class_root, klass);
310a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
311a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
312a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  static const char* class_roots_descriptors_[kClassRootsMax];
313a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
314a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  const char* GetClassRootDescriptor(ClassRoot class_root) {
315a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    const char* descriptor = class_roots_descriptors_[class_root];
316a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    CHECK(descriptor != NULL);
317a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom    return descriptor;
318a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom  }
319a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom
3204a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  ObjectArray<Class>* array_interfaces_;
321913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom  InterfaceEntry* array_iftable_;
322565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
32375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  bool init_done_;
32475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
325f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom  friend class CommonTest;
32675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(DexCacheTest, Open);
32775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  friend class ObjectTest;
32875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(ObjectTest, AllocObjectArray);
3291a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  FRIEND_TEST(ExceptionTest, FindExceptionHandler);
3300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(ClassLinker);
3310e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
3320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
3340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_CLASS_LINKER_H_
336