Add read barrier option to UpdateEntrypoints
Also call this without read barrier for image relocation.
Bug: 26786304
Change-Id: Ia718c1491b54cadb7283c62afc1eb9031a15b4ef
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 74eb722..28540c8 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -41,17 +41,15 @@
namespace art {
+template <ReadBarrierOption kReadBarrierOption>
inline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() {
GcRootSource gc_root_source(this);
- return declaring_class_.Read(&gc_root_source);
+ return declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
}
-inline mirror::Class* ArtMethod::GetDeclaringClassNoBarrier() {
- return declaring_class_.Read<kWithoutReadBarrier>();
-}
-
+template <ReadBarrierOption kReadBarrierOption>
inline mirror::Class* ArtMethod::GetDeclaringClass() {
- mirror::Class* result = GetDeclaringClassUnchecked();
+ mirror::Class* result = GetDeclaringClassUnchecked<kReadBarrierOption>();
if (kIsDebugBuild) {
if (!IsRuntimeMethod()) {
CHECK(result != nullptr) << this;
@@ -79,24 +77,28 @@
// AssertSharedHeld doesn't work in GetAccessFlags, so use a NO_THREAD_SAFETY_ANALYSIS helper.
// TODO: Figure out why ASSERT_SHARED_CAPABILITY doesn't work.
-ALWAYS_INLINE
-static inline void DoGetAccessFlagsHelper(ArtMethod* method) NO_THREAD_SAFETY_ANALYSIS {
- CHECK(method->IsRuntimeMethod() || method->GetDeclaringClass()->IsIdxLoaded() ||
- method->GetDeclaringClass()->IsErroneous());
+template <ReadBarrierOption kReadBarrierOption>
+ALWAYS_INLINE static inline void DoGetAccessFlagsHelper(ArtMethod* method)
+ NO_THREAD_SAFETY_ANALYSIS {
+ CHECK(method->IsRuntimeMethod() ||
+ method->GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() ||
+ method->GetDeclaringClass<kReadBarrierOption>()->IsErroneous());
}
+template <ReadBarrierOption kReadBarrierOption>
inline uint32_t ArtMethod::GetAccessFlags() {
if (kIsDebugBuild) {
Thread* self = Thread::Current();
if (!Locks::mutator_lock_->IsSharedHeld(self)) {
ScopedObjectAccess soa(self);
- CHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() ||
- GetDeclaringClass()->IsErroneous());
+ CHECK(IsRuntimeMethod() ||
+ GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() ||
+ GetDeclaringClass<kReadBarrierOption>()->IsErroneous());
} else {
// We cannot use SOA in this case. We might be holding the lock, but may not be in the
// runnable state (e.g., during GC).
Locks::mutator_lock_->AssertSharedHeld(self);
- DoGetAccessFlagsHelper(this);
+ DoGetAccessFlagsHelper<kReadBarrierOption>(this);
}
}
return access_flags_;
@@ -469,7 +471,7 @@
template <typename Visitor>
inline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor) {
- mirror::Class* old_class = GetDeclaringClassNoBarrier();
+ mirror::Class* old_class = GetDeclaringClassUnchecked<kWithoutReadBarrier>();
mirror::Class* new_class = visitor(old_class);
if (old_class != new_class) {
SetDeclaringClass(new_class);
@@ -486,9 +488,9 @@
}
}
-template <typename Visitor>
+template <ReadBarrierOption kReadBarrierOption, typename Visitor>
inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor) {
- if (IsNative()) {
+ if (IsNative<kReadBarrierOption>()) {
const void* old_native_code = GetEntryPointFromJni();
const void* new_native_code = visitor(old_native_code);
if (old_native_code != new_native_code) {
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 440e796..ce23c2a 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -57,11 +57,10 @@
jobject jlr_method)
SHARED_REQUIRES(Locks::mutator_lock_);
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
ALWAYS_INLINE mirror::Class* GetDeclaringClass() SHARED_REQUIRES(Locks::mutator_lock_);
- ALWAYS_INLINE mirror::Class* GetDeclaringClassNoBarrier()
- SHARED_REQUIRES(Locks::mutator_lock_);
-
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
ALWAYS_INLINE mirror::Class* GetDeclaringClassUnchecked()
SHARED_REQUIRES(Locks::mutator_lock_);
@@ -77,6 +76,7 @@
// Note: GetAccessFlags acquires the mutator lock in debug mode to check that it is not called for
// a proxy method.
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
ALWAYS_INLINE uint32_t GetAccessFlags();
void SetAccessFlags(uint32_t new_access_flags) {
@@ -154,8 +154,9 @@
return (GetAccessFlags() & kAccDefault) != 0;
}
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
bool IsNative() {
- return (GetAccessFlags() & kAccNative) != 0;
+ return (GetAccessFlags<kReadBarrierOption>() & kAccNative) != 0;
}
bool IsFastNative() {
@@ -485,7 +486,7 @@
SHARED_REQUIRES(Locks::mutator_lock_);
// Update entry points by passing them through the visitor.
- template <typename Visitor>
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
ALWAYS_INLINE void UpdateEntrypoints(const Visitor& visitor);
protected:
diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc
index 5345b89..5c5abeb 100644
--- a/runtime/fault_handler.cc
+++ b/runtime/fault_handler.cc
@@ -349,7 +349,7 @@
// Check that the class pointer inside the object is not null and is aligned.
// TODO: Method might be not a heap address, and GetClass could fault.
// No read barrier because method_obj may not be a real object.
- mirror::Class* cls = method_obj->GetDeclaringClassNoBarrier();
+ mirror::Class* cls = method_obj->GetDeclaringClassUnchecked<kWithoutReadBarrier>();
if (cls == nullptr) {
VLOG(signals) << "not a class";
return false;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 21241d2..2abcd67 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2704,7 +2704,7 @@
// Visiting the declaring class is necessary so that we don't unload the class of a method that
// is executing. We need to ensure that the code stays mapped.
void VisitDeclaringClass(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_) {
- mirror::Class* klass = method->GetDeclaringClassNoBarrier();
+ mirror::Class* klass = method->GetDeclaringClassUnchecked<kWithoutReadBarrier>();
// klass can be null for runtime methods.
if (klass != nullptr) {
mirror::Object* new_ref = klass;