diff options
| -rw-r--r-- | runtime/art_field-inl.h | 3 | ||||
| -rw-r--r-- | runtime/art_field.h | 1 | ||||
| -rw-r--r-- | runtime/art_method-inl.h | 19 | ||||
| -rw-r--r-- | runtime/art_method.h | 3 | ||||
| -rw-r--r-- | runtime/class_linker-inl.h | 28 | ||||
| -rw-r--r-- | runtime/class_linker.cc | 27 | ||||
| -rw-r--r-- | runtime/class_linker.h | 1 | ||||
| -rw-r--r-- | runtime/mirror/class-inl.h | 13 | ||||
| -rw-r--r-- | runtime/mirror/class.h | 2 |
9 files changed, 52 insertions, 45 deletions
diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h index 98d33453e2..a102858acc 100644 --- a/runtime/art_field-inl.h +++ b/runtime/art_field-inl.h @@ -33,9 +33,10 @@ namespace art { +template<ReadBarrierOption kReadBarrierOption> inline mirror::Class* ArtField::GetDeclaringClass() { GcRootSource gc_root_source(this); - mirror::Class* result = declaring_class_.Read(&gc_root_source); + mirror::Class* result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source); DCHECK(result != nullptr); DCHECK(result->IsLoaded() || result->IsErroneous()) << result->GetStatus(); return result; diff --git a/runtime/art_field.h b/runtime/art_field.h index b64b70fa8d..aaccbf3699 100644 --- a/runtime/art_field.h +++ b/runtime/art_field.h @@ -41,6 +41,7 @@ class ArtField FINAL { public: ArtField(); + template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> mirror::Class* GetDeclaringClass() SHARED_REQUIRES(Locks::mutator_lock_); void SetDeclaringClass(mirror::Class *new_declaring_class) diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 7647ad6e57..26450c41c7 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -395,8 +395,9 @@ inline mirror::DexCache* ArtMethod::GetDexCache() { return GetDeclaringClass()->GetDexCache(); } +template<ReadBarrierOption kReadBarrierOption> inline bool ArtMethod::IsProxyMethod() { - return GetDeclaringClass()->IsProxyClass(); + return GetDeclaringClass<kReadBarrierOption>()->IsProxyClass(); } inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(size_t pointer_size) { @@ -438,24 +439,24 @@ inline mirror::Class* ArtMethod::GetReturnType(bool resolve, size_t ptr_size) { return type; } -template<typename RootVisitorType> +template<ReadBarrierOption kReadBarrierOption, typename RootVisitorType> void ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) { - ArtMethod* interface_method = nullptr; - mirror::Class* klass = declaring_class_.Read(); - if (LIKELY(klass != nullptr)) { + if (LIKELY(!declaring_class_.IsNull())) { + visitor.VisitRoot(declaring_class_.AddressWithoutBarrier()); + mirror::Class* klass = declaring_class_.Read<kReadBarrierOption>(); if (UNLIKELY(klass->IsProxyClass())) { // For normal methods, dex cache shortcuts will be visited through the declaring class. // However, for proxies we need to keep the interface method alive, so we visit its roots. - interface_method = mirror::DexCache::GetElementPtrSize( + 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<kReadBarrierOption>( + klass, this)); interface_method->VisitRoots(visitor, pointer_size); } - visitor.VisitRoot(declaring_class_.AddressWithoutBarrier()); // We know we don't have profiling information if the class hasn't been verified. Note // that this check also ensures the IsNative call can be made, as IsNative expects a fully // created class (and not a retired one). @@ -463,7 +464,7 @@ void ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) { // Runtime methods and native methods use the same field as the profiling info for // storing their own data (jni entrypoint for native methods, and ImtConflictTable for // some runtime methods). - if (!IsNative() && !IsRuntimeMethod()) { + if (!IsNative<kReadBarrierOption>() && !IsRuntimeMethod()) { ProfilingInfo* profiling_info = GetProfilingInfo(pointer_size); if (profiling_info != nullptr) { profiling_info->VisitRoots(visitor); diff --git a/runtime/art_method.h b/runtime/art_method.h index a012a5a9ca..2b025f8c62 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -340,6 +340,7 @@ class ArtMethod FINAL { return (GetAccessFlags() & kAccSynthetic) != 0; } + template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> bool IsProxyMethod() SHARED_REQUIRES(Locks::mutator_lock_); bool SkipAccessChecks() { @@ -564,7 +565,7 @@ class ArtMethod FINAL { SHARED_REQUIRES(Locks::mutator_lock_); // NO_THREAD_SAFETY_ANALYSIS since we don't know what the callback requires. - template<typename RootVisitorType> + template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename RootVisitorType> void VisitRoots(RootVisitorType& visitor, size_t pointer_size) NO_THREAD_SAFETY_ANALYSIS; const DexFile* GetDexFile() SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index f3e260be56..f2575f702f 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -225,6 +225,34 @@ inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root) return klass; } +template<ReadBarrierOption kReadBarrierOption> +ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, ArtMethod* proxy_method) { + DCHECK(proxy_class->IsProxyClass()); + DCHECK(proxy_method->IsProxyMethod<kReadBarrierOption>()); + { + Thread* const self = Thread::Current(); + ReaderMutexLock mu(self, dex_lock_); + // Locate the dex cache of the original interface/Object + for (const DexCacheData& data : dex_caches_) { + if (!self->IsJWeakCleared(data.weak_root) && + proxy_method->HasSameDexCacheResolvedTypes(data.resolved_types, + image_pointer_size_)) { + mirror::DexCache* dex_cache = down_cast<mirror::DexCache*>( + self->DecodeJObject(data.weak_root)); + if (dex_cache != nullptr) { + ArtMethod* resolved_method = dex_cache->GetResolvedMethod( + proxy_method->GetDexMethodIndex(), image_pointer_size_); + CHECK(resolved_method != nullptr); + return resolved_method; + } + } + } + } + LOG(FATAL) << "Didn't find dex cache for " << PrettyClass(proxy_class) << " " + << PrettyMethod(proxy_method); + UNREACHABLE(); +} + } // namespace art #endif // ART_RUNTIME_CLASS_LINKER_INL_H_ diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index db0e9ac9c4..fe7448fa25 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4280,33 +4280,6 @@ std::string ClassLinker::GetDescriptorForProxy(mirror::Class* proxy_class) { return DotToDescriptor(name->ToModifiedUtf8().c_str()); } -ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, ArtMethod* proxy_method) { - DCHECK(proxy_class->IsProxyClass()); - DCHECK(proxy_method->IsProxyMethod()); - { - Thread* const self = Thread::Current(); - ReaderMutexLock mu(self, dex_lock_); - // Locate the dex cache of the original interface/Object - for (const DexCacheData& data : dex_caches_) { - if (!self->IsJWeakCleared(data.weak_root) && - proxy_method->HasSameDexCacheResolvedTypes(data.resolved_types, - image_pointer_size_)) { - mirror::DexCache* dex_cache = down_cast<mirror::DexCache*>( - self->DecodeJObject(data.weak_root)); - if (dex_cache != nullptr) { - ArtMethod* resolved_method = dex_cache->GetResolvedMethod( - proxy_method->GetDexMethodIndex(), image_pointer_size_); - CHECK(resolved_method != nullptr); - return resolved_method; - } - } - } - } - LOG(FATAL) << "Didn't find dex cache for " << PrettyClass(proxy_class) << " " - << PrettyMethod(proxy_method); - UNREACHABLE(); -} - void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out) { // Create constructor for Proxy that must initialize the method. CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 18u); diff --git a/runtime/class_linker.h b/runtime/class_linker.h index cd1ca7f15a..ca5af19976 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -483,6 +483,7 @@ class ClassLinker { SHARED_REQUIRES(Locks::mutator_lock_); std::string GetDescriptorForProxy(mirror::Class* proxy_class) SHARED_REQUIRES(Locks::mutator_lock_); + template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> ArtMethod* FindMethodForProxy(mirror::Class* proxy_class, ArtMethod* proxy_method) REQUIRES(!dex_lock_) SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index fcdfc88495..cefd9f0315 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -532,7 +532,7 @@ template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() { Class* super_class = GetSuperClass<kVerifyFlags, kReadBarrierOption>(); return (super_class != nullptr) - ? MemberOffset(RoundUp(super_class->GetObjectSize(), + ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags, kReadBarrierOption>(), sizeof(mirror::HeapReference<mirror::Object>))) : ClassOffset(); } @@ -778,7 +778,8 @@ inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) } if (kVisitNativeRoots) { // Since this class is reachable, we must also visit the associated roots when we scan it. - VisitNativeRoots(visitor, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); + VisitNativeRoots<kReadBarrierOption>( + visitor, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); } } @@ -917,24 +918,24 @@ inline GcRoot<String>* Class::GetDexCacheStrings() { return GetFieldPtr<GcRoot<String>*>(DexCacheStringsOffset()); } -template<class Visitor> +template<ReadBarrierOption kReadBarrierOption, class Visitor> void mirror::Class::VisitNativeRoots(Visitor& visitor, size_t pointer_size) { for (ArtField& field : GetSFieldsUnchecked()) { // Visit roots first in case the declaring class gets moved. field.VisitRoots(visitor); if (kIsDebugBuild && IsResolved()) { - CHECK_EQ(field.GetDeclaringClass(), this) << GetStatus(); + CHECK_EQ(field.GetDeclaringClass<kReadBarrierOption>(), this) << GetStatus(); } } for (ArtField& field : GetIFieldsUnchecked()) { // Visit roots first in case the declaring class gets moved. field.VisitRoots(visitor); if (kIsDebugBuild && IsResolved()) { - CHECK_EQ(field.GetDeclaringClass(), this) << GetStatus(); + CHECK_EQ(field.GetDeclaringClass<kReadBarrierOption>(), this) << GetStatus(); } } for (ArtMethod& method : GetMethods(pointer_size)) { - method.VisitRoots(visitor, pointer_size); + method.VisitRoots<kReadBarrierOption>(visitor, pointer_size); } } diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index 8c20fa680f..5235a3e8df 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -1156,7 +1156,7 @@ class MANAGED Class FINAL : public Object { // Visit native roots visits roots which are keyed off the native pointers such as ArtFields and // ArtMethods. - template<class Visitor> + template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier, class Visitor> void VisitNativeRoots(Visitor& visitor, size_t pointer_size) SHARED_REQUIRES(Locks::mutator_lock_); |