class_linker.h revision 9cff8e13d41825c4f3f0127af061e94b06114fc8
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"
177e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
18578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "gtest/gtest.h"
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass ClassLinker {
230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
24565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro  // Initializes the class linker.
252ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path);
2661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
27de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes  ~ClassLinker() {
28de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes    delete classes_lock_;
29de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes  }
30565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
310e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Finds a class by its descriptor name.
3274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  // If class_loader is null, searches boot_class_path_.
336cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom  Class* FindClass(const StringPiece& descriptor,
3474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                   ClassLoader* class_loader);
350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
36d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes  Class* FindPrimitiveClass(char type);
37d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
386cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom  Class* FindSystemClass(const StringPiece& descriptor) {
3974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return FindClass(descriptor, NULL);
40565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro  }
41565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
42f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  // Returns true on success, false if there's an exception pending.
43f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  bool EnsureInitialized(Class* c);
440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
454a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  void RegisterDexFile(const DexFile* dex_file);
460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
477e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  void VisitRoots(Heap::RootVistor* root_visitor, void* arg);
4875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
50d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes  ClassLinker()
51d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes      : classes_lock_(Mutex::Create("ClassLinker::Lock")),
52d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes        init_done_(false) {
537e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  }
5461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
552ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  void Init(const std::vector<DexFile*>& boot_class_path_);
5661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
57f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes  bool InitializeClass(Class* klass);
58f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes
5975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // For early bootstrapping by Init
6075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Class* AllocClass(Class* java_lang_Class);
6175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
6275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // Alloc* convenience functions to avoid needing to pass in Class*
6375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // values that are known to the ClassLinker such as
6475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // kObjectArrayClass and kJavaLangString etc.
6575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Class* AllocClass();
6675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  DexCache* AllocDexCache();
6735baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson  Field* AllocField();
6875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  Method* AllocMethod();
6975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  template <class T>
7075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  ObjectArray<T>* AllocObjectArray(size_t length) {
7175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    return ObjectArray<T>::Alloc(class_roots_->Get(kObjectArrayClass), length);
7275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  }
7374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  PathClassLoader* AllocPathClassLoader(std::vector<const DexFile*> dex_files);
7475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
759cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  Class* CreatePrimitiveClass(const char* descriptor);
76a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom
77578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom  Class* CreateArrayClass(const StringPiece& descriptor,
7874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                          ClassLoader* class_loader);
79578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
8074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  const DexFile& FindDexFile(const DexCache* dex_cache) const;
81578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
82f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  DexCache* FindDexCache(const DexFile* dex_file) const;
83578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
84f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void AppendToBootClassPath(DexFile* dex_file);
85578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
86f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadClass(const DexFile& dex_file,
87f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::ClassDef& dex_class_def,
8874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                 Class* klass,
8974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom                 ClassLoader* class_loader);
90565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
91f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadInterfaces(const DexFile& dex_file,
92f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                      const DexFile::ClassDef& dex_class_def,
93578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                      Class *klass);
94934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
95f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadField(const DexFile& dex_file,
96f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                 const DexFile::Field& dex_field,
97578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Class* klass,
98578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                 Field* dst);
99934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
100f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  void LoadMethod(const DexFile& dex_file,
101f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom                  const DexFile::Method& dex_method,
102578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                  Class* klass,
103578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom                  Method* dst);
104934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom
1057e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  Class* ResolveClass(const Class* referring,
1067e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom                      uint32_t class_idx,
1077e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom                      const DexFile& dex_file);
1087e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
1097e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  String* ResolveString(const Class* referring,
1107e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom                        uint32_t string_idx,
1117e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom                        const DexFile& dex_file);
1127e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
1137e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  Class* LookupClass(const StringPiece& descriptor, ClassLoader* class_loader);
1147e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom
1150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Inserts a class into the class table.  Returns true if the class
1160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // was inserted.
1179cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  bool InsertClass(const StringPiece& descriptor, Class* klass);
1180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool InitializeSuperClass(Class* klass);
1200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void InitializeStaticFields(Class* klass);
1220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool ValidateSuperClassDescriptors(const Class* klass);
1240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameDescriptorClasses(const char* descriptor,
1260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass1,
1270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                const Class* klass2);
1280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool HasSameMethodDescriptorClasses(const Method* descriptor,
1300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass1,
1310e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro                                      const Class* klass2);
1320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
13374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  bool LinkClass(Class* klass, const DexFile& dex_file);
1340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkSuperClass(Class* klass);
1360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
13774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file);
1380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkMethods(Class* klass);
1400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkVirtualMethods(Class* klass);
1420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInterfaceMethods(Class* klass);
1440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void LinkAbstractMethods(Class* klass);
1460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1477833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson  bool LinkStaticFields(Class* klass);
1487833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson
1490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool LinkInstanceFields(Class* klass);
1500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  void CreateReferenceOffsets(Class* klass);
1520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1534a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> boot_class_path_;
154578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
1554a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  std::vector<const DexFile*> dex_files_;
156578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
1577e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  std::vector<DexCache*> dex_caches_;
1580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1599cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // multimap from a StringPiece hash code of a class descriptor to
1609cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class* instances. Results should be compared for a matching
1619cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  // Class::descriptor_ and Class::class_loader_.
1629cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom  typedef std::tr1::unordered_multimap<size_t, Class*> Table;
1630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Table classes_;
1640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Mutex* classes_lock_;
1650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1667e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom  InternTable intern_table_;
1670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
16875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  // indexes into class_roots_
16974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  enum ClassRoot {
17075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangClass,
17175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangObject,
17274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kObjectArrayClass,
17374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangString,
17475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectField,
17575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kJavaLangReflectMethod,
17674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kJavaLangClassLoader,
17774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemBaseDexClassLoader,
17874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    kDalvikSystemPathClassLoader,
17975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveBoolean,
180d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveByte,
18175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveChar,
18275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveDouble,
183d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveFloat,
18475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveInt,
18575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveLong,
186d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kPrimitiveShort,
18775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kPrimitiveVoid,
188d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kBooleanArrayClass,
189d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kByteArrayClass,
190d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kCharArrayClass,
191d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kDoubleArrayClass,
192d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kFloatArrayClass,
193d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kIntArrayClass,
194d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kLongArrayClass,
195d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes    kShortArrayClass,
19675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom    kClassRootsMax,
19775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  };
19875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  ObjectArray<Class>* class_roots_;
199913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom
20074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  Class* GetClassRoot(ClassRoot class_root) {
20174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    Class* klass = class_roots_->Get(class_root);
20274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    DCHECK(klass != NULL);
20374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom    return klass;
20474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom  }
20574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom
2064a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom  ObjectArray<Class>* array_interfaces_;
207913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom  InterfaceEntry* array_iftable_;
208565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro
20975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  bool init_done_;
21075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom
211f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom  friend class CommonTest;
21275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(DexCacheTest, Open);
21375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  friend class ObjectTest;
21475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom  FRIEND_TEST(ObjectTest, AllocObjectArray);
2152fb9753c58ce1a511fd6996856840120eb2930dbShih-wei Liao  FRIEND_TEST(ExceptionTest, MyClass_F_G);
2160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(ClassLinker);
2170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
2180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
2200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_CLASS_LINKER_H_
222