class_linker.h revision 64bf5a33d55aa779ef452552a466943002d39e4f
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" 138daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "mutex.h" 14578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "object.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: 27c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom // Initializes the class linker using DexFiles and an optional an image. 28cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes static ClassLinker* Create(const std::vector<const DexFile*>& boot_class_path, 2969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const std::vector<const DexFile*>& class_path, 30c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom InternTable* intern_table, bool image); 319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom ~ClassLinker(); 33565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 3464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes // Finds a class by its descriptor, loading it if necessary. 3574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom // If class_loader is null, searches boot_class_path_. 3664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes Class* FindClass(const StringPiece& descriptor, const ClassLoader* class_loader); 3764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 3864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes // Finds a class by its descriptor, returning NULL if it isn't wasn't loaded 3964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes // by the given 'class_loader'. 4064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader); 410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 42d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes Class* FindPrimitiveClass(char type); 43d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes 446cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom Class* FindSystemClass(const StringPiece& descriptor) { 4574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom return FindClass(descriptor, NULL); 46565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro } 47565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 489d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes void DumpAllClasses(int flags) const; 499d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 50e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes size_t NumLoadedClasses() const; 51e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 52b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom // Resolve a String with the given index from the DexFile, storing the 539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // result in the DexCache. 540cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers String* ResolveString(const DexFile& dex_file, uint32_t string_idx, DexCache* dex_cache); 559ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 56b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom // Resolve a Type with the given index from the DexFile, storing the 579ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // result in the DexCache. The referrer is used to identity the 589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // target DexCache and ClassLoader to use for resolution. 599ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Class* ResolveType(const DexFile& dex_file, 609ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom uint32_t type_idx, 619ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const Class* referrer) { 629ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom return ResolveType(dex_file, 639ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom type_idx, 649ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom referrer->GetDexCache(), 659ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom referrer->GetClassLoader()); 669ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 68b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom // Resolve a Type with the given index from the DexFile, storing the 690cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // result in the DexCache. The referrer is used to identify the 70b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom // target DexCache and ClassLoader to use for resolution. 71b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom Class* ResolveType(uint32_t type_idx, const Method* referrer) { 72b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom Class* declaring_class = referrer->GetDeclaringClass(); 73b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom DexCache* dex_cache = declaring_class->GetDexCache(); 740cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: we could check for a dex cache hit here 750cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers const ClassLoader* class_loader = declaring_class->GetClassLoader(); 760cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers const DexFile& dex_file = FindDexFile(dex_cache); 770cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return ResolveType(dex_file, type_idx, dex_cache, class_loader); 780cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 790cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 800cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class* ResolveType(uint32_t type_idx, const Field* referrer) { 810cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class* declaring_class = referrer->GetDeclaringClass(); 820cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DexCache* dex_cache = declaring_class->GetDexCache(); 830cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: we could check for a dex cache hit here 84b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom const ClassLoader* class_loader = declaring_class->GetClassLoader(); 85b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom const DexFile& dex_file = FindDexFile(dex_cache); 86b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom return ResolveType(dex_file, type_idx, dex_cache, class_loader); 87b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom } 88b63ec393a5c4ba2be1d34dd871cda811eaa803c7Brian Carlstrom 899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // Resolve a type with the given ID from the DexFile, storing the 909ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // result in DexCache. The ClassLoader is used to search for the 919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // type, since it may be referenced from but not contained within 929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // the given DexFile. 939ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Class* ResolveType(const DexFile& dex_file, 949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom uint32_t type_idx, 959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* dex_cache, 969ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader); 979ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 98b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom static StaticStorageBase* InitializeStaticStorageFromCode(uint32_t type_idx, 99b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom const Method* referrer); 1001caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom 1019ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // Resolve a method with a given ID from the DexFile, storing the 1029ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // result in DexCache. The ClassLinker and ClassLoader are used as 1039ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // in ResolveType. What is unique is the method type argument which 1049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // is used to determine if this method is a direct, static, or 1059ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // virtual method. 1069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Method* ResolveMethod(const DexFile& dex_file, 1079ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom uint32_t method_idx, 1089ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* dex_cache, 1099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader, 11020cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom bool is_direct); 1119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 112161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom Method* ResolveMethod(uint32_t method_idx, const Method* referrer, bool is_direct) { 113161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom Class* declaring_class = referrer->GetDeclaringClass(); 114161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom DexCache* dex_cache = declaring_class->GetDexCache(); 115161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // TODO: we could check for a dex cache hit here 116161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom const ClassLoader* class_loader = declaring_class->GetClassLoader(); 117161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom const DexFile& dex_file = FindDexFile(dex_cache); 118161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom return ResolveMethod(dex_file, method_idx, dex_cache, class_loader, is_direct); 119161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 120161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 121845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom Field* ResolveField(uint32_t field_idx, const Method* referrer, bool is_static) { 122b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom Class* declaring_class = referrer->GetDeclaringClass(); 123b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom DexCache* dex_cache = declaring_class->GetDexCache(); 1240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: we could check for a dex cache hit here 125b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom const ClassLoader* class_loader = declaring_class->GetClassLoader(); 126b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom const DexFile& dex_file = FindDexFile(dex_cache); 127845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom return ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static); 128b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom } 129b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom 130161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // Resolve a field with a given ID from the DexFile, storing the 1319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // result in DexCache. The ClassLinker and ClassLoader are used as 1329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // in ResolveType. What is unique is the is_static argument which is 1339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // used to determine if we are resolving a static or non-static 1349ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // field. 1359ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Field* ResolveField(const DexFile& dex_file, 1369ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom uint32_t field_idx, 1379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* dex_cache, 1389ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader, 1399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom bool is_static); 1409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 141f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes // Returns true on success, false if there's an exception pending. 14225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom // can_run_clinit=false allows the compiler to attempt to init a class, 14325c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom // given the restriction that no <clinit> execution is possible. 14425c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom bool EnsureInitialized(Class* c, bool can_run_clinit); 1450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1469ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void RegisterDexFile(const DexFile& dex_file); 1479ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache); 1480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1498a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const std::vector<const DexFile*>& GetBootClassPath() { 1508a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom return boot_class_path_; 1518a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom } 1528a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 153410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes void VisitRoots(Heap::RootVisitor* visitor, void* arg) const; 15475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 155c143c55718342519db5398e41dda31422cf16c79buzbee const DexFile& FindDexFile(const DexCache* dex_cache) const; 1569ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* FindDexCache(const DexFile& dex_file) const; 157c143c55718342519db5398e41dda31422cf16c79buzbee 1584417536522fd2a9d8215d8672331984769c9520bShih-wei Liao template <class T> 1594417536522fd2a9d8215d8672331984769c9520bShih-wei Liao ObjectArray<T>* AllocObjectArray(size_t length) { 1604417536522fd2a9d8215d8672331984769c9520bShih-wei Liao return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length); 1614417536522fd2a9d8215d8672331984769c9520bShih-wei Liao } 1624417536522fd2a9d8215d8672331984769c9520bShih-wei Liao 16355df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length); 16455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 16598eacac683b78e60799323e8c7d59e7214808639jeffhao void VerifyClass(Class* klass); 16698eacac683b78e60799323e8c7d59e7214808639jeffhao 1670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 168cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes ClassLinker(InternTable*); 16961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 170a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom // Initialize class linker from DexFile instances. 17169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom void Init(const std::vector<const DexFile*>& boot_class_path_, 17269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const std::vector<const DexFile*>& class_path_); 17361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 174c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom // Initialize class linker from pre-initialized image. 175c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom void InitFromImage(const std::vector<const DexFile*>& boot_class_path_, 176c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom const std::vector<const DexFile*>& class_path_); 17778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom static void InitFromImageCallback(Object* obj, void* arg); 178c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom struct InitFromImageCallbackState; 179a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 180a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom void FinishInit(); 181a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 18225c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom bool InitializeClass(Class* klass, bool can_run_clinit); 183f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes 18475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // For early bootstrapping by Init 1854873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom Class* AllocClass(Class* java_lang_Class, size_t class_size); 18675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 18775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // Alloc* convenience functions to avoid needing to pass in Class* 18875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // values that are known to the ClassLinker such as 18975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // kObjectArrayClass and kJavaLangString etc. 1904873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom Class* AllocClass(size_t class_size); 1919ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* AllocDexCache(const DexFile& dex_file); 19235baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson Field* AllocField(); 193bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 194bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // TODO: have no friends, we need this currently to create a special method 195bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // to describe callee save registers for throwing exceptions 196bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers friend class Thread; 19775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom Method* AllocMethod(); 198bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1999cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length); 2004b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom InterfaceEntry* AllocInterfaceEntry(Class* interface); 20175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 2020cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class* CreatePrimitiveClass(const char* descriptor, 2035b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom Class::PrimitiveType type) { 2045b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom return InitializePrimitiveClass(AllocClass(sizeof(Class)), descriptor, type); 2055b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom } 2065b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom Class* InitializePrimitiveClass(Class* primitive_class, 2075b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom const char* descriptor, 2085b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom Class::PrimitiveType type); 2095b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom 210a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom 211578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* CreateArrayClass(const StringPiece& descriptor, 2129ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader); 213578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 2149ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void AppendToBootClassPath(const DexFile& dex_file); 2159ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache); 216578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 2175fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, 2185fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Class* c, std::map<int, Field*>& field_map); 2195fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 2204873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom size_t SizeOfClass(const DexFile& dex_file, 2214873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom const DexFile::ClassDef& dex_class_def); 2224873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom 223f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadClass(const DexFile& dex_file, 224f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::ClassDef& dex_class_def, 22574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom Class* klass, 2269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader); 227565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 228f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadInterfaces(const DexFile& dex_file, 229f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::ClassDef& dex_class_def, 230578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class *klass); 231934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 232f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadField(const DexFile& dex_file, 233f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::Field& dex_field, 234578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass, 235578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Field* dst); 236934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 237f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadMethod(const DexFile& dex_file, 238f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::Method& dex_method, 239578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass, 2401f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom Method* dst); 241934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 2420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Inserts a class into the class table. Returns true if the class 2430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // was inserted. 2449cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom bool InsertClass(const StringPiece& descriptor, Class* klass); 2450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 24625c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom bool InitializeSuperClass(Class* klass, bool can_run_clinit); 2470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void InitializeStaticFields(Class* klass); 2490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool ValidateSuperClassDescriptors(const Class* klass); 2510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool HasSameDescriptorClasses(const char* descriptor, 2530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass1, 2540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass2); 2550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool HasSameMethodDescriptorClasses(const Method* descriptor, 2570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass1, 2580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass2); 2590e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2600cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers bool LinkClass(Class* klass); 2610e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkSuperClass(Class* klass); 2630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 26474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file); 2650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2660e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkMethods(Class* klass); 2670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2680e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkVirtualMethods(Class* klass); 2690e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2700e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkInterfaceMethods(Class* klass); 2710e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2727833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson bool LinkStaticFields(Class* klass); 2730e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkInstanceFields(Class* klass); 2740cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers bool LinkFields(Class *klass, bool instance); 2750cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2764873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom 2774873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom void CreateReferenceInstanceOffsets(Class* klass); 2784873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom void CreateReferenceStaticOffsets(Class* klass); 2790cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void CreateReferenceOffsets(Class *klass, bool instance, 2800cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers uint32_t reference_offsets); 2810e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 282161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // lock to protect ClassLinker state 283161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom mutable Mutex lock_; 284161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 2854a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom std::vector<const DexFile*> boot_class_path_; 286578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 2874a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom std::vector<const DexFile*> dex_files_; 2887e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom std::vector<DexCache*> dex_caches_; 2890e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2909cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom // multimap from a StringPiece hash code of a class descriptor to 2919cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom // Class* instances. Results should be compared for a matching 2929cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom // Class::descriptor_ and Class::class_loader_. 2939cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom typedef std::tr1::unordered_multimap<size_t, Class*> Table; 2940e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Table classes_; 2950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 296a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom // indexes into class_roots_. 297a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom // needs to be kept in sync with class_roots_descriptors_. 29874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom enum ClassRoot { 29975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangClass, 30075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangObject, 30174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kObjectArrayClass, 30274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kJavaLangString, 30375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangReflectField, 30475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangReflectMethod, 30574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kJavaLangClassLoader, 30674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kDalvikSystemBaseDexClassLoader, 30774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kDalvikSystemPathClassLoader, 30855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao kJavaLangStackTraceElement, 30975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveBoolean, 310d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kPrimitiveByte, 31175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveChar, 31275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveDouble, 313d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kPrimitiveFloat, 31475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveInt, 31575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveLong, 316d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kPrimitiveShort, 31775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveVoid, 318d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kBooleanArrayClass, 319d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kByteArrayClass, 320d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kCharArrayClass, 321d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kDoubleArrayClass, 322d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kFloatArrayClass, 323d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kIntArrayClass, 324d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kLongArrayClass, 325d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kShortArrayClass, 32655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao kJavaLangStackTraceElementArrayClass, 32775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kClassRootsMax, 32875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom }; 32975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom ObjectArray<Class>* class_roots_; 330913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom 33174eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom Class* GetClassRoot(ClassRoot class_root) { 332a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(class_roots_ != NULL); 33374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom Class* klass = class_roots_->Get(class_root); 33474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom DCHECK(klass != NULL); 33574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom return klass; 33674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom } 33774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom 338a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom void SetClassRoot(ClassRoot class_root, Class* klass) { 339a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(!init_done_); 340a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 341a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(klass != NULL); 3420cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(klass->GetClassLoader() == NULL); 3430cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(klass->GetDescriptor() != NULL); 3440cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(klass->GetDescriptor()->Equals(GetClassRootDescriptor(class_root))); 345a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 346a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(class_roots_ != NULL); 347a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(class_roots_->Get(class_root) == NULL); 348a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom class_roots_->Set(class_root, klass); 349a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom } 350a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 351a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom static const char* class_roots_descriptors_[kClassRootsMax]; 352a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 353a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom const char* GetClassRootDescriptor(ClassRoot class_root) { 354a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom const char* descriptor = class_roots_descriptors_[class_root]; 355a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom CHECK(descriptor != NULL); 356a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom return descriptor; 357a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom } 358a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 3594a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom ObjectArray<Class>* array_interfaces_; 3604b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom ObjectArray<InterfaceEntry>* array_iftable_; 361565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 36275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom bool init_done_; 36375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 364cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes InternTable* intern_table_; 365cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes 366f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom friend class CommonTest; 36775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom FRIEND_TEST(DexCacheTest, Open); 36875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom friend class ObjectTest; 36975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom FRIEND_TEST(ObjectTest, AllocObjectArray); 3701a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao FRIEND_TEST(ExceptionTest, FindExceptionHandler); 3710e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ClassLinker); 3720e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 3730e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 3740e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 3750e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 3760e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_CLASS_LINKER_H_ 377