summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2018-11-14 16:18:18 -0800
committer Mathieu Chartier <mathieuc@google.com> 2018-11-14 16:40:48 -0800
commitbc1e0fab934b7fb03545f08085b109d6508b17d0 (patch)
tree87048ec7cccd78f9819ba16d95539a8deae51659
parent0bcbe9399dfc546db5c81b13979afc85da19d025 (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.cc32
-rw-r--r--runtime/mirror/class-inl.h10
-rw-r--r--runtime/mirror/class.cc8
-rw-r--r--runtime/mirror/class.h1
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() {