diff options
Diffstat (limited to 'runtime/class_linker.h')
| -rw-r--r-- | runtime/class_linker.h | 123 |
1 files changed, 75 insertions, 48 deletions
diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 7f3e93806e..a70967d49b 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_CLASS_LINKER_H_ #include <string> +#include <unordered_map> #include <utility> #include <vector> @@ -318,24 +319,17 @@ class ClassLinker { SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); - mirror::DexCache* RegisterDexFile(const DexFile& dex_file) + mirror::DexCache* RegisterDexFile(const DexFile& dex_file, LinearAlloc* linear_alloc) REQUIRES(!dex_lock_) SHARED_REQUIRES(Locks::mutator_lock_); void RegisterDexFile(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) REQUIRES(!dex_lock_) SHARED_REQUIRES(Locks::mutator_lock_); - const OatFile* RegisterOatFile(const OatFile* oat_file) - REQUIRES(!dex_lock_); - const std::vector<const DexFile*>& GetBootClassPath() { return boot_class_path_; } - // Returns the first non-image oat file in the class path. - const OatFile* GetPrimaryOatFile() - REQUIRES(!dex_lock_); - void VisitClasses(ClassVisitor* visitor) REQUIRES(!Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_); @@ -364,26 +358,6 @@ class ClassLinker { REQUIRES(!dex_lock_) SHARED_REQUIRES(Locks::mutator_lock_); - // Finds or creates the oat file holding dex_location. Then loads and returns - // all corresponding dex files (there may be more than one dex file loaded - // in the case of multidex). - // This may return the original, unquickened dex files if the oat file could - // not be generated. - // - // Returns an empty vector if the dex files could not be loaded. In this - // case, there will be at least one error message returned describing why no - // dex files could not be loaded. The 'error_msgs' argument must not be - // null, regardless of whether there is an error or not. - // - // This method should not be called with the mutator_lock_ held, because it - // could end up starving GC if we need to generate or relocate any oat - // files. - std::vector<std::unique_ptr<const DexFile>> OpenDexFilesFromOat( - const char* dex_location, - const char* oat_location, - std::vector<std::string>* error_msgs) - REQUIRES(!dex_lock_, !Locks::mutator_lock_); - // Allocate an instance of a java.lang.Object. mirror::Object* AllocObject(Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) @@ -558,6 +532,12 @@ class ClassLinker { static LinearAlloc* GetAllocatorForClassLoader(mirror::ClassLoader* class_loader) SHARED_REQUIRES(Locks::mutator_lock_); + // Return the linear alloc for a class loader if it is already allocated, otherwise allocate and + // set it. TODO: Consider using a lock other than classlinker_classes_lock_. + static LinearAlloc* GetOrCreateAllocatorForClassLoader(mirror::ClassLoader* class_loader) + SHARED_REQUIRES(Locks::mutator_lock_) + REQUIRES(!Locks::classlinker_classes_lock_); + private: struct ClassLoaderData { jweak weak_root; // Weak root to enable class unloading. @@ -581,10 +561,6 @@ class ClassLinker { REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_); - OatFile& GetImageOatFile(gc::space::ImageSpace* space) - REQUIRES(!dex_lock_) - SHARED_REQUIRES(Locks::mutator_lock_); - void FinishInit(Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_, !Roles::uninterruptible_); @@ -600,7 +576,9 @@ class ClassLinker { mirror::Class* AllocClass(Thread* self, uint32_t class_size) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); - mirror::DexCache* AllocDexCache(Thread* self, const DexFile& dex_file) + mirror::DexCache* AllocDexCache(Thread* self, + const DexFile& dex_file, + LinearAlloc* linear_alloc) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); @@ -679,6 +657,12 @@ class ClassLinker { bool can_init_parents) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_); + bool InitializeDefaultInterfaceRecursive(Thread* self, + Handle<mirror::Class> klass, + bool can_run_clinit, + bool can_init_parents) + REQUIRES(!dex_lock_) + SHARED_REQUIRES(Locks::mutator_lock_); bool WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self, ObjectLock<mirror::Class>& lock); @@ -718,12 +702,65 @@ class ClassLinker { ArtMethod** out_imt) SHARED_REQUIRES(Locks::mutator_lock_); - bool LinkVirtualMethods(Thread* self, Handle<mirror::Class> klass) - SHARED_REQUIRES(Locks::mutator_lock_); - + // Links the virtual methods for the given class and records any default methods that will need to + // be updated later. + // + // Arguments: + // * self - The current thread. + // * klass - class, whose vtable will be filled in. + // * default_translations - Vtable index to new method map. + // Any vtable entries that need to be updated with new default methods + // are stored into the default_translations map. The default_translations + // map is keyed on the vtable index that needs to be updated. We use this + // map because if we override a default method with another default + // method we need to update the vtable to point to the new method. + // Unfortunately since we copy the ArtMethod* we cannot just do a simple + // scan, we therefore store the vtable index's that might need to be + // updated with the method they will turn into. + // TODO This whole default_translations thing is very dirty. There should be a better way. + bool LinkVirtualMethods(Thread* self, + Handle<mirror::Class> klass, + /*out*/std::unordered_map<size_t, ArtMethod*>* default_translations) + SHARED_REQUIRES(Locks::mutator_lock_); + + // Sets up the interface lookup table (IFTable) in the correct order to allow searching for + // default methods. + bool SetupInterfaceLookupTable(Thread* self, + Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces) + SHARED_REQUIRES(Locks::mutator_lock_); + + // Find the default method implementation for 'interface_method' in 'klass', if one exists. + // + // Arguments: + // * self - The current thread. + // * target_method - The method we are trying to find a default implementation for. + // * klass - The class we are searching for a definition of target_method. + // * out_default_method - The pointer we will store the found default method to on success. + // * icce_message - A string we will store an appropriate IncompatibleClassChangeError message + // into in case of failure. Note we must do it this way since we do not know + // whether we can allocate the exception object, which could cause us to go to + // sleep. + // + // Return value: + // * True - There were no conflicting method implementations found in the class while searching + // for target_method. The default method implementation is stored into out_default_method + // if it was found. Otherwise *out_default_method will be set to nullptr. + // * False - Conflicting method implementations were found when searching for target_method. The + // value of *out_default_method is undefined and *icce_message is a string that should + // be used to create an IncompatibleClassChangeError as soon as possible. + bool FindDefaultMethodImplementation(Thread* self, + ArtMethod* target_method, + Handle<mirror::Class> klass, + /*out*/ArtMethod** out_default_method, + /*out*/std::string* icce_message) const + SHARED_REQUIRES(Locks::mutator_lock_); + + // Sets the imt entries and fixes up the vtable for the given class by linking all the interface + // methods. See LinkVirtualMethods for an explanation of what default_translations is. bool LinkInterfaceMethods(Thread* self, Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces, + const std::unordered_map<size_t, ArtMethod*>& default_translations, ArtMethod** out_imt) SHARED_REQUIRES(Locks::mutator_lock_); @@ -758,12 +795,6 @@ class ClassLinker { return dex_caches_; } - const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location) - REQUIRES(!dex_lock_); - - // Returns the boot image oat file. - const OatFile* GetBootOatFile() SHARED_REQUIRES(dex_lock_); - void CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out) SHARED_REQUIRES(Locks::mutator_lock_); void CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prototype, ArtMethod* out) @@ -813,9 +844,6 @@ class ClassLinker { SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_); - // Check for duplicate class definitions of the given oat file against all open oat files. - bool HasCollisions(const OatFile* oat_file, std::string* error_msg) REQUIRES(!dex_lock_); - bool HasInitWithString(Thread* self, const char* descriptor) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_); @@ -834,7 +862,6 @@ class ClassLinker { // JNI weak globals to allow dex caches to get unloaded. We lazily delete weak globals when we // register new dex files. std::list<jweak> dex_caches_ GUARDED_BY(dex_lock_); - std::vector<const OatFile*> oat_files_ GUARDED_BY(dex_lock_); // This contains the class loaders which have class tables. It is populated by // InsertClassTableForClassLoader. @@ -880,8 +907,8 @@ class ClassLinker { // Image pointer size. size_t image_pointer_size_; + friend class ImageDumper; // for DexLock friend class ImageWriter; // for GetClassRoots - friend class ImageDumper; // for FindOpenedOatFileFromOatLocation friend class JniCompilerTest; // for GetRuntimeQuickGenericJniStub friend class JniInternalTest; // for GetRuntimeQuickGenericJniStub ART_FRIEND_TEST(mirror::DexCacheTest, Open); // for AllocDexCache |