// Returns true if the given class loader derives from BaseDexClassLoader. inlinebool IsInstanceOfBaseDexClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) { return class_loader->InstanceOf(WellKnownClasses::dalvik_system_BaseDexClassLoader.Get());
}
// Returns true if the given class loader is either a PathClassLoader or a DexClassLoader. // (they both have the same behaviour with respect to class lookup order) inlinebool IsPathOrDexClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass(); return (class_loader_class == WellKnownClasses::dalvik_system_PathClassLoader) ||
(class_loader_class == WellKnownClasses::dalvik_system_DexClassLoader);
}
// Returns true if the given class loader is an InMemoryDexClassLoader. inlinebool IsInMemoryDexClassLoader(Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass(); return (class_loader_class == WellKnownClasses::dalvik_system_InMemoryDexClassLoader);
}
// Visit the DexPathList$Element instances in the given classloader with the given visitor. // Constraints on the visitor: // * The visitor should return true to continue visiting more Elements. // * The last argument of the visitor is an out argument of RetType. It will be returned // when the visitor ends the visit (by returning false). // This function assumes that the given classloader is a subclass of BaseDexClassLoader! template <typename Visitor, typename RetType> inline RetType VisitClassLoaderDexElements(Thread* self,
Handle<mirror::ClassLoader> class_loader,
Visitor fn,
RetType defaultReturn)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Object> dex_path_list =
WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList->GetObject(class_loader.Get()); if (dex_path_list != nullptr) { // DexPathList has an array dexElements of Elements[] which each contain a dex file.
ObjPtr<mirror::Object> dex_elements_obj =
WellKnownClasses::dalvik_system_DexPathList_dexElements->GetObject(dex_path_list); // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look // at the mCookie which is a DexFile vector. if (dex_elements_obj != nullptr) {
StackHandleScope<1> hs(self);
Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>()); for (auto element : dex_elements.Iterate<mirror::Object>()) { if (element == nullptr) { // Should never happen, fail. break;
}
RetType ret_value; if (!fn(element, &ret_value)) { return ret_value;
}
}
}
} return defaultReturn;
}
// Visit the DexFiles in the given classloader with the given visitor. // Constraints on the visitor: // * The visitor should return true to continue visiting more DexFiles. // * The last argument of the visitor is an out argument of RetType. It will be returned // when the visitor ends the visit (by returning false). // This function assumes that the given classloader is a subclass of BaseDexClassLoader! template <typename Visitor, typename RetType> inline RetType VisitClassLoaderDexFiles(Thread* self,
Handle<mirror::ClassLoader> class_loader,
Visitor fn,
RetType defaultReturn)
REQUIRES_SHARED(Locks::mutator_lock_) {
ArtField* const cookie_field = WellKnownClasses::dalvik_system_DexFile_cookie;
ArtField* const dex_file_field = WellKnownClasses::dalvik_system_DexPathList__Element_dexFile; if (dex_file_field == nullptr || cookie_field == nullptr) { return defaultReturn;
} auto visit_dex_files = [&](ObjPtr<mirror::Object> element, RetType* ret)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element); if (dex_file != nullptr) {
StackHandleScope<1> hs(self);
Handle<mirror::LongArray> long_array =
hs.NewHandle(cookie_field->GetObject(dex_file)->AsLongArray()); if (long_array == nullptr) { // This should never happen so log a warning.
LOG(WARNING) << "Null DexFile::mCookie";
*ret = defaultReturn; returntrue;
}
int32_t long_array_size = long_array->GetLength(); // First element is the oat file. for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) { const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
long_array->GetWithoutChecks(j)));
RetType ret_value; if (!fn(cp_dex_file, /* out */ &ret_value)) {
*ret = ret_value; returnfalse;
}
}
} returntrue;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.