diff options
-rw-r--r-- | runtime/art_method-inl.h | 34 | ||||
-rw-r--r-- | runtime/art_method.h | 11 | ||||
-rw-r--r-- | runtime/fault_handler.cc | 2 | ||||
-rw-r--r-- | runtime/thread.cc | 2 |
4 files changed, 26 insertions, 23 deletions
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 74eb7227dc..28540c8437 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); -} - -inline mirror::Class* ArtMethod::GetDeclaringClassNoBarrier() { - return declaring_class_.Read<kWithoutReadBarrier>(); + return declaring_class_.Read<kReadBarrierOption>(&gc_root_source); } +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 @@ inline bool ArtMethod::CASDeclaringClass(mirror::Class* expected_class, // 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 @@ void ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) { 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 @@ inline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor) { } } -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 440e796f46..ce23c2a52b 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -57,11 +57,10 @@ class ArtMethod FINAL { 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 @@ class ArtMethod FINAL { // 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 @@ class ArtMethod FINAL { 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 @@ class ArtMethod FINAL { 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 5345b890a1..5c5abeb0a6 100644 --- a/runtime/fault_handler.cc +++ b/runtime/fault_handler.cc @@ -349,7 +349,7 @@ bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool che // 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 21241d240b..2abcd67c2d 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2704,7 +2704,7 @@ class ReferenceMapVisitor : public StackVisitor { // 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; |