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.h232
1 files changed, 102 insertions, 130 deletions
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 52ecf82c86..548bf915dd 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -27,6 +27,7 @@
#include "base/enums.h"
#include "base/macros.h"
#include "base/mutex.h"
+#include "dex/class_accessor.h"
#include "dex/dex_cache_resolved_classes.h"
#include "dex/dex_file.h"
#include "dex/dex_file_types.h"
@@ -67,7 +68,10 @@ using MethodDexCachePair = NativeDexCachePair<ArtMethod>;
using MethodDexCacheType = std::atomic<MethodDexCachePair>;
} // namespace mirror
+class ArtField;
+class ArtMethod;
class ClassHierarchyAnalysis;
+enum class ClassRoot : uint32_t;
class ClassTable;
template<class T> class Handle;
class ImtConflictTable;
@@ -107,59 +111,6 @@ class AllocatorVisitor {
class ClassLinker {
public:
- // Well known mirror::Class roots accessed via GetClassRoot.
- enum ClassRoot {
- kJavaLangClass,
- kJavaLangObject,
- kClassArrayClass,
- kObjectArrayClass,
- kJavaLangString,
- kJavaLangDexCache,
- kJavaLangRefReference,
- kJavaLangReflectConstructor,
- kJavaLangReflectField,
- kJavaLangReflectMethod,
- kJavaLangReflectProxy,
- kJavaLangStringArrayClass,
- kJavaLangReflectConstructorArrayClass,
- kJavaLangReflectFieldArrayClass,
- kJavaLangReflectMethodArrayClass,
- kJavaLangInvokeCallSite,
- kJavaLangInvokeMethodHandleImpl,
- kJavaLangInvokeMethodHandlesLookup,
- kJavaLangInvokeMethodType,
- kJavaLangInvokeVarHandle,
- kJavaLangInvokeFieldVarHandle,
- kJavaLangInvokeArrayElementVarHandle,
- kJavaLangInvokeByteArrayViewVarHandle,
- kJavaLangInvokeByteBufferViewVarHandle,
- kJavaLangClassLoader,
- kJavaLangThrowable,
- kJavaLangClassNotFoundException,
- kJavaLangStackTraceElement,
- kDalvikSystemEmulatedStackFrame,
- kPrimitiveBoolean,
- kPrimitiveByte,
- kPrimitiveChar,
- kPrimitiveDouble,
- kPrimitiveFloat,
- kPrimitiveInt,
- kPrimitiveLong,
- kPrimitiveShort,
- kPrimitiveVoid,
- kBooleanArrayClass,
- kByteArrayClass,
- kCharArrayClass,
- kDoubleArrayClass,
- kFloatArrayClass,
- kIntArrayClass,
- kLongArrayClass,
- kShortArrayClass,
- kJavaLangStackTraceElementArrayClass,
- kDalvikSystemClassExt,
- kClassRootsMax,
- };
-
static constexpr bool kAppImageMayContainStrings = false;
explicit ClassLinker(InternTable* intern_table);
@@ -198,22 +149,22 @@ class ClassLinker {
// Finds a class by its descriptor, loading it if necessary.
// If class_loader is null, searches boot_class_path_.
- mirror::Class* FindClass(Thread* self,
- const char* descriptor,
- Handle<mirror::ClassLoader> class_loader)
+ ObjPtr<mirror::Class> FindClass(Thread* self,
+ const char* descriptor,
+ Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
// Finds a class by its descriptor using the "system" class loader, ie by searching the
// boot_class_path_.
- mirror::Class* FindSystemClass(Thread* self, const char* descriptor)
+ ObjPtr<mirror::Class> FindSystemClass(Thread* self, const char* descriptor)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_) {
return FindClass(self, descriptor, ScopedNullHandle<mirror::ClassLoader>());
}
// Finds the array class given for the element class.
- mirror::Class* FindArrayClass(Thread* self, ObjPtr<mirror::Class>* element_class)
+ ObjPtr<mirror::Class> FindArrayClass(Thread* self, ObjPtr<mirror::Class> element_class)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
@@ -223,20 +174,20 @@ class ClassLinker {
}
// Define a new a class based on a ClassDef from a DexFile
- mirror::Class* DefineClass(Thread* self,
- const char* descriptor,
- size_t hash,
- Handle<mirror::ClassLoader> class_loader,
- const DexFile& dex_file,
- const DexFile::ClassDef& dex_class_def)
+ ObjPtr<mirror::Class> DefineClass(Thread* self,
+ const char* descriptor,
+ size_t hash,
+ Handle<mirror::ClassLoader> class_loader,
+ const DexFile& dex_file,
+ const DexFile::ClassDef& dex_class_def)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
// Finds a class by its descriptor, returning null if it isn't wasn't loaded
// by the given 'class_loader'.
- mirror::Class* LookupClass(Thread* self,
- const char* descriptor,
- ObjPtr<mirror::ClassLoader> class_loader)
+ ObjPtr<mirror::Class> LookupClass(Thread* self,
+ const char* descriptor,
+ ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -245,7 +196,7 @@ class ClassLinker {
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::Class* FindPrimitiveClass(char type) REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::Class> FindPrimitiveClass(char type) REQUIRES_SHARED(Locks::mutator_lock_);
void DumpForSigQuit(std::ostream& os) REQUIRES(!Locks::classlinker_classes_lock_);
@@ -253,6 +204,16 @@ class ClassLinker {
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
+ // Resolve a String with the given index from the DexFile associated with the given `referrer`,
+ // storing the result in the DexCache. The `referrer` is used to identify the target DexCache
+ // to use for resolution.
+ ObjPtr<mirror::String> ResolveString(dex::StringIndex string_idx,
+ ArtField* referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::String> ResolveString(dex::StringIndex string_idx,
+ ArtMethod* referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Resolve a String with the given index from the DexFile associated with the given DexCache,
// storing the result in the DexCache.
ObjPtr<mirror::String> ResolveString(dex::StringIndex string_idx,
@@ -271,10 +232,9 @@ class ClassLinker {
ObjPtr<mirror::Class> ResolveType(dex::TypeIndex type_idx, ObjPtr<mirror::Class> referrer)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
-
- // Resolve a type with the given index from the DexFile associated with the given `referrer`,
- // storing the result in the DexCache. The `referrer` is used to identify the target DexCache
- // and ClassLoader to use for resolution.
+ ObjPtr<mirror::Class> ResolveType(dex::TypeIndex type_idx, ArtField* referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
ObjPtr<mirror::Class> ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
@@ -294,10 +254,8 @@ class ClassLinker {
ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_idx,
ObjPtr<mirror::Class> referrer)
REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Look up a resolved type with the given index from the DexFile associated with the given
- // `referrer`, storing the result in the DexCache. The `referrer` is used to identify the
- // target DexCache and ClassLoader to use for lookup.
+ ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_idx, ArtField* referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_);
ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_idx, ArtMethod* referrer)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -504,16 +462,16 @@ class ClassLinker {
LinearAlloc* allocator,
size_t length);
- mirror::PointerArray* AllocPointerArray(Thread* self, size_t length)
+ ObjPtr<mirror::PointerArray> AllocPointerArray(Thread* self, size_t length)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
- mirror::IfTable* AllocIfTable(Thread* self, size_t ifcount)
+ ObjPtr<mirror::IfTable> AllocIfTable(Thread* self, size_t ifcount)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
- mirror::ObjectArray<mirror::StackTraceElement>* AllocStackTraceElementArray(Thread* self,
- size_t length)
+ ObjPtr<mirror::ObjectArray<mirror::StackTraceElement>> AllocStackTraceElementArray(Thread* self,
+ size_t length)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
@@ -535,12 +493,12 @@ class ClassLinker {
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
- mirror::Class* CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa,
- jstring name,
- jobjectArray interfaces,
- jobject loader,
- jobjectArray methods,
- jobjectArray throws)
+ ObjPtr<mirror::Class> CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa,
+ jstring name,
+ jobjectArray interfaces,
+ jobject loader,
+ jobjectArray methods,
+ jobjectArray throws)
REQUIRES_SHARED(Locks::mutator_lock_);
std::string GetDescriptorForProxy(ObjPtr<mirror::Class> proxy_class)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -552,10 +510,6 @@ class ClassLinker {
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
- mirror::Class* GetClassRoot(ClassRoot class_root) REQUIRES_SHARED(Locks::mutator_lock_);
-
- static const char* GetClassRootDescriptor(ClassRoot class_root);
-
// Is the given entry point quick code to run the resolution stub?
bool IsQuickResolutionStub(const void* entry_point) const;
@@ -587,7 +541,9 @@ class ClassLinker {
// Attempts to insert a class into a class table. Returns null if
// the class was inserted, otherwise returns an existing class with
// the same descriptor and ClassLoader.
- mirror::Class* InsertClass(const char* descriptor, ObjPtr<mirror::Class> klass, size_t hash)
+ ObjPtr<mirror::Class> InsertClass(const char* descriptor,
+ ObjPtr<mirror::Class> klass,
+ size_t hash)
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -597,8 +553,10 @@ class ClassLinker {
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::ObjectArray<mirror::Class>* GetClassRoots() REQUIRES_SHARED(Locks::mutator_lock_) {
- mirror::ObjectArray<mirror::Class>* class_roots = class_roots_.Read();
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ ObjPtr<mirror::ObjectArray<mirror::Class>> GetClassRoots() REQUIRES_SHARED(Locks::mutator_lock_) {
+ ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
+ class_roots_.Read<kReadBarrierOption>();
DCHECK(class_roots != nullptr);
return class_roots;
}
@@ -714,7 +672,7 @@ class ClassLinker {
REQUIRES(!Locks::dex_lock_);
// Get the actual holding class for a copied method. Pretty slow, don't call often.
- mirror::Class* GetHoldingClassOfCopiedMethod(ArtMethod* method)
+ ObjPtr<mirror::Class> GetHoldingClassOfCopiedMethod(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns null if not found.
@@ -818,45 +776,41 @@ class ClassLinker {
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
// For early bootstrapping by Init
- mirror::Class* AllocClass(Thread* self,
- ObjPtr<mirror::Class> java_lang_Class,
- uint32_t class_size)
+ ObjPtr<mirror::Class> AllocClass(Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class,
+ uint32_t class_size)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
- // Alloc* convenience functions to avoid needing to pass in mirror::Class*
- // values that are known to the ClassLinker such as
- // kObjectArrayClass and kJavaLangString etc.
- mirror::Class* AllocClass(Thread* self, uint32_t class_size)
+ // Alloc* convenience functions to avoid needing to pass in ObjPtr<mirror::Class>
+ // values that are known to the ClassLinker such as classes corresponding to
+ // ClassRoot::kObjectArrayClass and ClassRoot::kJavaLangString etc.
+ ObjPtr<mirror::Class> AllocClass(Thread* self, uint32_t class_size)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
- mirror::DexCache* AllocDexCache(ObjPtr<mirror::String>* out_location,
- Thread* self,
- const DexFile& dex_file)
+ ObjPtr<mirror::DexCache> AllocDexCache(/*out*/ ObjPtr<mirror::String>* out_location,
+ Thread* self,
+ const DexFile& dex_file)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
// Used for tests and AppendToBootClassPath.
- mirror::DexCache* AllocAndInitializeDexCache(Thread* self,
- const DexFile& dex_file,
- LinearAlloc* linear_alloc)
+ ObjPtr<mirror::DexCache> AllocAndInitializeDexCache(Thread* self,
+ const DexFile& dex_file,
+ LinearAlloc* linear_alloc)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_)
REQUIRES(!Roles::uninterruptible_);
- mirror::Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!Roles::uninterruptible_);
- mirror::Class* InitializePrimitiveClass(ObjPtr<mirror::Class> primitive_class,
- Primitive::Type type)
+ ObjPtr<mirror::Class> CreatePrimitiveClass(Thread* self, Primitive::Type type)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
- mirror::Class* CreateArrayClass(Thread* self,
- const char* descriptor,
- size_t hash,
- Handle<mirror::ClassLoader> class_loader)
+ ObjPtr<mirror::Class> CreateArrayClass(Thread* self,
+ const char* descriptor,
+ size_t hash,
+ Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
@@ -882,18 +836,14 @@ class ClassLinker {
const DexFile::ClassDef& dex_class_def,
Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
- void LoadClassMembers(Thread* self,
- const DexFile& dex_file,
- const uint8_t* class_data,
- Handle<mirror::Class> klass)
- REQUIRES_SHARED(Locks::mutator_lock_);
- void LoadField(const ClassDataItemIterator& it, Handle<mirror::Class> klass, ArtField* dst)
+ void LoadField(const ClassAccessor::Field& field, Handle<mirror::Class> klass, ArtField* dst)
REQUIRES_SHARED(Locks::mutator_lock_);
void LoadMethod(const DexFile& dex_file,
- const ClassDataItemIterator& it,
- Handle<mirror::Class> klass, ArtMethod* dst)
+ const ClassAccessor::Method& method,
+ Handle<mirror::Class> klass,
+ ArtMethod* dst)
REQUIRES_SHARED(Locks::mutator_lock_);
void FixupStaticTrampolines(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -908,7 +858,7 @@ class ClassLinker {
const char* descriptor,
size_t hash,
Handle<mirror::ClassLoader> class_loader,
- ObjPtr<mirror::Class>* result)
+ /*out*/ ObjPtr<mirror::Class>* result)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
@@ -935,12 +885,32 @@ class ClassLinker {
// Implementation of LookupResolvedType() called when the type was not found in the dex cache.
ObjPtr<mirror::Class> DoLookupResolvedType(dex::TypeIndex type_idx,
+ ObjPtr<mirror::Class> referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::Class> DoLookupResolvedType(dex::TypeIndex type_idx,
ObjPtr<mirror::DexCache> dex_cache,
ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_);
+ // Implementation of ResolveString() called when the string was not found in the dex cache.
+ ObjPtr<mirror::String> DoResolveString(dex::StringIndex string_idx,
+ ObjPtr<mirror::DexCache> dex_cache)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::String> DoResolveString(dex::StringIndex string_idx,
+ Handle<mirror::DexCache> dex_cache)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+ // Implementation of LookupString() called when the string was not found in the dex cache.
+ ObjPtr<mirror::String> DoLookupString(dex::StringIndex string_idx,
+ ObjPtr<mirror::DexCache> dex_cache)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Implementation of ResolveType() called when the type was not found in the dex cache.
ObjPtr<mirror::Class> DoResolveType(dex::TypeIndex type_idx,
+ ObjPtr<mirror::Class> referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
+ ObjPtr<mirror::Class> DoResolveType(dex::TypeIndex type_idx,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_)
@@ -948,10 +918,10 @@ class ClassLinker {
// Finds a class by its descriptor, returning NULL if it isn't wasn't loaded
// by the given 'class_loader'. Uses the provided hash for the descriptor.
- mirror::Class* LookupClass(Thread* self,
- const char* descriptor,
- size_t hash,
- ObjPtr<mirror::ClassLoader> class_loader)
+ ObjPtr<mirror::Class> LookupClass(Thread* self,
+ const char* descriptor,
+ size_t hash,
+ ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -1222,7 +1192,9 @@ class ClassLinker {
// when resolution has occurred. This happens in mirror::Class::SetStatus. As resolution may
// retire a class, the version of the class in the table is returned and this may differ from
// the class passed in.
- mirror::Class* EnsureResolved(Thread* self, const char* descriptor, ObjPtr<mirror::Class> klass)
+ ObjPtr<mirror::Class> EnsureResolved(Thread* self,
+ const char* descriptor,
+ ObjPtr<mirror::Class> klass)
WARN_UNUSED
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);