class_linker.h revision 161928613d3f097108319de60494fab1aab8d48a
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 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 107161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom Method* ResolveMethod(uint32_t method_idx, const Method* referrer, bool is_direct) { 108161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom Class* declaring_class = referrer->GetDeclaringClass(); 109161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom DexCache* dex_cache = declaring_class->GetDexCache(); 110161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // TODO: we could check for a dex cache hit here 111161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom const ClassLoader* class_loader = declaring_class->GetClassLoader(); 112161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom const DexFile& dex_file = FindDexFile(dex_cache); 113161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom return ResolveMethod(dex_file, method_idx, dex_cache, class_loader, is_direct); 114161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 115161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 116b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom Field* ResolveField(uint32_t field_idx, const Method* referrer) { 117b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom Class* declaring_class = referrer->GetDeclaringClass(); 118b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom DexCache* dex_cache = declaring_class->GetDexCache(); 1190cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: we could check for a dex cache hit here 120b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom const ClassLoader* class_loader = declaring_class->GetClassLoader(); 121b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom const DexFile& dex_file = FindDexFile(dex_cache); 122b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom return ResolveField(dex_file, field_idx, dex_cache, class_loader, true); 123b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom } 124b9edb841423dfe60e193fcffd25994398c91baa2Brian Carlstrom 125161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // Resolve a field with a given ID from the DexFile, storing the 1269ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // result in DexCache. The ClassLinker and ClassLoader are used as 1279ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // in ResolveType. What is unique is the is_static argument which is 1289ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // used to determine if we are resolving a static or non-static 1299ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // field. 1309ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Field* ResolveField(const DexFile& dex_file, 1319ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom uint32_t field_idx, 1329ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* dex_cache, 1339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader, 1349ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom bool is_static); 1359ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 136f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes // Returns true on success, false if there's an exception pending. 137f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes bool EnsureInitialized(Class* c); 1380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1399ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void RegisterDexFile(const DexFile& dex_file); 1409ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache); 1410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1428a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const std::vector<const DexFile*>& GetBootClassPath() { 1438a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom return boot_class_path_; 1448a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom } 1458a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 146410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes void VisitRoots(Heap::RootVisitor* visitor, void* arg) const; 14775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 148c143c55718342519db5398e41dda31422cf16c79buzbee const DexFile& FindDexFile(const DexCache* dex_cache) const; 1499ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* FindDexCache(const DexFile& dex_file) const; 150c143c55718342519db5398e41dda31422cf16c79buzbee 1514417536522fd2a9d8215d8672331984769c9520bShih-wei Liao template <class T> 1524417536522fd2a9d8215d8672331984769c9520bShih-wei Liao ObjectArray<T>* AllocObjectArray(size_t length) { 1534417536522fd2a9d8215d8672331984769c9520bShih-wei Liao return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length); 1544417536522fd2a9d8215d8672331984769c9520bShih-wei Liao } 1554417536522fd2a9d8215d8672331984769c9520bShih-wei Liao 15655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length); 15755df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 1580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 159cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes ClassLinker(InternTable*); 16061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 161a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom // Initialize class linker from DexFile instances. 16269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom void Init(const std::vector<const DexFile*>& boot_class_path_, 16369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const std::vector<const DexFile*>& class_path_); 16461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 165c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom // Initialize class linker from pre-initialized image. 166c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom void InitFromImage(const std::vector<const DexFile*>& boot_class_path_, 167c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom const std::vector<const DexFile*>& class_path_); 168c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom static void InitFromImageCallback(Object* obj, void *arg); 169c74255fffb035001304c9a058a2e730a5a1a9604Brian Carlstrom struct InitFromImageCallbackState; 170a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 171a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom void FinishInit(); 172a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 173f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes bool InitializeClass(Class* klass); 174f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes 17575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // For early bootstrapping by Init 1764873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom Class* AllocClass(Class* java_lang_Class, size_t class_size); 17775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 17875cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // Alloc* convenience functions to avoid needing to pass in Class* 17975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // values that are known to the ClassLinker such as 18075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom // kObjectArrayClass and kJavaLangString etc. 1814873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom Class* AllocClass(size_t class_size); 1829ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* AllocDexCache(const DexFile& dex_file); 18335baaab2a79014f35e225b189f6dbec1b4ba9542Jesse Wilson Field* AllocField(); 18475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom Method* AllocMethod(); 1859cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length); 1864b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom InterfaceEntry* AllocInterfaceEntry(Class* interface); 18775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 1880cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class* CreatePrimitiveClass(const char* descriptor, 1890cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class::PrimitiveType type); 190a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom 191578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* CreateArrayClass(const StringPiece& descriptor, 1929ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader); 193578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 1949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void AppendToBootClassPath(const DexFile& dex_file); 1959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache); 196578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 1975fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, 1985fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Class* c, std::map<int, Field*>& field_map); 1995fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 2004873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom size_t SizeOfClass(const DexFile& dex_file, 2014873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom const DexFile::ClassDef& dex_class_def); 2024873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom 203f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadClass(const DexFile& dex_file, 204f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::ClassDef& dex_class_def, 20574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom Class* klass, 2069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ClassLoader* class_loader); 207565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 208f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadInterfaces(const DexFile& dex_file, 209f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::ClassDef& dex_class_def, 210578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class *klass); 211934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 212f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadField(const DexFile& dex_file, 213f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::Field& dex_field, 214578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass, 215578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Field* dst); 216934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 217f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadMethod(const DexFile& dex_file, 218f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::Method& dex_method, 219578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass, 2201f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom Method* dst); 221934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 2229ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader); 2237e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom 2240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Inserts a class into the class table. Returns true if the class 2250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // was inserted. 2269cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom bool InsertClass(const StringPiece& descriptor, Class* klass); 2270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool InitializeSuperClass(Class* klass); 2290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void InitializeStaticFields(Class* klass); 2310e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool ValidateSuperClassDescriptors(const Class* klass); 2330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool HasSameDescriptorClasses(const char* descriptor, 2350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass1, 2360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass2); 2370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool HasSameMethodDescriptorClasses(const Method* descriptor, 2390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass1, 2400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass2); 2410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2420cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers bool LinkClass(Class* klass); 2430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkSuperClass(Class* klass); 2450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 24674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file); 2470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkMethods(Class* klass); 2490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkVirtualMethods(Class* klass); 2510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkInterfaceMethods(Class* klass); 2530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2547833bd261d78be2c42284031f169a62c9065cc3cJesse Wilson bool LinkStaticFields(Class* klass); 2550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkInstanceFields(Class* klass); 2560cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers bool LinkFields(Class *klass, bool instance); 2570cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2584873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom 2594873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom void CreateReferenceInstanceOffsets(Class* klass); 2604873d465a1eb6dfbdeddb085c81239d39db60c42Brian Carlstrom void CreateReferenceStaticOffsets(Class* klass); 2610cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void CreateReferenceOffsets(Class *klass, bool instance, 2620cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers uint32_t reference_offsets); 2630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 264161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // lock to protect ClassLinker state 265161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom mutable Mutex lock_; 266161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 2674a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom std::vector<const DexFile*> boot_class_path_; 268578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 2694a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom std::vector<const DexFile*> dex_files_; 2707e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom std::vector<DexCache*> dex_caches_; 2710e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2729cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom // multimap from a StringPiece hash code of a class descriptor to 2739cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom // Class* instances. Results should be compared for a matching 2749cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom // Class::descriptor_ and Class::class_loader_. 2759cff8e13d41825c4f3f0127af061e94b06114fc8Brian Carlstrom typedef std::tr1::unordered_multimap<size_t, Class*> Table; 2760e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Table classes_; 2770e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 278a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom // indexes into class_roots_. 279a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom // needs to be kept in sync with class_roots_descriptors_. 28074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom enum ClassRoot { 28175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangClass, 28275cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangObject, 28374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kObjectArrayClass, 28474eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kJavaLangString, 28575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangReflectField, 28675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kJavaLangReflectMethod, 28774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kJavaLangClassLoader, 28874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kDalvikSystemBaseDexClassLoader, 28974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom kDalvikSystemPathClassLoader, 29055df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao kJavaLangStackTraceElement, 29175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveBoolean, 292d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kPrimitiveByte, 29375cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveChar, 29475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveDouble, 295d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kPrimitiveFloat, 29675cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveInt, 29775cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveLong, 298d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kPrimitiveShort, 29975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kPrimitiveVoid, 300d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kBooleanArrayClass, 301d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kByteArrayClass, 302d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kCharArrayClass, 303d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kDoubleArrayClass, 304d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kFloatArrayClass, 305d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kIntArrayClass, 306d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kLongArrayClass, 307d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes kShortArrayClass, 30855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao kJavaLangStackTraceElementArrayClass, 30975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom kClassRootsMax, 31075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom }; 31175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom ObjectArray<Class>* class_roots_; 312913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom 31374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom Class* GetClassRoot(ClassRoot class_root) { 314a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(class_roots_ != NULL); 31574eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom Class* klass = class_roots_->Get(class_root); 31674eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom DCHECK(klass != NULL); 31774eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom return klass; 31874eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom } 31974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom 320a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom void SetClassRoot(ClassRoot class_root, Class* klass) { 321a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(!init_done_); 322a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 323a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(klass != NULL); 3240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(klass->GetClassLoader() == NULL); 3250cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(klass->GetDescriptor() != NULL); 3260cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(klass->GetDescriptor()->Equals(GetClassRootDescriptor(class_root))); 327a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 328a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(class_roots_ != NULL); 329a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom DCHECK(class_roots_->Get(class_root) == NULL); 330a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom class_roots_->Set(class_root, klass); 331a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom } 332a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 333a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom static const char* class_roots_descriptors_[kClassRootsMax]; 334a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 335a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom const char* GetClassRootDescriptor(ClassRoot class_root) { 336a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom const char* descriptor = class_roots_descriptors_[class_root]; 337a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom CHECK(descriptor != NULL); 338a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom return descriptor; 339a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom } 340a663ea5de4c9ab6b1510fdebd6d8eca77ba699aeBrian Carlstrom 3414a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom ObjectArray<Class>* array_interfaces_; 3424b620ffb1b4d0c96a94bb3afe314f35d53990ec6Brian Carlstrom ObjectArray<InterfaceEntry>* array_iftable_; 343565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 34475cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom bool init_done_; 34575cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom 346cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes InternTable* intern_table_; 347cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes 348f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom friend class CommonTest; 34975cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom FRIEND_TEST(DexCacheTest, Open); 35075cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom friend class ObjectTest; 35175cb3b477be3757a0351fb6ab1cb70751a71e2bfBrian Carlstrom FRIEND_TEST(ObjectTest, AllocObjectArray); 3521a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao FRIEND_TEST(ExceptionTest, FindExceptionHandler); 3530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ClassLinker); 3540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 3550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 3560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 3570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 3580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_CLASS_LINKER_H_ 359