xref: /aosp_15_r20/art/runtime/mirror/class_ext-inl.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_MIRROR_CLASS_EXT_INL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_MIRROR_CLASS_EXT_INL_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "class_ext.h"
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "array-inl.h"
23*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/globals.h"
26*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
27*795d594fSAndroid Build Coastguard Worker #include "handle_scope.h"
28*795d594fSAndroid Build Coastguard Worker #include "jni/jni_internal.h"
29*795d594fSAndroid Build Coastguard Worker #include "jni_id_type.h"
30*795d594fSAndroid Build Coastguard Worker #include "mirror/array.h"
31*795d594fSAndroid Build Coastguard Worker #include "mirror/object.h"
32*795d594fSAndroid Build Coastguard Worker #include "object-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "verify_object.h"
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
36*795d594fSAndroid Build Coastguard Worker namespace mirror {
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
EnsureJniIdsArrayPresent(MemberOffset off,size_t count)39*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::EnsureJniIdsArrayPresent(MemberOffset off, size_t count) {
40*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> existing(
41*795d594fSAndroid Build Coastguard Worker       GetFieldObject<Object, kVerifyFlags, kReadBarrierOption>(off));
42*795d594fSAndroid Build Coastguard Worker   if (!existing.IsNull()) {
43*795d594fSAndroid Build Coastguard Worker     return true;
44*795d594fSAndroid Build Coastguard Worker   }
45*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
46*795d594fSAndroid Build Coastguard Worker   StackHandleScope<2> hs(self);
47*795d594fSAndroid Build Coastguard Worker   Handle<ClassExt> h_this(hs.NewHandle(this));
48*795d594fSAndroid Build Coastguard Worker   MutableHandle<Object> new_arr(hs.NewHandle<Object>(nullptr));
49*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(Runtime::Current()->GetJniIdType() == JniIdType::kSwapablePointer)) {
50*795d594fSAndroid Build Coastguard Worker     new_arr.Assign(Runtime::Current()->GetJniIdManager()->GetPointerMarker());
51*795d594fSAndroid Build Coastguard Worker   } else {
52*795d594fSAndroid Build Coastguard Worker     new_arr.Assign(Runtime::Current()->GetClassLinker()->AllocPointerArray(self, count));
53*795d594fSAndroid Build Coastguard Worker   }
54*795d594fSAndroid Build Coastguard Worker   if (new_arr.IsNull()) {
55*795d594fSAndroid Build Coastguard Worker     // Fail.
56*795d594fSAndroid Build Coastguard Worker     self->AssertPendingOOMException();
57*795d594fSAndroid Build Coastguard Worker     return false;
58*795d594fSAndroid Build Coastguard Worker   }
59*795d594fSAndroid Build Coastguard Worker   bool set;
60*795d594fSAndroid Build Coastguard Worker   // Set the ext_data_ field using CAS semantics.
61*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->IsActiveTransaction()) {
62*795d594fSAndroid Build Coastguard Worker     set = h_this->CasFieldObject<true>(
63*795d594fSAndroid Build Coastguard Worker         off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst);
64*795d594fSAndroid Build Coastguard Worker   } else {
65*795d594fSAndroid Build Coastguard Worker     set = h_this->CasFieldObject<false>(
66*795d594fSAndroid Build Coastguard Worker         off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst);
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
69*795d594fSAndroid Build Coastguard Worker     ObjPtr<Object> ret(
70*795d594fSAndroid Build Coastguard Worker         set ? new_arr.Get()
71*795d594fSAndroid Build Coastguard Worker             : h_this->GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(off));
72*795d594fSAndroid Build Coastguard Worker     CHECK(!ret.IsNull());
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker   return true;
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
EnsureJMethodIDsArrayPresent(size_t count)78*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::EnsureJMethodIDsArrayPresent(size_t count) {
79*795d594fSAndroid Build Coastguard Worker   return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
80*795d594fSAndroid Build Coastguard Worker       MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_)), count);
81*795d594fSAndroid Build Coastguard Worker }
82*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
EnsureStaticJFieldIDsArrayPresent(size_t count)83*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::EnsureStaticJFieldIDsArrayPresent(size_t count) {
84*795d594fSAndroid Build Coastguard Worker   return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
85*795d594fSAndroid Build Coastguard Worker       MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_)), count);
86*795d594fSAndroid Build Coastguard Worker }
87*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
EnsureInstanceJFieldIDsArrayPresent(size_t count)88*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::EnsureInstanceJFieldIDsArrayPresent(size_t count) {
89*795d594fSAndroid Build Coastguard Worker   return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
90*795d594fSAndroid Build Coastguard Worker       MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_)), count);
91*795d594fSAndroid Build Coastguard Worker }
92*795d594fSAndroid Build Coastguard Worker 
93*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetInstanceJFieldIDs()94*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Object> ClassExt::GetInstanceJFieldIDs() {
95*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Object, kVerifyFlags, kReadBarrierOption>(
96*795d594fSAndroid Build Coastguard Worker       OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_));
97*795d594fSAndroid Build Coastguard Worker }
98*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
HasInstanceFieldPointerIdMarker()99*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::HasInstanceFieldPointerIdMarker() {
100*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> arr(GetInstanceJFieldIDs<kVerifyFlags, kReadBarrierOption>());
101*795d594fSAndroid Build Coastguard Worker   return !arr.IsNull() && !arr->IsArrayInstance();
102*795d594fSAndroid Build Coastguard Worker }
103*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetInstanceJFieldIDsPointerArray()104*795d594fSAndroid Build Coastguard Worker inline ObjPtr<PointerArray> ClassExt::GetInstanceJFieldIDsPointerArray() {
105*795d594fSAndroid Build Coastguard Worker   DCHECK(!HasInstanceFieldPointerIdMarker());
106*795d594fSAndroid Build Coastguard Worker   return down_cast<PointerArray*>(GetInstanceJFieldIDs<kVerifyFlags, kReadBarrierOption>().Ptr());
107*795d594fSAndroid Build Coastguard Worker }
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetStaticJFieldIDs()110*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Object> ClassExt::GetStaticJFieldIDs() {
111*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Object, kVerifyFlags, kReadBarrierOption>(
112*795d594fSAndroid Build Coastguard Worker       OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_));
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetStaticJFieldIDsPointerArray()115*795d594fSAndroid Build Coastguard Worker inline ObjPtr<PointerArray> ClassExt::GetStaticJFieldIDsPointerArray() {
116*795d594fSAndroid Build Coastguard Worker   DCHECK(!HasStaticFieldPointerIdMarker());
117*795d594fSAndroid Build Coastguard Worker   return down_cast<PointerArray*>(GetStaticJFieldIDs<kVerifyFlags, kReadBarrierOption>().Ptr());
118*795d594fSAndroid Build Coastguard Worker }
119*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
HasStaticFieldPointerIdMarker()120*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::HasStaticFieldPointerIdMarker() {
121*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> arr(GetStaticJFieldIDs<kVerifyFlags, kReadBarrierOption>());
122*795d594fSAndroid Build Coastguard Worker   return !arr.IsNull() && !arr->IsArrayInstance();
123*795d594fSAndroid Build Coastguard Worker }
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetObsoleteClass()126*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Class> ClassExt::GetObsoleteClass() {
127*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
128*795d594fSAndroid Build Coastguard Worker       OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_class_));
129*795d594fSAndroid Build Coastguard Worker }
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetJMethodIDs()132*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Object> ClassExt::GetJMethodIDs() {
133*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Object, kVerifyFlags, kReadBarrierOption>(
134*795d594fSAndroid Build Coastguard Worker       OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_));
135*795d594fSAndroid Build Coastguard Worker }
136*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetJMethodIDsPointerArray()137*795d594fSAndroid Build Coastguard Worker inline ObjPtr<PointerArray> ClassExt::GetJMethodIDsPointerArray() {
138*795d594fSAndroid Build Coastguard Worker   DCHECK(!HasMethodPointerIdMarker());
139*795d594fSAndroid Build Coastguard Worker   return down_cast<PointerArray*>(GetJMethodIDs<kVerifyFlags, kReadBarrierOption>().Ptr());
140*795d594fSAndroid Build Coastguard Worker }
141*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
HasMethodPointerIdMarker()142*795d594fSAndroid Build Coastguard Worker inline bool ClassExt::HasMethodPointerIdMarker() {
143*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> arr(GetJMethodIDs<kVerifyFlags, kReadBarrierOption>());
144*795d594fSAndroid Build Coastguard Worker   return !arr.IsNull() && !arr->IsArrayInstance();
145*795d594fSAndroid Build Coastguard Worker }
146*795d594fSAndroid Build Coastguard Worker 
GetErroneousStateError()147*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Throwable> ClassExt::GetErroneousStateError() {
148*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Throwable>(OFFSET_OF_OBJECT_MEMBER(ClassExt, erroneous_state_error_));
149*795d594fSAndroid Build Coastguard Worker }
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetObsoleteDexCaches()152*795d594fSAndroid Build Coastguard Worker inline ObjPtr<ObjectArray<DexCache>> ClassExt::GetObsoleteDexCaches() {
153*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<ObjectArray<DexCache>, kVerifyFlags, kReadBarrierOption>(
154*795d594fSAndroid Build Coastguard Worker       OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_dex_caches_));
155*795d594fSAndroid Build Coastguard Worker }
156*795d594fSAndroid Build Coastguard Worker 
157*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags,
158*795d594fSAndroid Build Coastguard Worker          ReadBarrierOption kReadBarrierOption>
GetObsoleteMethods()159*795d594fSAndroid Build Coastguard Worker inline ObjPtr<PointerArray> ClassExt::GetObsoleteMethods() {
160*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
161*795d594fSAndroid Build Coastguard Worker       OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_methods_));
162*795d594fSAndroid Build Coastguard Worker }
163*795d594fSAndroid Build Coastguard Worker 
GetOriginalDexFile()164*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Object> ClassExt::GetOriginalDexFile() {
165*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Object>(OFFSET_OF_OBJECT_MEMBER(ClassExt, original_dex_file_));
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker template<ReadBarrierOption kReadBarrierOption, bool kVisitProxyMethod, class Visitor>
VisitNativeRoots(Visitor & visitor,PointerSize pointer_size)169*795d594fSAndroid Build Coastguard Worker void ClassExt::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) {
170*795d594fSAndroid Build Coastguard Worker   VisitMethods<kReadBarrierOption>([&](ArtMethod* method) {
171*795d594fSAndroid Build Coastguard Worker     method->VisitRoots<kReadBarrierOption, kVisitProxyMethod>(visitor, pointer_size);
172*795d594fSAndroid Build Coastguard Worker   }, pointer_size);
173*795d594fSAndroid Build Coastguard Worker }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
VisitDexCaches(DexCacheVisitor & visitor)176*795d594fSAndroid Build Coastguard Worker void ClassExt::VisitDexCaches(DexCacheVisitor& visitor) {
177*795d594fSAndroid Build Coastguard Worker   ObjPtr<ObjectArray<DexCache>> arr(GetObsoleteDexCaches<kVerifyFlags, kReadBarrierOption>());
178*795d594fSAndroid Build Coastguard Worker   if (!arr.IsNull()) {
179*795d594fSAndroid Build Coastguard Worker     int32_t len = arr->GetLength();
180*795d594fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < len; i++) {
181*795d594fSAndroid Build Coastguard Worker       ObjPtr<mirror::DexCache> dex_cache = arr->Get<kVerifyFlags, kReadBarrierOption>(i);
182*795d594fSAndroid Build Coastguard Worker       visitor.Visit(dex_cache);
183*795d594fSAndroid Build Coastguard Worker     }
184*795d594fSAndroid Build Coastguard Worker   }
185*795d594fSAndroid Build Coastguard Worker }
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker template<ReadBarrierOption kReadBarrierOption, class Visitor>
VisitMethods(Visitor visitor,PointerSize pointer_size)188*795d594fSAndroid Build Coastguard Worker void ClassExt::VisitMethods(Visitor visitor, PointerSize pointer_size) {
189*795d594fSAndroid Build Coastguard Worker   ObjPtr<PointerArray> arr(GetObsoleteMethods<kDefaultVerifyFlags, kReadBarrierOption>());
190*795d594fSAndroid Build Coastguard Worker   if (!arr.IsNull()) {
191*795d594fSAndroid Build Coastguard Worker     int32_t len = arr->GetLength();
192*795d594fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < len; i++) {
193*795d594fSAndroid Build Coastguard Worker       ArtMethod* method = arr->GetElementPtrSize<ArtMethod*>(i, pointer_size);
194*795d594fSAndroid Build Coastguard Worker       if (method != nullptr) {
195*795d594fSAndroid Build Coastguard Worker         visitor(method);
196*795d594fSAndroid Build Coastguard Worker       }
197*795d594fSAndroid Build Coastguard Worker     }
198*795d594fSAndroid Build Coastguard Worker   }
199*795d594fSAndroid Build Coastguard Worker }
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker template<ReadBarrierOption kReadBarrierOption, class Visitor>
VisitJMethodIDs(Visitor v)202*795d594fSAndroid Build Coastguard Worker void ClassExt::VisitJMethodIDs(Visitor v) {
203*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> arr(GetJMethodIDs<kDefaultVerifyFlags, kReadBarrierOption>());
204*795d594fSAndroid Build Coastguard Worker   if (!arr.IsNull() && arr->IsArrayInstance()) {
205*795d594fSAndroid Build Coastguard Worker     ObjPtr<PointerArray> marr(down_cast<PointerArray*>(arr.Ptr()));
206*795d594fSAndroid Build Coastguard Worker     int32_t len = marr->GetLength();
207*795d594fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < len; i++) {
208*795d594fSAndroid Build Coastguard Worker       jmethodID id = marr->GetElementPtrSize<jmethodID>(i, kRuntimePointerSize);
209*795d594fSAndroid Build Coastguard Worker       if (id != nullptr) {
210*795d594fSAndroid Build Coastguard Worker         v(id, i);
211*795d594fSAndroid Build Coastguard Worker       }
212*795d594fSAndroid Build Coastguard Worker     }
213*795d594fSAndroid Build Coastguard Worker   }
214*795d594fSAndroid Build Coastguard Worker }
215*795d594fSAndroid Build Coastguard Worker template<ReadBarrierOption kReadBarrierOption, class Visitor>
VisitJFieldIDs(Visitor v)216*795d594fSAndroid Build Coastguard Worker void ClassExt::VisitJFieldIDs(Visitor v) {
217*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> sarr_obj(GetStaticJFieldIDs<kDefaultVerifyFlags, kReadBarrierOption>());
218*795d594fSAndroid Build Coastguard Worker   if (!sarr_obj.IsNull() && sarr_obj->IsArrayInstance()) {
219*795d594fSAndroid Build Coastguard Worker     ObjPtr<PointerArray> sarr(down_cast<PointerArray*>(sarr_obj->AsArray().Ptr()));
220*795d594fSAndroid Build Coastguard Worker     int32_t len = sarr->GetLength();
221*795d594fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < len; i++) {
222*795d594fSAndroid Build Coastguard Worker       jfieldID id = sarr->GetElementPtrSize<jfieldID>(i, kRuntimePointerSize);
223*795d594fSAndroid Build Coastguard Worker       if (id != nullptr) {
224*795d594fSAndroid Build Coastguard Worker         v(id, i, true);
225*795d594fSAndroid Build Coastguard Worker       }
226*795d594fSAndroid Build Coastguard Worker     }
227*795d594fSAndroid Build Coastguard Worker   }
228*795d594fSAndroid Build Coastguard Worker   ObjPtr<PointerArray> iarr_obj(GetInstanceJFieldIDs<kDefaultVerifyFlags, kReadBarrierOption>());
229*795d594fSAndroid Build Coastguard Worker   if (!iarr_obj.IsNull() && iarr_obj->IsArrayInstance()) {
230*795d594fSAndroid Build Coastguard Worker     ObjPtr<PointerArray> iarr(down_cast<PointerArray*>(iarr_obj->AsArray().Ptr()));
231*795d594fSAndroid Build Coastguard Worker     int32_t len = iarr->GetLength();
232*795d594fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < len; i++) {
233*795d594fSAndroid Build Coastguard Worker       jfieldID id = iarr->GetElementPtrSize<jfieldID>(i, kRuntimePointerSize);
234*795d594fSAndroid Build Coastguard Worker       if (id != nullptr) {
235*795d594fSAndroid Build Coastguard Worker         v(id, i, false);
236*795d594fSAndroid Build Coastguard Worker       }
237*795d594fSAndroid Build Coastguard Worker     }
238*795d594fSAndroid Build Coastguard Worker   }
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
242*795d594fSAndroid Build Coastguard Worker }  // namespace art
243*795d594fSAndroid Build Coastguard Worker 
244*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_MIRROR_CLASS_EXT_INL_H_
245