diff options
| author | 2018-11-14 16:18:18 -0800 | |
|---|---|---|
| committer | 2018-11-14 16:40:48 -0800 | |
| commit | bc1e0fab934b7fb03545f08085b109d6508b17d0 (patch) | |
| tree | 87048ec7cccd78f9819ba16d95539a8deae51659 | |
| parent | 0bcbe9399dfc546db5c81b13979afc85da19d025 (diff) | |
Reduce class loader updating overhead.
Avoid unnecessary read barrier for comparing class loader agianst
null. Avoid transaction check.
Deleted the helper class to simplify the code.
The time goes from ~3.8ms to ~2.9ms on Maps.
Test: test-art-host
Bug: 116052292
Change-Id: I4a966a9bb39400ba58d7cf3e0b2c8ab4747d65ed
| -rw-r--r-- | runtime/class_linker.cc | 32 | ||||
| -rw-r--r-- | runtime/mirror/class-inl.h | 10 | ||||
| -rw-r--r-- | runtime/mirror/class.cc | 8 | ||||
| -rw-r--r-- | runtime/mirror/class.h | 1 |
4 files changed, 21 insertions, 30 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index cc4f56cc06..63e7915b40 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1543,26 +1543,6 @@ void AppImageLoadingHelper::HandleAppImageStrings(gc::space::ImageSpace* space) } } -// Update the class loader. Should only be used on classes in the image space. -class UpdateClassLoaderVisitor { - public: - UpdateClassLoaderVisitor(gc::space::ImageSpace* space, ObjPtr<mirror::ClassLoader> class_loader) - : space_(space), - class_loader_(class_loader) {} - - bool operator()(ObjPtr<mirror::Class> klass) const REQUIRES_SHARED(Locks::mutator_lock_) { - // Do not update class loader for boot image classes where the app image - // class loader is only the initiating loader but not the defining loader. - if (klass->GetClassLoader() != nullptr) { - klass->SetClassLoader(class_loader_); - } - return true; - } - - gc::space::ImageSpace* const space_; - ObjPtr<mirror::ClassLoader> const class_loader_; -}; - static std::unique_ptr<const DexFile> OpenOatDexFile(const OatFile* oat_file, const char* location, std::string* error_msg) @@ -2036,9 +2016,17 @@ bool ClassLinker::AddImageSpace( ScopedTrace trace("AppImage:UpdateClassLoaders"); // Update class loader and resolved strings. If added_class_table is false, the resolved // strings were forwarded UpdateAppImageClassLoadersAndDexCaches. - UpdateClassLoaderVisitor visitor(space, class_loader.Get()); + ObjPtr<mirror::ClassLoader> loader(class_loader.Get()); for (const ClassTable::TableSlot& root : temp_set) { - visitor(root.Read()); + // Note: We probably don't need the read barrier unless we copy the app image objects into + // the region space. + ObjPtr<mirror::Class> klass(root.Read()); + // Do not update class loader for boot image classes where the app image + // class loader is only the initiating loader but not the defining loader. + // Avoid read barrier since we are comparing against null. + if (klass->GetClassLoader<kDefaultVerifyFlags, kWithoutReadBarrier>() != nullptr) { + klass->SetClassLoader</*kCheckTransaction=*/ false>(loader); + } } } diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 6b9ba8c8a2..185ae3b2ac 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -1102,6 +1102,16 @@ inline bool Class::CannotBeAssignedFromOtherTypes() { return component->IsPrimitive() || component->CannotBeAssignedFromOtherTypes(); } +template <bool kCheckTransaction> +inline void Class::SetClassLoader(ObjPtr<ClassLoader> new_class_loader) { + if (kCheckTransaction && Runtime::Current()->IsActiveTransaction()) { + SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader); + } else { + DCHECK(!Runtime::Current()->IsActiveTransaction()); + SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader); + } +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index e33e407149..83d76a98cd 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -427,14 +427,6 @@ bool Class::IsThrowableClass() { return GetClassRoot<mirror::Throwable>()->IsAssignableFrom(this); } -void Class::SetClassLoader(ObjPtr<ClassLoader> new_class_loader) { - if (Runtime::Current()->IsActiveTransaction()) { - SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader); - } else { - SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader); - } -} - template <typename SignatureType> static inline ArtMethod* FindInterfaceMethodWithSignature(ObjPtr<Class> klass, const StringPiece& name, diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index bb54b3d33f..c38cc86c59 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -628,6 +628,7 @@ class MANAGED Class final : public Object { ReadBarrierOption kReadBarrierOption = kWithReadBarrier> ClassLoader* GetClassLoader() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_); + template <bool kCheckTransaction = true> void SetClassLoader(ObjPtr<ClassLoader> new_cl) REQUIRES_SHARED(Locks::mutator_lock_); static constexpr MemberOffset DexCacheOffset() { |