Move ArtField to ObjPtr
Added EXPECT_OBJ_PTR_EQ and variants to gtests.
Fixed moving GC bugs in:
ClassLinker::CreatePathClassLoader
ClassLinkerTest: StaticFields
ObjPtr Decode call sites: 186 -> 181.
Some tests fail due to ResolvedFieldAccessTest, will fix in follow
up CL.
Bug: 31113334
Test: test-art-host CC baker
Change-Id: I8b266ad00f3c20c8cbe7cfdf280d175083df0b88
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 5a5f717..8aebd6e 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -341,13 +341,13 @@
// Don't forget about primitive types.
// Object[] = int[] --> false
//
-inline bool Class::IsArrayAssignableFromArray(Class* src) {
+inline bool Class::IsArrayAssignableFromArray(ObjPtr<Class> src) {
DCHECK(IsArrayClass()) << PrettyClass(this);
DCHECK(src->IsArrayClass()) << PrettyClass(src);
return GetComponentType()->IsAssignableFrom(src->GetComponentType());
}
-inline bool Class::IsAssignableFromArray(Class* src) {
+inline bool Class::IsAssignableFromArray(ObjPtr<Class> src) {
DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
DCHECK(src->IsArrayClass()) << PrettyClass(src);
if (!IsArrayClass()) {
@@ -362,8 +362,10 @@
}
template <bool throw_on_failure, bool use_referrers_cache>
-inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field,
- uint32_t field_idx, DexCache* dex_cache) {
+inline bool Class::ResolvedFieldAccessTest(Class* access_to,
+ ArtField* field,
+ uint32_t field_idx,
+ DexCache* dex_cache) {
DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
if (UNLIKELY(!this->CanAccess(access_to))) {
// The referrer class can't access the field's declaring class but may still be able
@@ -447,14 +449,20 @@
return false;
}
-inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field,
- DexCache* dex_cache, uint32_t field_idx) {
- return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
+inline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to,
+ ArtField* field,
+ ObjPtr<DexCache> dex_cache,
+ uint32_t field_idx) {
+ return ResolvedFieldAccessTest<false, false>(access_to.Decode(),
+ field,
+ field_idx,
+ dex_cache.Decode());
}
-inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field,
+inline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to,
+ ArtField* field,
uint32_t field_idx) {
- return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
+ return ResolvedFieldAccessTest<true, true>(access_to.Decode(), field, field_idx, nullptr);
}
inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method,
@@ -469,10 +477,10 @@
nullptr);
}
-inline bool Class::IsSubClass(Class* klass) {
+inline bool Class::IsSubClass(ObjPtr<Class> klass) {
DCHECK(!IsInterface()) << PrettyClass(this);
DCHECK(!IsArrayClass()) << PrettyClass(this);
- Class* current = this;
+ ObjPtr<Class> current = this;
do {
if (current == klass) {
return true;
@@ -1032,7 +1040,7 @@
return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr;
}
-inline bool Class::IsAssignableFrom(Class* src) {
+inline bool Class::IsAssignableFrom(ObjPtr<Class> src) {
DCHECK(src != nullptr);
if (this == src) {
// Can always assign to things of the same type.
@@ -1113,6 +1121,34 @@
}
}
+inline bool Class::CanAccess(ObjPtr<Class> that) {
+ return that->IsPublic() || this->IsInSamePackage(that);
+}
+
+
+inline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags) {
+ // Classes can access all of their own members
+ if (this == access_to) {
+ return true;
+ }
+ // Public members are trivially accessible
+ if (member_flags & kAccPublic) {
+ return true;
+ }
+ // Private members are trivially not accessible
+ if (member_flags & kAccPrivate) {
+ return false;
+ }
+ // Check for protected access from a sub-class, which may or may not be in the same package.
+ if (member_flags & kAccProtected) {
+ if (!this->IsInterface() && this->IsSubClass(access_to)) {
+ return true;
+ }
+ }
+ // Allow protected access from other classes in the same package.
+ return this->IsInSamePackage(access_to);
+}
+
} // namespace mirror
} // namespace art