summaryrefslogtreecommitdiff
path: root/runtime/class_linker.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.h')
-rw-r--r--runtime/class_linker.h68
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;