summaryrefslogtreecommitdiff
path: root/runtime/art_field-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/art_field-inl.h')
-rw-r--r--runtime/art_field-inl.h34
1 files changed, 28 insertions, 6 deletions
diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h
index 5f23f1e737..f6a99ac44e 100644
--- a/runtime/art_field-inl.h
+++ b/runtime/art_field-inl.h
@@ -40,15 +40,11 @@ inline bool ArtField::IsProxyField() {
return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass<kVerifyNone>();
}
-// We are only ever allowed to set our own final fields. We do need to be careful since if a
-// structural redefinition occurs during <clinit> we can end up trying to set the non-obsolete
-// class's fields from the obsolete class. This is something we want to allow. This is tested by
-// run-test 2002-virtual-structural-initializing.
+// We are only ever allowed to set our own final fields
inline bool ArtField::CanBeChangedBy(ArtMethod* method) {
ObjPtr<mirror::Class> declaring_class(GetDeclaringClass());
ObjPtr<mirror::Class> referring_class(method->GetDeclaringClass());
- return !IsFinal() || (declaring_class == referring_class) ||
- UNLIKELY(referring_class->IsObsoleteVersionOf(declaring_class));
+ return !IsFinal() || (declaring_class == referring_class);
}
template<ReadBarrierOption kReadBarrierOption>
@@ -64,6 +60,32 @@ inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_clas
declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
}
+template<typename RootVisitorType>
+void ArtField::VisitArrayRoots(RootVisitorType& visitor,
+ uint8_t* start_boundary,
+ uint8_t* end_boundary,
+ LengthPrefixedArray<ArtField>* array) {
+ DCHECK_LE(start_boundary, end_boundary);
+ DCHECK_NE(array->size(), 0u);
+ ArtField* first_field = &array->At(0);
+ DCHECK_LE(static_cast<void*>(end_boundary), static_cast<void*>(first_field + array->size()));
+ static constexpr size_t kFieldSize = sizeof(ArtField);
+ // Confirm the assumption that ArtField size is power of two. It's important
+ // as we assume so below (RoundUp).
+ static_assert(IsPowerOfTwo(kFieldSize));
+ uint8_t* declaring_class =
+ reinterpret_cast<uint8_t*>(first_field) + DeclaringClassOffset().Int32Value();
+ // Jump to the first class to visit.
+ if (declaring_class < start_boundary) {
+ declaring_class += RoundUp(start_boundary - declaring_class, kFieldSize);
+ }
+ while (declaring_class < end_boundary) {
+ visitor.VisitRoot(
+ reinterpret_cast<mirror::CompressedReference<mirror::Object>*>(declaring_class));
+ declaring_class += kFieldSize;
+ }
+}
+
inline MemberOffset ArtField::GetOffsetDuringLinking() {
DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
return MemberOffset(offset_);