xref: /aosp_15_r20/art/runtime/entrypoints/quick/quick_field_entrypoints.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2012 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 #include <stdint.h>
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
20*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/callee_save_type.h"
22*795d594fSAndroid Build Coastguard Worker #include "callee_save_frame.h"
23*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "entrypoints/entrypoint_utils-inl.h"
25*795d594fSAndroid Build Coastguard Worker #include "gc_root-inl.h"
26*795d594fSAndroid Build Coastguard Worker #include "mirror/class-inl.h"
27*795d594fSAndroid Build Coastguard Worker #include "mirror/object_reference.h"
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker // Fast path field resolution that can't initialize classes or throw exceptions.
FindFieldFast(uint32_t field_idx,ArtMethod * referrer,FindFieldType type,bool should_resolve_type=false)32*795d594fSAndroid Build Coastguard Worker inline ArtField* FindFieldFast(uint32_t field_idx,
33*795d594fSAndroid Build Coastguard Worker                                ArtMethod* referrer,
34*795d594fSAndroid Build Coastguard Worker                                FindFieldType type,
35*795d594fSAndroid Build Coastguard Worker                                bool should_resolve_type = false)
36*795d594fSAndroid Build Coastguard Worker     REQUIRES(!Roles::uninterruptible_)
37*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
38*795d594fSAndroid Build Coastguard Worker   ScopedAssertNoThreadSuspension ants(__FUNCTION__);
39*795d594fSAndroid Build Coastguard Worker   ArtField* resolved_field = referrer->GetDexCache()->GetResolvedField(field_idx);
40*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(resolved_field == nullptr)) {
41*795d594fSAndroid Build Coastguard Worker     return nullptr;
42*795d594fSAndroid Build Coastguard Worker   }
43*795d594fSAndroid Build Coastguard Worker   // Check for incompatible class change.
44*795d594fSAndroid Build Coastguard Worker   const bool is_set = (type & FindFieldFlags::WriteBit) != 0;
45*795d594fSAndroid Build Coastguard Worker   const bool is_static = (type & FindFieldFlags::StaticBit) != 0;
46*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
47*795d594fSAndroid Build Coastguard Worker     // Incompatible class change.
48*795d594fSAndroid Build Coastguard Worker     return nullptr;
49*795d594fSAndroid Build Coastguard Worker   }
50*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> fields_class = resolved_field->GetDeclaringClass();
51*795d594fSAndroid Build Coastguard Worker   if (is_static) {
52*795d594fSAndroid Build Coastguard Worker     // Check class is initialized else fail so that we can contend to initialize the class with
53*795d594fSAndroid Build Coastguard Worker     // other threads that may be racing to do this.
54*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(!fields_class->IsVisiblyInitialized())) {
55*795d594fSAndroid Build Coastguard Worker       return nullptr;
56*795d594fSAndroid Build Coastguard Worker     }
57*795d594fSAndroid Build Coastguard Worker   }
58*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
59*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
60*795d594fSAndroid Build Coastguard Worker                !referring_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) ||
61*795d594fSAndroid Build Coastguard Worker                (is_set && !resolved_field->CanBeChangedBy(referrer)))) {
62*795d594fSAndroid Build Coastguard Worker     // Illegal access.
63*795d594fSAndroid Build Coastguard Worker     return nullptr;
64*795d594fSAndroid Build Coastguard Worker   }
65*795d594fSAndroid Build Coastguard Worker   if (should_resolve_type && resolved_field->LookupResolvedType() == nullptr) {
66*795d594fSAndroid Build Coastguard Worker     return nullptr;
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker   return resolved_field;
69*795d594fSAndroid Build Coastguard Worker }
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker // Helper function to do a null check after trying to resolve the field. Not for statics since obj
72*795d594fSAndroid Build Coastguard Worker // does not exist there. There is a suspend check, object is a double pointer to update the value
73*795d594fSAndroid Build Coastguard Worker // in the caller in case it moves.
74*795d594fSAndroid Build Coastguard Worker template<FindFieldType type>
FindInstanceField(uint32_t field_idx,ArtMethod * referrer,Thread * self,mirror::Object ** obj,bool should_resolve_type=false)75*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE static inline ArtField* FindInstanceField(uint32_t field_idx,
76*795d594fSAndroid Build Coastguard Worker                                                         ArtMethod* referrer,
77*795d594fSAndroid Build Coastguard Worker                                                         Thread* self,
78*795d594fSAndroid Build Coastguard Worker                                                         mirror::Object** obj,
79*795d594fSAndroid Build Coastguard Worker                                                         bool should_resolve_type = false)
80*795d594fSAndroid Build Coastguard Worker     REQUIRES(!Roles::uninterruptible_)
81*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
82*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
83*795d594fSAndroid Build Coastguard Worker   HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj));
84*795d594fSAndroid Build Coastguard Worker   ArtField* field = FindFieldFromCode<type>(field_idx, referrer, self, should_resolve_type);
85*795d594fSAndroid Build Coastguard Worker   if (LIKELY(field != nullptr) && UNLIKELY(h == nullptr)) {
86*795d594fSAndroid Build Coastguard Worker     ThrowNullPointerExceptionForFieldAccess(field, referrer, (type & FindFieldFlags::ReadBit) != 0);
87*795d594fSAndroid Build Coastguard Worker     return nullptr;
88*795d594fSAndroid Build Coastguard Worker   }
89*795d594fSAndroid Build Coastguard Worker   return field;
90*795d594fSAndroid Build Coastguard Worker }
91*795d594fSAndroid Build Coastguard Worker 
GetReferrer(Thread * self)92*795d594fSAndroid Build Coastguard Worker static ArtMethod* GetReferrer(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
93*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
94*795d594fSAndroid Build Coastguard Worker     // stub_test doesn't call this code with a proper frame, so get the outer, and if
95*795d594fSAndroid Build Coastguard Worker     // it does not have compiled code return it.
96*795d594fSAndroid Build Coastguard Worker     ArtMethod* outer = GetCalleeSaveOuterMethod(self, CalleeSaveType::kSaveRefsOnly);
97*795d594fSAndroid Build Coastguard Worker     if (outer->GetEntryPointFromQuickCompiledCode() == nullptr) {
98*795d594fSAndroid Build Coastguard Worker       return outer;
99*795d594fSAndroid Build Coastguard Worker     }
100*795d594fSAndroid Build Coastguard Worker   }
101*795d594fSAndroid Build Coastguard Worker   return GetCalleeSaveMethodCallerAndOuterMethod(self, CalleeSaveType::kSaveRefsOnly).caller;
102*795d594fSAndroid Build Coastguard Worker }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker // Macro used to define this set of functions:
105*795d594fSAndroid Build Coastguard Worker //
106*795d594fSAndroid Build Coastguard Worker //   art{Get,Set}<Kind>{Static,Instance}FromCode
107*795d594fSAndroid Build Coastguard Worker //   art{Get,Set}<Kind>{Static,Instance}FromCompiledCode
108*795d594fSAndroid Build Coastguard Worker //
109*795d594fSAndroid Build Coastguard Worker #define ART_GET_FIELD_FROM_CODE(Kind, RetType, SetType, PrimitiveOrObject,     \
110*795d594fSAndroid Build Coastguard Worker                                 IsObject, Ptr)                                 \
111*795d594fSAndroid Build Coastguard Worker   extern "C" RetType artGet ## Kind ## StaticFromCode(uint32_t field_idx,      \
112*795d594fSAndroid Build Coastguard Worker                                                       ArtMethod* referrer,     \
113*795d594fSAndroid Build Coastguard Worker                                                       Thread* self)            \
114*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
115*795d594fSAndroid Build Coastguard Worker     ScopedQuickEntrypointChecks sqec(self);                                    \
116*795d594fSAndroid Build Coastguard Worker     ArtField* field = FindFieldFast(                                           \
117*795d594fSAndroid Build Coastguard Worker         field_idx, referrer, Static ## PrimitiveOrObject ## Read);             \
118*795d594fSAndroid Build Coastguard Worker     if (LIKELY(field != nullptr)) {                                            \
119*795d594fSAndroid Build Coastguard Worker       return field->Get ## Kind (field->GetDeclaringClass())Ptr;  /* NOLINT */ \
120*795d594fSAndroid Build Coastguard Worker     }                                                                          \
121*795d594fSAndroid Build Coastguard Worker     field = FindFieldFromCode<Static ## PrimitiveOrObject ## Read>(            \
122*795d594fSAndroid Build Coastguard Worker         field_idx, referrer, self);                                            \
123*795d594fSAndroid Build Coastguard Worker     if (LIKELY(field != nullptr)) {                                            \
124*795d594fSAndroid Build Coastguard Worker       return field->Get ## Kind (field->GetDeclaringClass())Ptr;  /* NOLINT */ \
125*795d594fSAndroid Build Coastguard Worker     }                                                                          \
126*795d594fSAndroid Build Coastguard Worker     /* Will throw exception by checking with Thread::Current. */               \
127*795d594fSAndroid Build Coastguard Worker     return 0;                                                                  \
128*795d594fSAndroid Build Coastguard Worker   }                                                                            \
129*795d594fSAndroid Build Coastguard Worker                                                                                \
130*795d594fSAndroid Build Coastguard Worker   extern "C" RetType artGet ## Kind ## InstanceFromCode(uint32_t field_idx,    \
131*795d594fSAndroid Build Coastguard Worker                                                         mirror::Object* obj,   \
132*795d594fSAndroid Build Coastguard Worker                                                         ArtMethod* referrer,   \
133*795d594fSAndroid Build Coastguard Worker                                                         Thread* self)          \
134*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
135*795d594fSAndroid Build Coastguard Worker     ScopedQuickEntrypointChecks sqec(self);                                    \
136*795d594fSAndroid Build Coastguard Worker     ArtField* field = FindFieldFast(                                           \
137*795d594fSAndroid Build Coastguard Worker         field_idx, referrer, Instance ## PrimitiveOrObject ## Read);           \
138*795d594fSAndroid Build Coastguard Worker     if (LIKELY(field != nullptr) && obj != nullptr) {                          \
139*795d594fSAndroid Build Coastguard Worker       return field->Get ## Kind (obj)Ptr;  /* NOLINT */                        \
140*795d594fSAndroid Build Coastguard Worker     }                                                                          \
141*795d594fSAndroid Build Coastguard Worker     field = FindInstanceField<Instance ## PrimitiveOrObject ## Read>(          \
142*795d594fSAndroid Build Coastguard Worker         field_idx, referrer, self, &obj);                                      \
143*795d594fSAndroid Build Coastguard Worker     if (LIKELY(field != nullptr)) {                                            \
144*795d594fSAndroid Build Coastguard Worker       return field->Get ## Kind (obj)Ptr;  /* NOLINT */                        \
145*795d594fSAndroid Build Coastguard Worker     }                                                                          \
146*795d594fSAndroid Build Coastguard Worker     /* Will throw exception by checking with Thread::Current. */               \
147*795d594fSAndroid Build Coastguard Worker     return 0;                                                                  \
148*795d594fSAndroid Build Coastguard Worker   }                                                                            \
149*795d594fSAndroid Build Coastguard Worker                                                                                \
150*795d594fSAndroid Build Coastguard Worker   extern "C" int artSet ## Kind ## StaticFromCode(uint32_t field_idx,          \
151*795d594fSAndroid Build Coastguard Worker                                                   SetType new_value,           \
152*795d594fSAndroid Build Coastguard Worker                                                   ArtMethod* referrer,         \
153*795d594fSAndroid Build Coastguard Worker                                                   Thread* self)                \
154*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
155*795d594fSAndroid Build Coastguard Worker     ScopedQuickEntrypointChecks sqec(self);                                    \
156*795d594fSAndroid Build Coastguard Worker     bool should_resolve_type = (IsObject) && new_value != 0;                   \
157*795d594fSAndroid Build Coastguard Worker     ArtField* field = FindFieldFast(                                           \
158*795d594fSAndroid Build Coastguard Worker         field_idx,                                                             \
159*795d594fSAndroid Build Coastguard Worker         referrer,                                                              \
160*795d594fSAndroid Build Coastguard Worker         Static ## PrimitiveOrObject ## Write,                                  \
161*795d594fSAndroid Build Coastguard Worker         should_resolve_type);                                                  \
162*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(field == nullptr)) {                                          \
163*795d594fSAndroid Build Coastguard Worker       if (IsObject) {                                                          \
164*795d594fSAndroid Build Coastguard Worker         StackHandleScope<1> hs(self);                                          \
165*795d594fSAndroid Build Coastguard Worker         HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(               \
166*795d594fSAndroid Build Coastguard Worker             reinterpret_cast<mirror::Object**>(&new_value)));                  \
167*795d594fSAndroid Build Coastguard Worker         field = FindFieldFromCode<Static ## PrimitiveOrObject ## Write>(       \
168*795d594fSAndroid Build Coastguard Worker             field_idx,                                                         \
169*795d594fSAndroid Build Coastguard Worker             referrer,                                                          \
170*795d594fSAndroid Build Coastguard Worker             self,                                                              \
171*795d594fSAndroid Build Coastguard Worker             should_resolve_type);                                              \
172*795d594fSAndroid Build Coastguard Worker       } else {                                                                 \
173*795d594fSAndroid Build Coastguard Worker         field = FindFieldFromCode<Static ## PrimitiveOrObject ## Write>(       \
174*795d594fSAndroid Build Coastguard Worker             field_idx, referrer, self);                                        \
175*795d594fSAndroid Build Coastguard Worker       }                                                                        \
176*795d594fSAndroid Build Coastguard Worker       if (UNLIKELY(field == nullptr)) {                                        \
177*795d594fSAndroid Build Coastguard Worker         return -1;                                                             \
178*795d594fSAndroid Build Coastguard Worker       }                                                                        \
179*795d594fSAndroid Build Coastguard Worker     }                                                                          \
180*795d594fSAndroid Build Coastguard Worker     field->Set ## Kind <false>(field->GetDeclaringClass(), new_value);         \
181*795d594fSAndroid Build Coastguard Worker     return 0;                                                                  \
182*795d594fSAndroid Build Coastguard Worker   }                                                                            \
183*795d594fSAndroid Build Coastguard Worker                                                                                \
184*795d594fSAndroid Build Coastguard Worker   extern "C" int artSet ## Kind ## InstanceFromCode(uint32_t field_idx,        \
185*795d594fSAndroid Build Coastguard Worker                                                     mirror::Object* obj,       \
186*795d594fSAndroid Build Coastguard Worker                                                     SetType new_value,         \
187*795d594fSAndroid Build Coastguard Worker                                                     ArtMethod* referrer,       \
188*795d594fSAndroid Build Coastguard Worker                                                     Thread* self)              \
189*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {                                    \
190*795d594fSAndroid Build Coastguard Worker     ScopedQuickEntrypointChecks sqec(self);                                    \
191*795d594fSAndroid Build Coastguard Worker     bool should_resolve_type = (IsObject) && new_value != 0;                   \
192*795d594fSAndroid Build Coastguard Worker     ArtField* field = FindFieldFast(                                           \
193*795d594fSAndroid Build Coastguard Worker         field_idx,                                                             \
194*795d594fSAndroid Build Coastguard Worker         referrer,                                                              \
195*795d594fSAndroid Build Coastguard Worker         Instance ## PrimitiveOrObject ## Write,                                \
196*795d594fSAndroid Build Coastguard Worker         should_resolve_type);                                                  \
197*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(field == nullptr || obj == nullptr)) {                        \
198*795d594fSAndroid Build Coastguard Worker       if (IsObject) {                                                          \
199*795d594fSAndroid Build Coastguard Worker         StackHandleScope<1> hs(self);                                          \
200*795d594fSAndroid Build Coastguard Worker         HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(               \
201*795d594fSAndroid Build Coastguard Worker             reinterpret_cast<mirror::Object**>(&new_value)));                  \
202*795d594fSAndroid Build Coastguard Worker         field = FindInstanceField<Instance ## PrimitiveOrObject ## Write>(     \
203*795d594fSAndroid Build Coastguard Worker             field_idx,                                                         \
204*795d594fSAndroid Build Coastguard Worker             referrer,                                                          \
205*795d594fSAndroid Build Coastguard Worker             self,                                                              \
206*795d594fSAndroid Build Coastguard Worker             &obj,                                                              \
207*795d594fSAndroid Build Coastguard Worker             should_resolve_type);                                              \
208*795d594fSAndroid Build Coastguard Worker       } else {                                                                 \
209*795d594fSAndroid Build Coastguard Worker         field = FindInstanceField<Instance ## PrimitiveOrObject ## Write>(     \
210*795d594fSAndroid Build Coastguard Worker             field_idx, referrer, self, &obj);                                  \
211*795d594fSAndroid Build Coastguard Worker       }                                                                        \
212*795d594fSAndroid Build Coastguard Worker       if (UNLIKELY(field == nullptr)) {                                        \
213*795d594fSAndroid Build Coastguard Worker         return -1;                                                             \
214*795d594fSAndroid Build Coastguard Worker       }                                                                        \
215*795d594fSAndroid Build Coastguard Worker     }                                                                          \
216*795d594fSAndroid Build Coastguard Worker     field->Set ## Kind<false>(obj, new_value);                                 \
217*795d594fSAndroid Build Coastguard Worker     return 0;                                                                  \
218*795d594fSAndroid Build Coastguard Worker   }                                                                            \
219*795d594fSAndroid Build Coastguard Worker                                                                                \
220*795d594fSAndroid Build Coastguard Worker   extern "C" RetType artGet ## Kind ## StaticFromCompiledCode(                 \
221*795d594fSAndroid Build Coastguard Worker       uint32_t field_idx,                                                      \
222*795d594fSAndroid Build Coastguard Worker       Thread* self)                                                            \
223*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
224*795d594fSAndroid Build Coastguard Worker     return artGet ## Kind ## StaticFromCode(                                   \
225*795d594fSAndroid Build Coastguard Worker         field_idx, GetReferrer(self), self);                                   \
226*795d594fSAndroid Build Coastguard Worker   }                                                                            \
227*795d594fSAndroid Build Coastguard Worker                                                                                \
228*795d594fSAndroid Build Coastguard Worker   extern "C" RetType artGet ## Kind ## InstanceFromCompiledCode(               \
229*795d594fSAndroid Build Coastguard Worker       uint32_t field_idx,                                                      \
230*795d594fSAndroid Build Coastguard Worker       mirror::Object* obj,                                                     \
231*795d594fSAndroid Build Coastguard Worker       Thread* self)                                                            \
232*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
233*795d594fSAndroid Build Coastguard Worker     return artGet ## Kind ## InstanceFromCode(                                 \
234*795d594fSAndroid Build Coastguard Worker         field_idx, obj, GetReferrer(self), self);                              \
235*795d594fSAndroid Build Coastguard Worker   }                                                                            \
236*795d594fSAndroid Build Coastguard Worker                                                                                \
237*795d594fSAndroid Build Coastguard Worker   extern "C" int artSet ## Kind ## StaticFromCompiledCode(                     \
238*795d594fSAndroid Build Coastguard Worker       uint32_t field_idx,                                                      \
239*795d594fSAndroid Build Coastguard Worker       SetType new_value,                                                       \
240*795d594fSAndroid Build Coastguard Worker       Thread* self)                                                            \
241*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
242*795d594fSAndroid Build Coastguard Worker     return artSet ## Kind ## StaticFromCode(                                   \
243*795d594fSAndroid Build Coastguard Worker         field_idx, new_value, GetReferrer(self), self);                        \
244*795d594fSAndroid Build Coastguard Worker   }                                                                            \
245*795d594fSAndroid Build Coastguard Worker                                                                                \
246*795d594fSAndroid Build Coastguard Worker   extern "C" int artSet ## Kind ## InstanceFromCompiledCode(                   \
247*795d594fSAndroid Build Coastguard Worker       uint32_t field_idx,                                                      \
248*795d594fSAndroid Build Coastguard Worker       mirror::Object* obj,                                                     \
249*795d594fSAndroid Build Coastguard Worker       SetType new_value,                                                       \
250*795d594fSAndroid Build Coastguard Worker       Thread* self)                                                            \
251*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {                                  \
252*795d594fSAndroid Build Coastguard Worker     return artSet ## Kind ## InstanceFromCode(                                 \
253*795d594fSAndroid Build Coastguard Worker         field_idx, obj, new_value, GetReferrer(self), self);                   \
254*795d594fSAndroid Build Coastguard Worker   }
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker // Define these functions:
257*795d594fSAndroid Build Coastguard Worker //
258*795d594fSAndroid Build Coastguard Worker //   artGetByteStaticFromCode
259*795d594fSAndroid Build Coastguard Worker //   artGetByteInstanceFromCode
260*795d594fSAndroid Build Coastguard Worker //   artSetByteStaticFromCode
261*795d594fSAndroid Build Coastguard Worker //   artSetByteInstanceFromCode
262*795d594fSAndroid Build Coastguard Worker //   artGetByteStaticFromCompiledCode
263*795d594fSAndroid Build Coastguard Worker //   artGetByteInstanceFromCompiledCode
264*795d594fSAndroid Build Coastguard Worker //   artSetByteStaticFromCompiledCode
265*795d594fSAndroid Build Coastguard Worker //   artSetByteInstanceFromCompiledCode
266*795d594fSAndroid Build Coastguard Worker //
267*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(Byte, ssize_t, uint32_t, Primitive, false, )
268*795d594fSAndroid Build Coastguard Worker 
269*795d594fSAndroid Build Coastguard Worker // Define these functions:
270*795d594fSAndroid Build Coastguard Worker //
271*795d594fSAndroid Build Coastguard Worker //   artGetBooleanStaticFromCode
272*795d594fSAndroid Build Coastguard Worker //   artGetBooleanInstanceFromCode
273*795d594fSAndroid Build Coastguard Worker //   artSetBooleanStaticFromCode
274*795d594fSAndroid Build Coastguard Worker //   artSetBooleanInstanceFromCode
275*795d594fSAndroid Build Coastguard Worker //   artGetBooleanStaticFromCompiledCode
276*795d594fSAndroid Build Coastguard Worker //   artGetBooleanInstanceFromCompiledCode
277*795d594fSAndroid Build Coastguard Worker //   artSetBooleanStaticFromCompiledCode
278*795d594fSAndroid Build Coastguard Worker //   artSetBooleanInstanceFromCompiledCode
279*795d594fSAndroid Build Coastguard Worker //
280*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(Boolean, size_t, uint32_t, Primitive, false, )
281*795d594fSAndroid Build Coastguard Worker 
282*795d594fSAndroid Build Coastguard Worker // Define these functions:
283*795d594fSAndroid Build Coastguard Worker //
284*795d594fSAndroid Build Coastguard Worker //   artGetShortStaticFromCode
285*795d594fSAndroid Build Coastguard Worker //   artGetShortInstanceFromCode
286*795d594fSAndroid Build Coastguard Worker //   artSetShortStaticFromCode
287*795d594fSAndroid Build Coastguard Worker //   artSetShortInstanceFromCode
288*795d594fSAndroid Build Coastguard Worker //   artGetShortStaticFromCompiledCode
289*795d594fSAndroid Build Coastguard Worker //   artGetShortInstanceFromCompiledCode
290*795d594fSAndroid Build Coastguard Worker //   artSetShortStaticFromCompiledCode
291*795d594fSAndroid Build Coastguard Worker //   artSetShortInstanceFromCompiledCode
292*795d594fSAndroid Build Coastguard Worker //
293*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(Short, ssize_t, uint16_t, Primitive, false, )
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker // Define these functions:
296*795d594fSAndroid Build Coastguard Worker //
297*795d594fSAndroid Build Coastguard Worker //   artGetCharStaticFromCode
298*795d594fSAndroid Build Coastguard Worker //   artGetCharInstanceFromCode
299*795d594fSAndroid Build Coastguard Worker //   artSetCharStaticFromCode
300*795d594fSAndroid Build Coastguard Worker //   artSetCharInstanceFromCode
301*795d594fSAndroid Build Coastguard Worker //   artGetCharStaticFromCompiledCode
302*795d594fSAndroid Build Coastguard Worker //   artGetCharInstanceFromCompiledCode
303*795d594fSAndroid Build Coastguard Worker //   artSetCharStaticFromCompiledCode
304*795d594fSAndroid Build Coastguard Worker //   artSetCharInstanceFromCompiledCode
305*795d594fSAndroid Build Coastguard Worker //
306*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(Char, size_t, uint16_t, Primitive, false, )
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker // Define these functions:
309*795d594fSAndroid Build Coastguard Worker //
310*795d594fSAndroid Build Coastguard Worker //   artGet32StaticFromCode
311*795d594fSAndroid Build Coastguard Worker //   artGet32InstanceFromCode
312*795d594fSAndroid Build Coastguard Worker //   artSet32StaticFromCode
313*795d594fSAndroid Build Coastguard Worker //   artSet32InstanceFromCode
314*795d594fSAndroid Build Coastguard Worker //   artGet32StaticFromCompiledCode
315*795d594fSAndroid Build Coastguard Worker //   artGet32InstanceFromCompiledCode
316*795d594fSAndroid Build Coastguard Worker //   artSet32StaticFromCompiledCode
317*795d594fSAndroid Build Coastguard Worker //   artSet32InstanceFromCompiledCode
318*795d594fSAndroid Build Coastguard Worker //
319*795d594fSAndroid Build Coastguard Worker #if defined(__riscv)
320*795d594fSAndroid Build Coastguard Worker // On riscv64 we need to sign-extend `int` values to the full 64-bit register.
321*795d594fSAndroid Build Coastguard Worker // `ArtField::Get32()` returns a `uint32_t`, so let the getters return the same,
322*795d594fSAndroid Build Coastguard Worker // allowing the sign-extension specified by the RISC-V native calling convention:
323*795d594fSAndroid Build Coastguard Worker //     "[I]nteger scalars narrower than XLEN bits are widened according to the
324*795d594fSAndroid Build Coastguard Worker //     sign of their type up to 32 bits, then sign-extended to XLEN bits."
325*795d594fSAndroid Build Coastguard Worker // This is OK for `float` as the compiled code shall transfer it using FMV.W.X,
326*795d594fSAndroid Build Coastguard Worker // ignoring the upper 32 bits.
327*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(32, uint32_t, uint32_t, Primitive, false, )
328*795d594fSAndroid Build Coastguard Worker #else
329*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(32, size_t, uint32_t, Primitive, false, )
330*795d594fSAndroid Build Coastguard Worker #endif
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker // Define these functions:
333*795d594fSAndroid Build Coastguard Worker //
334*795d594fSAndroid Build Coastguard Worker //   artGet64StaticFromCode
335*795d594fSAndroid Build Coastguard Worker //   artGet64InstanceFromCode
336*795d594fSAndroid Build Coastguard Worker //   artSet64StaticFromCode
337*795d594fSAndroid Build Coastguard Worker //   artSet64InstanceFromCode
338*795d594fSAndroid Build Coastguard Worker //   artGet64StaticFromCompiledCode
339*795d594fSAndroid Build Coastguard Worker //   artGet64InstanceFromCompiledCode
340*795d594fSAndroid Build Coastguard Worker //   artSet64StaticFromCompiledCode
341*795d594fSAndroid Build Coastguard Worker //   artSet64InstanceFromCompiledCode
342*795d594fSAndroid Build Coastguard Worker //
343*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(64, uint64_t, uint64_t, Primitive, false, )
344*795d594fSAndroid Build Coastguard Worker 
345*795d594fSAndroid Build Coastguard Worker // Define these functions:
346*795d594fSAndroid Build Coastguard Worker //
347*795d594fSAndroid Build Coastguard Worker //   artGetObjStaticFromCode
348*795d594fSAndroid Build Coastguard Worker //   artGetObjInstanceFromCode
349*795d594fSAndroid Build Coastguard Worker //   artSetObjStaticFromCode
350*795d594fSAndroid Build Coastguard Worker //   artSetObjInstanceFromCode
351*795d594fSAndroid Build Coastguard Worker //   artGetObjStaticFromCompiledCode
352*795d594fSAndroid Build Coastguard Worker //   artGetObjInstanceFromCompiledCode
353*795d594fSAndroid Build Coastguard Worker //   artSetObjStaticFromCompiledCode
354*795d594fSAndroid Build Coastguard Worker //   artSetObjInstanceFromCompiledCode
355*795d594fSAndroid Build Coastguard Worker //
356*795d594fSAndroid Build Coastguard Worker ART_GET_FIELD_FROM_CODE(Obj, mirror::Object*, mirror::Object*, Object, true, .Ptr())
357*795d594fSAndroid Build Coastguard Worker 
358*795d594fSAndroid Build Coastguard Worker #undef ART_GET_FIELD_FROM_CODE
359*795d594fSAndroid Build Coastguard Worker 
360*795d594fSAndroid Build Coastguard Worker 
361*795d594fSAndroid Build Coastguard Worker // To cut on the number of entrypoints, we have shared entries for
362*795d594fSAndroid Build Coastguard Worker // byte/boolean and char/short for setting an instance or static field. We just
363*795d594fSAndroid Build Coastguard Worker // forward those to the unsigned variant.
artSet8StaticFromCompiledCode(uint32_t field_idx,uint32_t new_value,Thread * self)364*795d594fSAndroid Build Coastguard Worker extern "C" int artSet8StaticFromCompiledCode(uint32_t field_idx,
365*795d594fSAndroid Build Coastguard Worker                                              uint32_t new_value,
366*795d594fSAndroid Build Coastguard Worker                                              Thread* self)
367*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
368*795d594fSAndroid Build Coastguard Worker   return artSetBooleanStaticFromCode(field_idx, new_value, GetReferrer(self), self);
369*795d594fSAndroid Build Coastguard Worker }
370*795d594fSAndroid Build Coastguard Worker 
artSet16StaticFromCompiledCode(uint32_t field_idx,uint16_t new_value,Thread * self)371*795d594fSAndroid Build Coastguard Worker extern "C" int artSet16StaticFromCompiledCode(uint32_t field_idx,
372*795d594fSAndroid Build Coastguard Worker                                               uint16_t new_value,
373*795d594fSAndroid Build Coastguard Worker                                               Thread* self)
374*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
375*795d594fSAndroid Build Coastguard Worker   return artSetCharStaticFromCode(field_idx, new_value, GetReferrer(self), self);
376*795d594fSAndroid Build Coastguard Worker }
377*795d594fSAndroid Build Coastguard Worker 
artSet8InstanceFromCompiledCode(uint32_t field_idx,mirror::Object * obj,uint8_t new_value,Thread * self)378*795d594fSAndroid Build Coastguard Worker extern "C" int artSet8InstanceFromCompiledCode(uint32_t field_idx,
379*795d594fSAndroid Build Coastguard Worker                                                mirror::Object* obj,
380*795d594fSAndroid Build Coastguard Worker                                                uint8_t new_value,
381*795d594fSAndroid Build Coastguard Worker                                                Thread* self)
382*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
383*795d594fSAndroid Build Coastguard Worker   return artSetBooleanInstanceFromCode(field_idx, obj, new_value, GetReferrer(self), self);
384*795d594fSAndroid Build Coastguard Worker }
385*795d594fSAndroid Build Coastguard Worker 
artSet16InstanceFromCompiledCode(uint32_t field_idx,mirror::Object * obj,uint16_t new_value,Thread * self)386*795d594fSAndroid Build Coastguard Worker extern "C" int artSet16InstanceFromCompiledCode(uint32_t field_idx,
387*795d594fSAndroid Build Coastguard Worker                                                 mirror::Object* obj,
388*795d594fSAndroid Build Coastguard Worker                                                 uint16_t new_value,
389*795d594fSAndroid Build Coastguard Worker                                                 Thread* self)
390*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
391*795d594fSAndroid Build Coastguard Worker   return artSetCharInstanceFromCode(field_idx, obj, new_value, GetReferrer(self), self);
392*795d594fSAndroid Build Coastguard Worker }
393*795d594fSAndroid Build Coastguard Worker 
artSet8StaticFromCode(uint32_t field_idx,uint32_t new_value,ArtMethod * referrer,Thread * self)394*795d594fSAndroid Build Coastguard Worker extern "C" int artSet8StaticFromCode(uint32_t field_idx,
395*795d594fSAndroid Build Coastguard Worker                                      uint32_t new_value,
396*795d594fSAndroid Build Coastguard Worker                                      ArtMethod* referrer,
397*795d594fSAndroid Build Coastguard Worker                                      Thread* self)
398*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
399*795d594fSAndroid Build Coastguard Worker   return artSetBooleanStaticFromCode(field_idx, new_value, referrer, self);
400*795d594fSAndroid Build Coastguard Worker }
401*795d594fSAndroid Build Coastguard Worker 
artSet16StaticFromCode(uint32_t field_idx,uint16_t new_value,ArtMethod * referrer,Thread * self)402*795d594fSAndroid Build Coastguard Worker extern "C" int artSet16StaticFromCode(uint32_t field_idx,
403*795d594fSAndroid Build Coastguard Worker                                       uint16_t new_value,
404*795d594fSAndroid Build Coastguard Worker                                       ArtMethod* referrer,
405*795d594fSAndroid Build Coastguard Worker                                       Thread* self)
406*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
407*795d594fSAndroid Build Coastguard Worker   return artSetCharStaticFromCode(field_idx, new_value, referrer, self);
408*795d594fSAndroid Build Coastguard Worker }
409*795d594fSAndroid Build Coastguard Worker 
artSet8InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint8_t new_value,ArtMethod * referrer,Thread * self)410*795d594fSAndroid Build Coastguard Worker extern "C" int artSet8InstanceFromCode(uint32_t field_idx,
411*795d594fSAndroid Build Coastguard Worker                                        mirror::Object* obj,
412*795d594fSAndroid Build Coastguard Worker                                        uint8_t new_value,
413*795d594fSAndroid Build Coastguard Worker                                        ArtMethod* referrer,
414*795d594fSAndroid Build Coastguard Worker                                        Thread* self)
415*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
416*795d594fSAndroid Build Coastguard Worker   return artSetBooleanInstanceFromCode(field_idx, obj, new_value, referrer, self);
417*795d594fSAndroid Build Coastguard Worker }
418*795d594fSAndroid Build Coastguard Worker 
artSet16InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint16_t new_value,ArtMethod * referrer,Thread * self)419*795d594fSAndroid Build Coastguard Worker extern "C" int artSet16InstanceFromCode(uint32_t field_idx,
420*795d594fSAndroid Build Coastguard Worker                                         mirror::Object* obj,
421*795d594fSAndroid Build Coastguard Worker                                         uint16_t new_value,
422*795d594fSAndroid Build Coastguard Worker                                         ArtMethod* referrer,
423*795d594fSAndroid Build Coastguard Worker                                         Thread* self)
424*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
425*795d594fSAndroid Build Coastguard Worker   return artSetCharInstanceFromCode(field_idx, obj, new_value, referrer, self);
426*795d594fSAndroid Build Coastguard Worker }
427*795d594fSAndroid Build Coastguard Worker 
428*795d594fSAndroid Build Coastguard Worker // Read barrier entrypoints.
429*795d594fSAndroid Build Coastguard Worker //
430*795d594fSAndroid Build Coastguard Worker // Compilers for ARM, ARM64 can insert a call to these
431*795d594fSAndroid Build Coastguard Worker // functions directly.  For x86 and x86-64, compilers need a wrapper
432*795d594fSAndroid Build Coastguard Worker // assembly function, to handle mismatch in ABI.
433*795d594fSAndroid Build Coastguard Worker 
434*795d594fSAndroid Build Coastguard Worker // Mark the heap reference `obj`. This entry point is used by read
435*795d594fSAndroid Build Coastguard Worker // barrier fast path implementations generated by the compiler to mark
436*795d594fSAndroid Build Coastguard Worker // an object that is referenced by a field of a gray object.
artReadBarrierMark(mirror::Object * obj)437*795d594fSAndroid Build Coastguard Worker extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj)
438*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
439*795d594fSAndroid Build Coastguard Worker   DCHECK(gUseReadBarrier);
440*795d594fSAndroid Build Coastguard Worker   return ReadBarrier::Mark(obj);
441*795d594fSAndroid Build Coastguard Worker }
442*795d594fSAndroid Build Coastguard Worker 
443*795d594fSAndroid Build Coastguard Worker // Read barrier entrypoint for heap references.
444*795d594fSAndroid Build Coastguard Worker // This is the read barrier slow path for instance and static fields
445*795d594fSAndroid Build Coastguard Worker // and reference type arrays.
artReadBarrierSlow(mirror::Object * ref,mirror::Object * obj,uint32_t offset)446*795d594fSAndroid Build Coastguard Worker extern "C" mirror::Object* artReadBarrierSlow([[maybe_unused]] mirror::Object* ref,
447*795d594fSAndroid Build Coastguard Worker                                               mirror::Object* obj,
448*795d594fSAndroid Build Coastguard Worker                                               uint32_t offset)
449*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
450*795d594fSAndroid Build Coastguard Worker   // Used only in connection with non-volatile loads.
451*795d594fSAndroid Build Coastguard Worker   DCHECK(gUseReadBarrier);
452*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(obj) + offset;
453*795d594fSAndroid Build Coastguard Worker   mirror::HeapReference<mirror::Object>* ref_addr =
454*795d594fSAndroid Build Coastguard Worker      reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
455*795d594fSAndroid Build Coastguard Worker   mirror::Object* result =
456*795d594fSAndroid Build Coastguard Worker       ReadBarrier::Barrier<mirror::Object, /* kIsVolatile= */ false, kWithReadBarrier>(
457*795d594fSAndroid Build Coastguard Worker         obj,
458*795d594fSAndroid Build Coastguard Worker         MemberOffset(offset),
459*795d594fSAndroid Build Coastguard Worker         ref_addr);
460*795d594fSAndroid Build Coastguard Worker   return result;
461*795d594fSAndroid Build Coastguard Worker }
462*795d594fSAndroid Build Coastguard Worker 
463*795d594fSAndroid Build Coastguard Worker // Read barrier entrypoint for GC roots.
artReadBarrierForRootSlow(GcRoot<mirror::Object> * root)464*795d594fSAndroid Build Coastguard Worker extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root)
465*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
466*795d594fSAndroid Build Coastguard Worker   DCHECK(gUseReadBarrier);
467*795d594fSAndroid Build Coastguard Worker   return root->Read();
468*795d594fSAndroid Build Coastguard Worker }
469*795d594fSAndroid Build Coastguard Worker 
470*795d594fSAndroid Build Coastguard Worker }  // namespace art
471