2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Helper functions to access data fields in Objects.
20 #ifndef DALVIK_OO_OBJECTINLINES_H_
21 #define DALVIK_OO_OBJECTINLINES_H_
24 * Store a single value in the array, and if the value isn't null,
25 * note in the write barrier.
27 INLINE void dvmSetObjectArrayElement(const ArrayObject* obj, int index,
29 ((Object **)(void *)(obj)->contents)[index] = val;
31 dvmWriteBarrierArray(obj, index, index + 1);
37 * Field access functions. Pass in the word offset from Field->byteOffset.
39 * We guarantee that long/double field data is 64-bit aligned, so it's safe
40 * to access them with ldrd/strd on ARM.
42 * The VM treats all fields as 32 or 64 bits, so the field set functions
43 * write 32 bits even if the underlying type is smaller.
45 * Setting Object types to non-null values includes a call to the
48 #define BYTE_OFFSET(_ptr, _offset) ((void*) (((u1*)(_ptr)) + (_offset)))
50 INLINE JValue* dvmFieldPtr(const Object* obj, int offset) {
51 return ((JValue*)BYTE_OFFSET(obj, offset));
54 INLINE bool dvmGetFieldBoolean(const Object* obj, int offset) {
55 return ((JValue*)BYTE_OFFSET(obj, offset))->z;
57 INLINE s1 dvmGetFieldByte(const Object* obj, int offset) {
58 return ((JValue*)BYTE_OFFSET(obj, offset))->b;
60 INLINE s2 dvmGetFieldShort(const Object* obj, int offset) {
61 return ((JValue*)BYTE_OFFSET(obj, offset))->s;
63 INLINE u2 dvmGetFieldChar(const Object* obj, int offset) {
64 return ((JValue*)BYTE_OFFSET(obj, offset))->c;
66 INLINE s4 dvmGetFieldInt(const Object* obj, int offset) {
67 return ((JValue*)BYTE_OFFSET(obj, offset))->i;
69 INLINE s8 dvmGetFieldLong(const Object* obj, int offset) {
70 return ((JValue*)BYTE_OFFSET(obj, offset))->j;
72 INLINE float dvmGetFieldFloat(const Object* obj, int offset) {
73 return ((JValue*)BYTE_OFFSET(obj, offset))->f;
75 INLINE double dvmGetFieldDouble(const Object* obj, int offset) {
76 return ((JValue*)BYTE_OFFSET(obj, offset))->d;
78 INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
79 return ((JValue*)BYTE_OFFSET(obj, offset))->l;
81 INLINE bool dvmGetFieldBooleanVolatile(const Object* obj, int offset) {
82 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
83 return (bool)android_atomic_acquire_load(ptr);
85 INLINE s1 dvmGetFieldByteVolatile(const Object* obj, int offset) {
86 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
87 return (s1)android_atomic_acquire_load(ptr);
89 INLINE s2 dvmGetFieldShortVolatile(const Object* obj, int offset) {
90 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
91 return (s2)android_atomic_acquire_load(ptr);
93 INLINE u2 dvmGetFieldCharVolatile(const Object* obj, int offset) {
94 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
95 return (u2)android_atomic_acquire_load(ptr);
97 INLINE s4 dvmGetFieldIntVolatile(const Object* obj, int offset) {
98 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
99 return android_atomic_acquire_load(ptr);
101 INLINE float dvmGetFieldFloatVolatile(const Object* obj, int offset) {
102 union { s4 ival; float fval; } alias;
103 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
104 alias.ival = android_atomic_acquire_load(ptr);
107 INLINE s8 dvmGetFieldLongVolatile(const Object* obj, int offset) {
108 const s8* addr = (const s8*)BYTE_OFFSET(obj, offset);
109 s8 val = dvmQuasiAtomicRead64(addr);
110 ANDROID_MEMBAR_FULL();
113 INLINE double dvmGetFieldDoubleVolatile(const Object* obj, int offset) {
114 union { s8 lval; double dval; } alias;
115 const s8* addr = (const s8*)BYTE_OFFSET(obj, offset);
116 alias.lval = dvmQuasiAtomicRead64(addr);
117 ANDROID_MEMBAR_FULL();
120 INLINE Object* dvmGetFieldObjectVolatile(const Object* obj, int offset) {
121 Object** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
122 return (Object*)android_atomic_acquire_load((int32_t*)ptr);
125 INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
126 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
128 INLINE void dvmSetFieldByte(Object* obj, int offset, s1 val) {
129 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
131 INLINE void dvmSetFieldShort(Object* obj, int offset, s2 val) {
132 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
134 INLINE void dvmSetFieldChar(Object* obj, int offset, u2 val) {
135 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
137 INLINE void dvmSetFieldInt(Object* obj, int offset, s4 val) {
138 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
140 INLINE void dvmSetFieldFloat(Object* obj, int offset, float val) {
141 ((JValue*)BYTE_OFFSET(obj, offset))->f = val;
143 INLINE void dvmSetFieldLong(Object* obj, int offset, s8 val) {
144 ((JValue*)BYTE_OFFSET(obj, offset))->j = val;
146 INLINE void dvmSetFieldDouble(Object* obj, int offset, double val) {
147 ((JValue*)BYTE_OFFSET(obj, offset))->d = val;
149 INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
150 JValue* lhs = (JValue*)BYTE_OFFSET(obj, offset);
153 dvmWriteBarrierField(obj, &lhs->l);
156 INLINE void dvmSetFieldIntVolatile(Object* obj, int offset, s4 val) {
157 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
159 * TODO: add an android_atomic_synchronization_store() function and
160 * use it in the 32-bit volatile set handlers. On some platforms we
161 * can use a fast atomic instruction and avoid the barriers.
163 ANDROID_MEMBAR_STORE();
165 ANDROID_MEMBAR_FULL();
167 INLINE void dvmSetFieldBooleanVolatile(Object* obj, int offset, bool val) {
168 dvmSetFieldIntVolatile(obj, offset, val);
170 INLINE void dvmSetFieldByteVolatile(Object* obj, int offset, s1 val) {
171 dvmSetFieldIntVolatile(obj, offset, val);
173 INLINE void dvmSetFieldShortVolatile(Object* obj, int offset, s2 val) {
174 dvmSetFieldIntVolatile(obj, offset, val);
176 INLINE void dvmSetFieldCharVolatile(Object* obj, int offset, u2 val) {
177 dvmSetFieldIntVolatile(obj, offset, val);
179 INLINE void dvmSetFieldFloatVolatile(Object* obj, int offset, float val) {
180 union { s4 ival; float fval; } alias;
182 dvmSetFieldIntVolatile(obj, offset, alias.ival);
184 INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
185 s8* addr = (s8*)BYTE_OFFSET(obj, offset);
186 dvmQuasiAtomicSwap64Sync(val, addr);
188 INLINE void dvmSetFieldDoubleVolatile(Object* obj, int offset, double val) {
189 union { s8 lval; double dval; } alias;
191 dvmSetFieldLongVolatile(obj, offset, alias.lval);
193 INLINE void dvmSetFieldObjectVolatile(Object* obj, int offset, Object* val) {
194 Object** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
195 ANDROID_MEMBAR_STORE();
197 ANDROID_MEMBAR_FULL();
199 dvmWriteBarrierField(obj, ptr);
204 * Static field access functions.
206 INLINE JValue* dvmStaticFieldPtr(const StaticField* sfield) {
207 return (JValue*)&sfield->value;
210 INLINE bool dvmGetStaticFieldBoolean(const StaticField* sfield) {
211 return sfield->value.z;
213 INLINE s1 dvmGetStaticFieldByte(const StaticField* sfield) {
214 return sfield->value.b;
216 INLINE s2 dvmGetStaticFieldShort(const StaticField* sfield) {
217 return sfield->value.s;
219 INLINE u2 dvmGetStaticFieldChar(const StaticField* sfield) {
220 return sfield->value.c;
222 INLINE s4 dvmGetStaticFieldInt(const StaticField* sfield) {
223 return sfield->value.i;
225 INLINE float dvmGetStaticFieldFloat(const StaticField* sfield) {
226 return sfield->value.f;
228 INLINE s8 dvmGetStaticFieldLong(const StaticField* sfield) {
229 return sfield->value.j;
231 INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) {
232 return sfield->value.d;
234 INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
235 return sfield->value.l;
237 INLINE bool dvmGetStaticFieldBooleanVolatile(const StaticField* sfield) {
238 const s4* ptr = &(sfield->value.i);
239 return (bool)android_atomic_acquire_load((s4*)ptr);
241 INLINE s1 dvmGetStaticFieldByteVolatile(const StaticField* sfield) {
242 const s4* ptr = &(sfield->value.i);
243 return (s1)android_atomic_acquire_load((s4*)ptr);
245 INLINE s2 dvmGetStaticFieldShortVolatile(const StaticField* sfield) {
246 const s4* ptr = &(sfield->value.i);
247 return (s2)android_atomic_acquire_load((s4*)ptr);
249 INLINE u2 dvmGetStaticFieldCharVolatile(const StaticField* sfield) {
250 const s4* ptr = &(sfield->value.i);
251 return (u2)android_atomic_acquire_load((s4*)ptr);
253 INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) {
254 const s4* ptr = &(sfield->value.i);
255 return android_atomic_acquire_load((s4*)ptr);
257 INLINE float dvmGetStaticFieldFloatVolatile(const StaticField* sfield) {
258 union { s4 ival; float fval; } alias;
259 const s4* ptr = &(sfield->value.i);
260 alias.ival = android_atomic_acquire_load((s4*)ptr);
263 INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
264 const s8* addr = &sfield->value.j;
265 s8 val = dvmQuasiAtomicRead64(addr);
266 ANDROID_MEMBAR_FULL();
269 INLINE double dvmGetStaticFieldDoubleVolatile(const StaticField* sfield) {
270 union { s8 lval; double dval; } alias;
271 const s8* addr = &sfield->value.j;
272 alias.lval = dvmQuasiAtomicRead64(addr);
273 ANDROID_MEMBAR_FULL();
276 INLINE Object* dvmGetStaticFieldObjectVolatile(const StaticField* sfield) {
277 Object* const* ptr = &(sfield->value.l);
278 return (Object*)android_atomic_acquire_load((int32_t*)ptr);
281 INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
282 sfield->value.i = val;
284 INLINE void dvmSetStaticFieldByte(StaticField* sfield, s1 val) {
285 sfield->value.i = val;
287 INLINE void dvmSetStaticFieldShort(StaticField* sfield, s2 val) {
288 sfield->value.i = val;
290 INLINE void dvmSetStaticFieldChar(StaticField* sfield, u2 val) {
291 sfield->value.i = val;
293 INLINE void dvmSetStaticFieldInt(StaticField* sfield, s4 val) {
294 sfield->value.i = val;
296 INLINE void dvmSetStaticFieldFloat(StaticField* sfield, float val) {
297 sfield->value.f = val;
299 INLINE void dvmSetStaticFieldLong(StaticField* sfield, s8 val) {
300 sfield->value.j = val;
302 INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) {
303 sfield->value.d = val;
305 INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
306 sfield->value.l = val;
308 dvmWriteBarrierField(sfield->clazz, &sfield->value.l);
311 INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) {
312 s4* ptr = &sfield->value.i;
313 ANDROID_MEMBAR_STORE();
315 ANDROID_MEMBAR_FULL();
317 INLINE void dvmSetStaticFieldBooleanVolatile(StaticField* sfield, bool val) {
318 dvmSetStaticFieldIntVolatile(sfield, val);
320 INLINE void dvmSetStaticFieldByteVolatile(StaticField* sfield, s1 val) {
321 dvmSetStaticFieldIntVolatile(sfield, val);
323 INLINE void dvmSetStaticFieldShortVolatile(StaticField* sfield, s2 val) {
324 dvmSetStaticFieldIntVolatile(sfield, val);
326 INLINE void dvmSetStaticFieldCharVolatile(StaticField* sfield, u2 val) {
327 dvmSetStaticFieldIntVolatile(sfield, val);
329 INLINE void dvmSetStaticFieldFloatVolatile(StaticField* sfield, float val) {
330 union { s4 ival; float fval; } alias;
332 dvmSetStaticFieldIntVolatile(sfield, alias.ival);
334 INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
335 s8* addr = &sfield->value.j;
336 dvmQuasiAtomicSwap64Sync(val, addr);
338 INLINE void dvmSetStaticFieldDoubleVolatile(StaticField* sfield, double val) {
339 union { s8 lval; double dval; } alias;
341 dvmSetStaticFieldLongVolatile(sfield, alias.lval);
343 INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
344 Object** ptr = &(sfield->value.l);
345 ANDROID_MEMBAR_STORE();
347 ANDROID_MEMBAR_FULL();
349 dvmWriteBarrierField(sfield->clazz, &sfield->value.l);
353 #endif // DALVIK_OO_OBJECTINLINES_H_