Avoid read barriers for ArtMethod::GetDexFile
Shows up in pmd benchmark from Class::FindDeclaredDirectMethod and
Class::FindDeclaredVirtualMethod. There are still calls to
IsProxyMethod that could probably be eliminated.
ReadBarrier::Mark goes from 12.39% to 3.45% according to perf.
Test: test-art-host
Change-Id: I6a4f2fa2d68bf5f393f83b9b70e8d6fcc9dbdaa2
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index a35c7ab..7ec3900 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -244,7 +244,9 @@
}
inline const DexFile* ArtMethod::GetDexFile() {
- return GetDexCache()->GetDexFile();
+ // It is safe to avoid the read barrier here since the dex file is constant, so if we read the
+ // from-space dex file pointer it will be equal to the to-space copy.
+ return GetDexCache<kWithoutReadBarrier>()->GetDexFile();
}
inline const char* ArtMethod::GetDeclaringClassDescriptor() {
@@ -361,9 +363,11 @@
return GetDeclaringClass()->GetClassLoader();
}
+template <ReadBarrierOption kReadBarrierOption>
inline mirror::DexCache* ArtMethod::GetDexCache() {
if (LIKELY(!IsObsolete())) {
- return GetDeclaringClass()->GetDexCache();
+ mirror::Class* klass = GetDeclaringClass<kReadBarrierOption>();
+ return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>();
} else {
DCHECK(!IsProxyMethod());
return GetObsoleteDexCache();
@@ -379,14 +383,13 @@
if (LIKELY(!IsProxyMethod())) {
return this;
}
- mirror::Class* klass = GetDeclaringClass();
ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize(
GetDexCacheResolvedMethods(pointer_size),
GetDexMethodIndex(),
pointer_size);
DCHECK(interface_method != nullptr);
DCHECK_EQ(interface_method,
- Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this));
+ Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
return interface_method;
}
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 17f343d..7217ead 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -563,6 +563,7 @@
mirror::ClassLoader* GetClassLoader() REQUIRES_SHARED(Locks::mutator_lock_);
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
mirror::DexCache* GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
mirror::DexCache* GetObsoleteDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 2fb8d28..6a65e12 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -71,9 +71,10 @@
OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
}
-template<VerifyObjectFlags kVerifyFlags>
+template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline DexCache* Class::GetDexCache() {
- return GetFieldObject<DexCache, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
+ return GetFieldObject<DexCache, kVerifyFlags, kReadBarrierOption>(
+ OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
}
inline uint32_t Class::GetCopiedMethodsStartOffset() {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 7f6aa12..c9f27ad 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -722,7 +722,8 @@
void DumpClass(std::ostream& os, int flags) REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
+ ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
DexCache* GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
// Also updates the dex_cache_strings_ variable from new_dex_cache.