diff options
Diffstat (limited to 'runtime/class_linker.h')
-rw-r--r-- | runtime/class_linker.h | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 864d37fa89..62fb45b49a 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -55,8 +55,12 @@ namespace mirror { class MethodType; template<class T> class ObjectArray; class StackTraceElement; + template <typename T> struct NativeDexCachePair; + using MethodDexCachePair = NativeDexCachePair<ArtMethod>; + using MethodDexCacheType = std::atomic<MethodDexCachePair>; } // namespace mirror +class ClassHierarchyAnalysis; class ClassTable; template<class T> class Handle; class ImtConflictTable; @@ -281,12 +285,18 @@ class ClassLinker { REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); // Determine whether a dex cache result should be trusted, or an IncompatibleClassChangeError - // check should be performed even after a hit. - enum ResolveMode { // private. - kNoICCECheckForCache, - kForceICCECheck + // check and IllegalAccessError check should be performed even after a hit. + enum class ResolveMode { // private. + kNoChecks, + kCheckICCEAndIAE }; + // Look up a previously resolved method with the given index. + ArtMethod* LookupResolvedMethod(uint32_t method_idx, + ObjPtr<mirror::DexCache> dex_cache, + ObjPtr<mirror::ClassLoader> class_loader) + REQUIRES_SHARED(Locks::mutator_lock_); + // Resolve a method with a given ID from the DexFile, storing the // result in DexCache. The ClassLinker and ClassLoader are used as // in ResolveType. What is unique is the method type argument which @@ -302,17 +312,10 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); + template <InvokeType type, ResolveMode kResolveMode> ArtMethod* GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_); - // This returns the class referred to by GetMethodId(method_idx).class_idx_. This might be - // different then the declaring class of the resolved method due to copied - // miranda/default/conflict methods. - mirror::Class* ResolveReferencedClassOfMethod(uint32_t method_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) - REQUIRES_SHARED(Locks::mutator_lock_) - REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); template <ResolveMode kResolveMode> ArtMethod* ResolveMethod(Thread* self, uint32_t method_idx, ArtMethod* referrer, InvokeType type) REQUIRES_SHARED(Locks::mutator_lock_) @@ -394,9 +397,6 @@ class ClassLinker { ObjPtr<mirror::ClassLoader> class_loader) REQUIRES(!Locks::dex_lock_) REQUIRES_SHARED(Locks::mutator_lock_); - void RegisterBootClassPathDexFile(const DexFile& dex_file, ObjPtr<mirror::DexCache> dex_cache) - REQUIRES(!Locks::dex_lock_) - REQUIRES_SHARED(Locks::mutator_lock_); const std::vector<const DexFile*>& GetBootClassPath() { return boot_class_path_; @@ -430,9 +430,6 @@ class ClassLinker { ClassTable* FindClassTable(Thread* self, ObjPtr<mirror::DexCache> dex_cache) REQUIRES(!Locks::dex_lock_) REQUIRES_SHARED(Locks::mutator_lock_); - void FixupDexCaches(ArtMethod* resolution_method) - REQUIRES(!Locks::dex_lock_) - REQUIRES_SHARED(Locks::mutator_lock_); LengthPrefixedArray<ArtField>* AllocArtFieldArray(Thread* self, LinearAlloc* allocator, @@ -482,8 +479,7 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_); std::string GetDescriptorForProxy(ObjPtr<mirror::Class> proxy_class) REQUIRES_SHARED(Locks::mutator_lock_); - template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> - ArtMethod* FindMethodForProxy(ObjPtr<mirror::Class> proxy_class, ArtMethod* proxy_method) + ArtMethod* FindMethodForProxy(ArtMethod* proxy_method) REQUIRES(!Locks::dex_lock_) REQUIRES_SHARED(Locks::mutator_lock_); @@ -616,11 +612,6 @@ class ClassLinker { std::set<DexCacheResolvedClasses> GetResolvedClasses(bool ignore_boot_classes) REQUIRES(!Locks::dex_lock_); - // Returns the class descriptors for loaded dex files. - std::unordered_set<std::string> GetClassDescriptorsForResolvedClasses( - const std::set<DexCacheResolvedClasses>& classes) - REQUIRES(!Locks::dex_lock_); - static bool IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa, ObjPtr<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_); @@ -679,6 +670,10 @@ class ClassLinker { bool ValidateSuperClassDescriptors(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); + ClassHierarchyAnalysis* GetClassHierarchyAnalysis() { + return cha_.get(); + } + struct DexCacheData { // Construct an invalid data object. DexCacheData() @@ -699,7 +694,7 @@ class ClassLinker { // jweak decode that triggers read barriers (and mark them alive unnecessarily and mess with // class unloading.) const DexFile* dex_file; - ArtMethod** resolved_methods; + mirror::MethodDexCacheType* resolved_methods; // Identify the associated class loader's class table. This is used to make sure that // the Java call to native DexCache.setResolvedType() inserts the resolved type in that // class table. It is also used to make sure we don't register the same dex cache with @@ -725,7 +720,7 @@ class ClassLinker { REQUIRES(!Locks::dex_lock_) REQUIRES_SHARED(Locks::mutator_lock_); - static void DeleteClassLoader(Thread* self, const ClassLoaderData& data) + void DeleteClassLoader(Thread* self, const ClassLoaderData& data) REQUIRES_SHARED(Locks::mutator_lock_); void VisitClassesInternal(ClassVisitor* visitor) @@ -1205,6 +1200,23 @@ class ClassLinker { bool* new_conflict, ArtMethod** imt) REQUIRES_SHARED(Locks::mutator_lock_); + // Check invoke type against the referenced class. Throws IncompatibleClassChangeError + // (if `kThrowOnError`) and returns true on mismatch (kInterface on a non-interface class, + // kVirtual on interface, kDefault on interface for dex files not supporting default methods), + // otherwise returns false. + template <bool kThrowOnError, typename ClassGetter> + static bool CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_cache, + InvokeType type, + ClassGetter class_getter) + REQUIRES_SHARED(Locks::mutator_lock_); + // Helper that feeds the above function with `ClassGetter` doing `LookupResolvedType()`. + template <bool kThrow> + bool CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_cache, + InvokeType type, + uint32_t method_idx, + ObjPtr<mirror::ClassLoader> class_loader) + REQUIRES_SHARED(Locks::mutator_lock_); + std::vector<const DexFile*> boot_class_path_; std::vector<std::unique_ptr<const DexFile>> boot_dex_files_; @@ -1258,6 +1270,8 @@ class ClassLinker { // Image pointer size. PointerSize image_pointer_size_; + std::unique_ptr<ClassHierarchyAnalysis> cha_; + class FindVirtualMethodHolderVisitor; friend class AppImageClassLoadersAndDexCachesHelper; |