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