Move ArtFields and ArtMethods to be a length prefixed array
Fixes race conditions between changing method and fields arrays
being seen in the wrong order by the GC.
Bug: 22832610
Change-Id: Ia21d6698f73ba207a6392c3d6b9be2658933073f
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 6568487..887e204 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -28,6 +28,7 @@
#include "dex_file.h"
#include "gc/heap-inl.h"
#include "iftable.h"
+#include "length_prefixed_array.h"
#include "object_array-inl.h"
#include "read_barrier-inl.h"
#include "reference-inl.h"
@@ -61,25 +62,28 @@
return GetFieldObject<DexCache, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
}
-inline ArtMethod* Class::GetDirectMethodsPtr() {
+inline LengthPrefixedArray<ArtMethod>* Class::GetDirectMethodsPtr() {
DCHECK(IsLoaded() || IsErroneous());
return GetDirectMethodsPtrUnchecked();
}
-inline ArtMethod* Class::GetDirectMethodsPtrUnchecked() {
- return reinterpret_cast<ArtMethod*>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_)));
+inline LengthPrefixedArray<ArtMethod>* Class::GetDirectMethodsPtrUnchecked() {
+ return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(
+ GetField64(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_)));
}
-inline ArtMethod* Class::GetVirtualMethodsPtrUnchecked() {
- return reinterpret_cast<ArtMethod*>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_)));
+inline LengthPrefixedArray<ArtMethod>* Class::GetVirtualMethodsPtrUnchecked() {
+ return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(
+ GetField64(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_)));
}
-inline void Class::SetDirectMethodsPtr(ArtMethod* new_direct_methods) {
+inline void Class::SetDirectMethodsPtr(LengthPrefixedArray<ArtMethod>* new_direct_methods) {
DCHECK(GetDirectMethodsPtrUnchecked() == nullptr);
SetDirectMethodsPtrUnchecked(new_direct_methods);
}
-inline void Class::SetDirectMethodsPtrUnchecked(ArtMethod* new_direct_methods) {
+inline void Class::SetDirectMethodsPtrUnchecked(
+ LengthPrefixedArray<ArtMethod>* new_direct_methods) {
SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_),
reinterpret_cast<uint64_t>(new_direct_methods));
}
@@ -88,25 +92,23 @@
CheckPointerSize(pointer_size);
auto* methods = GetDirectMethodsPtrUnchecked();
DCHECK(methods != nullptr);
- return reinterpret_cast<ArtMethod*>(reinterpret_cast<uintptr_t>(methods) +
- ArtMethod::ObjectSize(pointer_size) * i);
+ return &methods->At(i, ArtMethod::ObjectSize(pointer_size));
}
inline ArtMethod* Class::GetDirectMethod(size_t i, size_t pointer_size) {
CheckPointerSize(pointer_size);
auto* methods = GetDirectMethodsPtr();
DCHECK(methods != nullptr);
- return reinterpret_cast<ArtMethod*>(reinterpret_cast<uintptr_t>(methods) +
- ArtMethod::ObjectSize(pointer_size) * i);
+ return &methods->At(i, ArtMethod::ObjectSize(pointer_size));
}
template<VerifyObjectFlags kVerifyFlags>
-inline ArtMethod* Class::GetVirtualMethodsPtr() {
+inline LengthPrefixedArray<ArtMethod>* Class::GetVirtualMethodsPtr() {
DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
return GetVirtualMethodsPtrUnchecked();
}
-inline void Class::SetVirtualMethodsPtr(ArtMethod* new_virtual_methods) {
+inline void Class::SetVirtualMethodsPtr(LengthPrefixedArray<ArtMethod>* new_virtual_methods) {
// TODO: we reassign virtual methods to grow the table for miranda
// methods.. they should really just be assigned once.
SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_),
@@ -129,10 +131,9 @@
inline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, size_t pointer_size) {
CheckPointerSize(pointer_size);
- auto* methods = GetVirtualMethodsPtrUnchecked();
+ LengthPrefixedArray<ArtMethod>* methods = GetVirtualMethodsPtrUnchecked();
DCHECK(methods != nullptr);
- return reinterpret_cast<ArtMethod*>(reinterpret_cast<uintptr_t>(methods) +
- ArtMethod::ObjectSize(pointer_size) * i);
+ return &methods->At(i, ArtMethod::ObjectSize(pointer_size));
}
inline PointerArray* Class::GetVTable() {
@@ -423,9 +424,9 @@
SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
}
-inline ArtField* Class::GetIFields() {
+inline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtr() {
DCHECK(IsLoaded() || IsErroneous());
- return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+ return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
}
inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
@@ -458,46 +459,44 @@
return MemberOffset(base);
}
-inline void Class::SetIFields(ArtField* new_ifields) {
- DCHECK(GetIFieldsUnchecked() == nullptr);
+inline void Class::SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields) {
+ DCHECK(GetIFieldsPtrUnchecked() == nullptr);
return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
}
-inline void Class::SetIFieldsUnchecked(ArtField* new_ifields) {
+inline void Class::SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_ifields) {
SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
}
-inline ArtField* Class::GetSFieldsUnchecked() {
- return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+inline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtrUnchecked() {
+ return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
}
-inline ArtField* Class::GetIFieldsUnchecked() {
- return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+inline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtrUnchecked() {
+ return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
}
-inline ArtField* Class::GetSFields() {
+inline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtr() {
DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
- return GetSFieldsUnchecked();
+ return GetSFieldsPtrUnchecked();
}
-inline void Class::SetSFields(ArtField* new_sfields) {
+inline void Class::SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields) {
DCHECK((IsRetired() && new_sfields == nullptr) ||
GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
}
-inline void Class::SetSFieldsUnchecked(ArtField* new_sfields) {
+inline void Class::SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields) {
SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
}
inline ArtField* Class::GetStaticField(uint32_t i) {
- DCHECK_LT(i, NumStaticFields());
- return &GetSFields()[i];
+ return &GetSFieldsPtr()->At(i);
}
inline ArtField* Class::GetInstanceField(uint32_t i) {
- DCHECK_LT(i, NumInstanceFields());
- return &GetIFields()[i];
+ return &GetIFieldsPtr()->At(i);
}
template<VerifyObjectFlags kVerifyFlags>
@@ -813,85 +812,54 @@
template<class Visitor>
void mirror::Class::VisitNativeRoots(Visitor& visitor, size_t pointer_size) {
- ArtField* const sfields = GetSFieldsUnchecked();
- // Since we visit class roots while we may be writing these fields, check against null.
- if (sfields != nullptr) {
- for (size_t i = 0, count = NumStaticFields(); i < count; ++i) {
- auto* f = &sfields[i];
- // Visit roots first in case the declaring class gets moved.
- f->VisitRoots(visitor);
- if (kIsDebugBuild && IsResolved()) {
- CHECK_EQ(f->GetDeclaringClass(), this) << GetStatus();
- }
+ 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();
}
}
- ArtField* const ifields = GetIFieldsUnchecked();
- if (ifields != nullptr) {
- for (size_t i = 0, count = NumInstanceFields(); i < count; ++i) {
- auto* f = &ifields[i];
- // Visit roots first in case the declaring class gets moved.
- f->VisitRoots(visitor);
- if (kIsDebugBuild && IsResolved()) {
- CHECK_EQ(f->GetDeclaringClass(), 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();
}
}
- // We may see GetDirectMethodsPtr() == null with NumDirectMethods() != 0 if the root marking
- // thread reads a null DirectMethodsBegin() but a non null DirectMethodsBegin() due to a race
- // SetDirectMethodsPtr from class linking. Same for virtual methods.
- // In this case, it is safe to avoid marking the roots since we must be either the CC or CMS. If
- // we are CMS then the roots are already marked through other sources, otherwise the roots are
- // already marked due to the to-space invariant.
- // Unchecked versions since we may visit roots of classes that aren't yet loaded.
- if (GetDirectMethodsPtrUnchecked() != nullptr) {
- for (auto& m : GetDirectMethods(pointer_size)) {
- m.VisitRoots(visitor);
- }
+ for (ArtMethod& method : GetDirectMethods(pointer_size)) {
+ method.VisitRoots(visitor);
}
- if (GetVirtualMethodsPtrUnchecked() != nullptr) {
- for (auto& m : GetVirtualMethods(pointer_size)) {
- m.VisitRoots(visitor);
- }
+ for (ArtMethod& method : GetVirtualMethods(pointer_size)) {
+ method.VisitRoots(visitor);
}
}
-inline StrideIterator<ArtMethod> Class::DirectMethodsBegin(size_t pointer_size) {
- CheckPointerSize(pointer_size);
- auto* methods = GetDirectMethodsPtrUnchecked();
- auto stride = ArtMethod::ObjectSize(pointer_size);
- return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods), stride);
-}
-
-inline StrideIterator<ArtMethod> Class::DirectMethodsEnd(size_t pointer_size) {
- CheckPointerSize(pointer_size);
- auto* methods = GetDirectMethodsPtrUnchecked();
- auto stride = ArtMethod::ObjectSize(pointer_size);
- auto count = NumDirectMethods();
- return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods) + stride * count, stride);
-}
-
inline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(size_t pointer_size) {
CheckPointerSize(pointer_size);
- return MakeIterationRange(DirectMethodsBegin(pointer_size), DirectMethodsEnd(pointer_size));
-}
-
-inline StrideIterator<ArtMethod> Class::VirtualMethodsBegin(size_t pointer_size) {
- CheckPointerSize(pointer_size);
- auto* methods = GetVirtualMethodsPtrUnchecked();
- auto stride = ArtMethod::ObjectSize(pointer_size);
- return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods), stride);
-}
-
-inline StrideIterator<ArtMethod> Class::VirtualMethodsEnd(size_t pointer_size) {
- CheckPointerSize(pointer_size);
- auto* methods = GetVirtualMethodsPtrUnchecked();
- auto stride = ArtMethod::ObjectSize(pointer_size);
- auto count = NumVirtualMethods();
- return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods) + stride * count, stride);
+ return MakeIterationRangeFromLengthPrefixedArray(GetDirectMethodsPtrUnchecked(),
+ ArtMethod::ObjectSize(pointer_size));
}
inline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods(size_t pointer_size) {
- return MakeIterationRange(VirtualMethodsBegin(pointer_size), VirtualMethodsEnd(pointer_size));
+ CheckPointerSize(pointer_size);
+ return MakeIterationRangeFromLengthPrefixedArray(GetVirtualMethodsPtrUnchecked(),
+ ArtMethod::ObjectSize(pointer_size));
+}
+
+inline IterationRange<StrideIterator<ArtField>> Class::GetIFields() {
+ return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr(), sizeof(ArtField));
+}
+
+inline IterationRange<StrideIterator<ArtField>> Class::GetSFields() {
+ return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr(), sizeof(ArtField));
+}
+
+inline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() {
+ return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked(), sizeof(ArtField));
+}
+
+inline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() {
+ return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked(), sizeof(ArtField));
}
inline MemberOffset Class::EmbeddedImTableOffset(size_t pointer_size) {
@@ -940,6 +908,26 @@
}
}
+inline uint32_t Class::NumDirectMethods() {
+ LengthPrefixedArray<ArtMethod>* arr = GetDirectMethodsPtrUnchecked();
+ return arr != nullptr ? arr->Length() : 0u;
+}
+
+inline uint32_t Class::NumVirtualMethods() {
+ LengthPrefixedArray<ArtMethod>* arr = GetVirtualMethodsPtrUnchecked();
+ return arr != nullptr ? arr->Length() : 0u;
+}
+
+inline uint32_t Class::NumInstanceFields() {
+ LengthPrefixedArray<ArtField>* arr = GetIFieldsPtrUnchecked();
+ return arr != nullptr ? arr->Length() : 0u;
+}
+
+inline uint32_t Class::NumStaticFields() {
+ LengthPrefixedArray<ArtField>* arr = GetSFieldsPtrUnchecked();
+ return arr != nullptr ? arr->Length() : 0u;
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index d95bcd8..f138936 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -41,7 +41,7 @@
class ArtMethod;
struct ClassOffsets;
template<class T> class Handle;
-template<class T> class Handle;
+template<typename T> class LengthPrefixedArray;
class Signature;
class StringPiece;
template<size_t kNumReferences> class PACKED(4) StackHandleScope;
@@ -656,21 +656,15 @@
// Also updates the dex_cache_strings_ variable from new_dex_cache.
void SetDexCache(DexCache* new_dex_cache) SHARED_REQUIRES(Locks::mutator_lock_);
- ALWAYS_INLINE StrideIterator<ArtMethod> DirectMethodsBegin(size_t pointer_size)
- SHARED_REQUIRES(Locks::mutator_lock_);
-
- ALWAYS_INLINE StrideIterator<ArtMethod> DirectMethodsEnd(size_t pointer_size)
- SHARED_REQUIRES(Locks::mutator_lock_);
-
ALWAYS_INLINE IterationRange<StrideIterator<ArtMethod>> GetDirectMethods(size_t pointer_size)
SHARED_REQUIRES(Locks::mutator_lock_);
- ArtMethod* GetDirectMethodsPtr() SHARED_REQUIRES(Locks::mutator_lock_);
+ LengthPrefixedArray<ArtMethod>* GetDirectMethodsPtr() SHARED_REQUIRES(Locks::mutator_lock_);
- void SetDirectMethodsPtr(ArtMethod* new_direct_methods)
+ void SetDirectMethodsPtr(LengthPrefixedArray<ArtMethod>* new_direct_methods)
SHARED_REQUIRES(Locks::mutator_lock_);
// Used by image writer.
- void SetDirectMethodsPtrUnchecked(ArtMethod* new_direct_methods)
+ void SetDirectMethodsPtrUnchecked(LengthPrefixedArray<ArtMethod>* new_direct_methods)
SHARED_REQUIRES(Locks::mutator_lock_);
ALWAYS_INLINE ArtMethod* GetDirectMethod(size_t i, size_t pointer_size)
@@ -683,35 +677,20 @@
SHARED_REQUIRES(Locks::mutator_lock_);
// Returns the number of static, private, and constructor methods.
- ALWAYS_INLINE uint32_t NumDirectMethods() SHARED_REQUIRES(Locks::mutator_lock_) {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_direct_methods_));
- }
- void SetNumDirectMethods(uint32_t num) SHARED_REQUIRES(Locks::mutator_lock_) {
- return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_direct_methods_), num);
- }
+ ALWAYS_INLINE uint32_t NumDirectMethods() SHARED_REQUIRES(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- ALWAYS_INLINE ArtMethod* GetVirtualMethodsPtr() SHARED_REQUIRES(Locks::mutator_lock_);
-
- ALWAYS_INLINE StrideIterator<ArtMethod> VirtualMethodsBegin(size_t pointer_size)
- SHARED_REQUIRES(Locks::mutator_lock_);
-
- ALWAYS_INLINE StrideIterator<ArtMethod> VirtualMethodsEnd(size_t pointer_size)
+ ALWAYS_INLINE LengthPrefixedArray<ArtMethod>* GetVirtualMethodsPtr()
SHARED_REQUIRES(Locks::mutator_lock_);
ALWAYS_INLINE IterationRange<StrideIterator<ArtMethod>> GetVirtualMethods(size_t pointer_size)
SHARED_REQUIRES(Locks::mutator_lock_);
- void SetVirtualMethodsPtr(ArtMethod* new_virtual_methods)
+ void SetVirtualMethodsPtr(LengthPrefixedArray<ArtMethod>* new_virtual_methods)
SHARED_REQUIRES(Locks::mutator_lock_);
// Returns the number of non-inherited virtual methods.
- ALWAYS_INLINE uint32_t NumVirtualMethods() SHARED_REQUIRES(Locks::mutator_lock_) {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_virtual_methods_));
- }
- void SetNumVirtualMethods(uint32_t num) SHARED_REQUIRES(Locks::mutator_lock_) {
- return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_virtual_methods_), num);
- }
+ ALWAYS_INLINE uint32_t NumVirtualMethods() SHARED_REQUIRES(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ArtMethod* GetVirtualMethod(size_t i, size_t pointer_size)
@@ -859,21 +838,19 @@
ALWAYS_INLINE void SetIfTable(IfTable* new_iftable) SHARED_REQUIRES(Locks::mutator_lock_);
// Get instance fields of the class (See also GetSFields).
- ArtField* GetIFields() SHARED_REQUIRES(Locks::mutator_lock_);
+ LengthPrefixedArray<ArtField>* GetIFieldsPtr() SHARED_REQUIRES(Locks::mutator_lock_);
- void SetIFields(ArtField* new_ifields) SHARED_REQUIRES(Locks::mutator_lock_);
+ ALWAYS_INLINE IterationRange<StrideIterator<ArtField>> GetIFields()
+ SHARED_REQUIRES(Locks::mutator_lock_);
+
+ void SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields)
+ SHARED_REQUIRES(Locks::mutator_lock_);
// Unchecked edition has no verification flags.
- void SetIFieldsUnchecked(ArtField* new_sfields) SHARED_REQUIRES(Locks::mutator_lock_);
+ void SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields)
+ SHARED_REQUIRES(Locks::mutator_lock_);
- uint32_t NumInstanceFields() SHARED_REQUIRES(Locks::mutator_lock_) {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_instance_fields_));
- }
-
- void SetNumInstanceFields(uint32_t num) SHARED_REQUIRES(Locks::mutator_lock_) {
- return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_instance_fields_), num);
- }
-
+ uint32_t NumInstanceFields() SHARED_REQUIRES(Locks::mutator_lock_);
ArtField* GetInstanceField(uint32_t i) SHARED_REQUIRES(Locks::mutator_lock_);
// Returns the number of instance fields containing reference types.
@@ -927,20 +904,18 @@
SHARED_REQUIRES(Locks::mutator_lock_);
// Gets the static fields of the class.
- ArtField* GetSFields() SHARED_REQUIRES(Locks::mutator_lock_);
+ LengthPrefixedArray<ArtField>* GetSFieldsPtr() SHARED_REQUIRES(Locks::mutator_lock_);
+ ALWAYS_INLINE IterationRange<StrideIterator<ArtField>> GetSFields()
+ SHARED_REQUIRES(Locks::mutator_lock_);
- void SetSFields(ArtField* new_sfields) SHARED_REQUIRES(Locks::mutator_lock_);
+ void SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields)
+ SHARED_REQUIRES(Locks::mutator_lock_);
// Unchecked edition has no verification flags.
- void SetSFieldsUnchecked(ArtField* new_sfields) SHARED_REQUIRES(Locks::mutator_lock_);
+ void SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields)
+ SHARED_REQUIRES(Locks::mutator_lock_);
- uint32_t NumStaticFields() SHARED_REQUIRES(Locks::mutator_lock_) {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_static_fields_));
- }
-
- void SetNumStaticFields(uint32_t num) SHARED_REQUIRES(Locks::mutator_lock_) {
- return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_static_fields_), num);
- }
+ uint32_t NumStaticFields() SHARED_REQUIRES(Locks::mutator_lock_);
// TODO: uint16_t
ArtField* GetStaticField(uint32_t i) SHARED_REQUIRES(Locks::mutator_lock_);
@@ -1129,10 +1104,10 @@
return pointer_size;
}
- ALWAYS_INLINE ArtMethod* GetDirectMethodsPtrUnchecked()
+ ALWAYS_INLINE LengthPrefixedArray<ArtMethod>* GetDirectMethodsPtrUnchecked()
SHARED_REQUIRES(Locks::mutator_lock_);
- ALWAYS_INLINE ArtMethod* GetVirtualMethodsPtrUnchecked()
+ ALWAYS_INLINE LengthPrefixedArray<ArtMethod>* GetVirtualMethodsPtrUnchecked()
SHARED_REQUIRES(Locks::mutator_lock_);
private:
@@ -1154,8 +1129,12 @@
void CheckObjectAlloc() SHARED_REQUIRES(Locks::mutator_lock_);
// Unchecked editions is for root visiting.
- ArtField* GetSFieldsUnchecked() SHARED_REQUIRES(Locks::mutator_lock_);
- ArtField* GetIFieldsUnchecked() SHARED_REQUIRES(Locks::mutator_lock_);
+ LengthPrefixedArray<ArtField>* GetSFieldsPtrUnchecked() SHARED_REQUIRES(Locks::mutator_lock_);
+ IterationRange<StrideIterator<ArtField>> GetSFieldsUnchecked()
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ LengthPrefixedArray<ArtField>* GetIFieldsPtrUnchecked() SHARED_REQUIRES(Locks::mutator_lock_);
+ IterationRange<StrideIterator<ArtField>> GetIFieldsUnchecked()
+ SHARED_REQUIRES(Locks::mutator_lock_);
bool ProxyDescriptorEquals(const char* match) SHARED_REQUIRES(Locks::mutator_lock_);
@@ -1216,7 +1195,7 @@
// Note: Shuffled back.
uint32_t access_flags_;
- // static, private, and <init> methods. Pointer to an ArtMethod array.
+ // static, private, and <init> methods. Pointer to an ArtMethod length-prefixed array.
uint64_t direct_methods_;
// instance fields
@@ -1229,10 +1208,11 @@
// ArtField arrays are allocated as an array of fields, and not an array of fields pointers.
uint64_t ifields_;
- // Static fields
+ // Static fields length-prefixed array.
uint64_t sfields_;
- // Virtual methods defined in this class; invoked through vtable. Pointer to an ArtMethod array.
+ // Virtual methods defined in this class; invoked through vtable. Pointer to an ArtMethod
+ // length-prefixed array.
uint64_t virtual_methods_;
// Total size of the Class instance; used when allocating storage on gc heap.
@@ -1250,24 +1230,12 @@
// TODO: really 16bits
int32_t dex_type_idx_;
- // Number of direct fields.
- uint32_t num_direct_methods_;
-
- // Number of instance fields.
- uint32_t num_instance_fields_;
-
// Number of instance fields that are object refs.
uint32_t num_reference_instance_fields_;
// Number of static fields that are object refs,
uint32_t num_reference_static_fields_;
- // Number of static fields.
- uint32_t num_static_fields_;
-
- // Number of virtual methods.
- uint32_t num_virtual_methods_;
-
// Total object size; used when allocating storage on gc heap.
// (For interfaces and abstract classes this will be zero.)
// See also class_size_.
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index 02e4484..ff6847c 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -61,10 +61,10 @@
DCHECK_EQ(declaring_class->NumStaticFields(), 2U);
// 0 == Class[] interfaces; 1 == Class[][] throws;
if (GetDexFieldIndex() == 0) {
- return &declaring_class->GetSFields()[0];
+ return &declaring_class->GetSFieldsPtr()->At(0);
} else {
DCHECK_EQ(GetDexFieldIndex(), 1U);
- return &declaring_class->GetSFields()[1];
+ return &declaring_class->GetSFieldsPtr()->At(1);
}
}
mirror::DexCache* const dex_cache = declaring_class->GetDexCache();
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 80decaa..87fb5ba 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -208,15 +208,13 @@
return;
}
for (Class* cur = c; cur != nullptr; cur = cur->GetSuperClass()) {
- ArtField* fields = cur->GetIFields();
- for (size_t i = 0, count = cur->NumInstanceFields(); i < count; ++i) {
+ for (ArtField& field : cur->GetIFields()) {
StackHandleScope<1> hs(Thread::Current());
Handle<Object> h_object(hs.NewHandle(new_value));
- ArtField* field = &fields[i];
- if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
- CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
+ if (field.GetOffset().Int32Value() == field_offset.Int32Value()) {
+ CHECK_NE(field.GetTypeAsPrimitiveType(), Primitive::kPrimNot);
// TODO: resolve the field type for moving GC.
- mirror::Class* field_type = field->GetType<!kMovingCollector>();
+ mirror::Class* field_type = field.GetType<!kMovingCollector>();
if (field_type != nullptr) {
CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
}
@@ -229,13 +227,11 @@
return;
}
if (IsClass()) {
- ArtField* fields = AsClass()->GetSFields();
- for (size_t i = 0, count = AsClass()->NumStaticFields(); i < count; ++i) {
- ArtField* field = &fields[i];
- if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
- CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
+ for (ArtField& field : AsClass()->GetSFields()) {
+ if (field.GetOffset().Int32Value() == field_offset.Int32Value()) {
+ CHECK_NE(field.GetTypeAsPrimitiveType(), Primitive::kPrimNot);
// TODO: resolve the field type for moving GC.
- mirror::Class* field_type = field->GetType<!kMovingCollector>();
+ mirror::Class* field_type = field.GetType<!kMovingCollector>();
if (field_type != nullptr) {
CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
}