blob: 6bf93ce15a36bb1f34ab9afe95024026ac935fc3 [file] [log] [blame]
Barry Hayes7ef07552010-06-25 13:36:37 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17/*
18 * Helper functions to access data fields in Objects.
19 */
Barry Hayes0dfa7bf2010-06-25 13:50:29 -070020#ifndef _DALVIK_OO_OBJECTINLINES
21#define _DALVIK_OO_OBJECTINLINES
Barry Hayes7ef07552010-06-25 13:36:37 -070022
23/*
Barry Hayes4ac66a92010-07-09 08:50:19 -070024 * Store a single value in the array, and if the value isn't null,
25 * note in the write barrier.
Barry Hayes7ef07552010-06-25 13:36:37 -070026 */
27INLINE void dvmSetObjectArrayElement(const ArrayObject* obj, int index,
28 Object* val) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -080029 ((Object **)(void *)(obj)->contents)[index] = val;
Barry Hayes4ac66a92010-07-09 08:50:19 -070030 if (val != NULL) {
31 dvmWriteBarrierArray(obj, index, index + 1);
32 }
Barry Hayes7ef07552010-06-25 13:36:37 -070033}
34
35
36/*
37 * Field access functions. Pass in the word offset from Field->byteOffset.
38 *
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.
41 *
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.
Barry Hayes4ac66a92010-07-09 08:50:19 -070044 *
45 * Setting Object types to non-null values includes a call to the
46 * write barrier.
Barry Hayes7ef07552010-06-25 13:36:37 -070047 */
48#define BYTE_OFFSET(_ptr, _offset) ((void*) (((u1*)(_ptr)) + (_offset)))
49
50INLINE JValue* dvmFieldPtr(const Object* obj, int offset) {
51 return ((JValue*)BYTE_OFFSET(obj, offset));
52}
53
54INLINE bool dvmGetFieldBoolean(const Object* obj, int offset) {
55 return ((JValue*)BYTE_OFFSET(obj, offset))->z;
56}
57INLINE s1 dvmGetFieldByte(const Object* obj, int offset) {
58 return ((JValue*)BYTE_OFFSET(obj, offset))->b;
59}
60INLINE s2 dvmGetFieldShort(const Object* obj, int offset) {
61 return ((JValue*)BYTE_OFFSET(obj, offset))->s;
62}
63INLINE u2 dvmGetFieldChar(const Object* obj, int offset) {
64 return ((JValue*)BYTE_OFFSET(obj, offset))->c;
65}
66INLINE s4 dvmGetFieldInt(const Object* obj, int offset) {
67 return ((JValue*)BYTE_OFFSET(obj, offset))->i;
68}
69INLINE s8 dvmGetFieldLong(const Object* obj, int offset) {
70 return ((JValue*)BYTE_OFFSET(obj, offset))->j;
71}
72INLINE float dvmGetFieldFloat(const Object* obj, int offset) {
73 return ((JValue*)BYTE_OFFSET(obj, offset))->f;
74}
75INLINE double dvmGetFieldDouble(const Object* obj, int offset) {
76 return ((JValue*)BYTE_OFFSET(obj, offset))->d;
77}
78INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -080079 return (Object*)((JValue*)BYTE_OFFSET(obj, offset))->l;
Barry Hayes7ef07552010-06-25 13:36:37 -070080}
Andy McFaddenf16cfef2010-08-18 15:51:37 -070081INLINE bool dvmGetFieldBooleanVolatile(const Object* obj, int offset) {
82 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
83 return (bool)android_atomic_acquire_load(ptr);
84}
85INLINE s1 dvmGetFieldByteVolatile(const Object* obj, int offset) {
86 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
87 return (s1)android_atomic_acquire_load(ptr);
88}
89INLINE s2 dvmGetFieldShortVolatile(const Object* obj, int offset) {
90 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
91 return (s2)android_atomic_acquire_load(ptr);
92}
93INLINE u2 dvmGetFieldCharVolatile(const Object* obj, int offset) {
94 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
95 return (u2)android_atomic_acquire_load(ptr);
96}
Barry Hayes7ef07552010-06-25 13:36:37 -070097INLINE s4 dvmGetFieldIntVolatile(const Object* obj, int offset) {
98 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
99 return android_atomic_acquire_load(ptr);
100}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700101INLINE 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);
105 return alias.fval;
Barry Hayes7ef07552010-06-25 13:36:37 -0700106}
107INLINE s8 dvmGetFieldLongVolatile(const Object* obj, int offset) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800108 const s8* addr = (const s8*)BYTE_OFFSET(obj, offset);
Barry Hayes7ef07552010-06-25 13:36:37 -0700109 s8 val = dvmQuasiAtomicRead64(addr);
110 ANDROID_MEMBAR_FULL();
111 return val;
112}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700113INLINE double dvmGetFieldDoubleVolatile(const Object* obj, int offset) {
114 union { s8 lval; double dval; } alias;
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800115 const s8* addr = (const s8*)BYTE_OFFSET(obj, offset);
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700116 alias.lval = dvmQuasiAtomicRead64(addr);
117 ANDROID_MEMBAR_FULL();
118 return alias.dval;
119}
120INLINE Object* dvmGetFieldObjectVolatile(const Object* obj, int offset) {
121 void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
122 return (Object*)android_atomic_acquire_load((int32_t*)ptr);
123}
Barry Hayes7ef07552010-06-25 13:36:37 -0700124
125INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
126 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
127}
128INLINE void dvmSetFieldByte(Object* obj, int offset, s1 val) {
129 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
130}
131INLINE void dvmSetFieldShort(Object* obj, int offset, s2 val) {
132 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
133}
134INLINE void dvmSetFieldChar(Object* obj, int offset, u2 val) {
135 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
136}
137INLINE void dvmSetFieldInt(Object* obj, int offset, s4 val) {
138 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
139}
Barry Hayes7ef07552010-06-25 13:36:37 -0700140INLINE void dvmSetFieldFloat(Object* obj, int offset, float val) {
141 ((JValue*)BYTE_OFFSET(obj, offset))->f = val;
142}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700143INLINE void dvmSetFieldLong(Object* obj, int offset, s8 val) {
144 ((JValue*)BYTE_OFFSET(obj, offset))->j = val;
145}
Barry Hayes7ef07552010-06-25 13:36:37 -0700146INLINE void dvmSetFieldDouble(Object* obj, int offset, double val) {
147 ((JValue*)BYTE_OFFSET(obj, offset))->d = val;
148}
149INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800150 JValue* lhs = (JValue*)BYTE_OFFSET(obj, offset);
Barry Hayes7ef07552010-06-25 13:36:37 -0700151 lhs->l = val;
Barry Hayes4ac66a92010-07-09 08:50:19 -0700152 if (val != NULL) {
153 dvmWriteBarrierField(obj, &lhs->l);
154 }
Barry Hayes7ef07552010-06-25 13:36:37 -0700155}
156INLINE void dvmSetFieldIntVolatile(Object* obj, int offset, s4 val) {
157 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
158 android_atomic_release_store(val, ptr);
159}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700160INLINE void dvmSetFieldBooleanVolatile(Object* obj, int offset, bool val) {
161 dvmSetFieldIntVolatile(obj, offset, val);
162}
163INLINE void dvmSetFieldByteVolatile(Object* obj, int offset, s1 val) {
164 dvmSetFieldIntVolatile(obj, offset, val);
165}
166INLINE void dvmSetFieldShortVolatile(Object* obj, int offset, s2 val) {
167 dvmSetFieldIntVolatile(obj, offset, val);
168}
169INLINE void dvmSetFieldCharVolatile(Object* obj, int offset, u2 val) {
170 dvmSetFieldIntVolatile(obj, offset, val);
171}
172INLINE void dvmSetFieldFloatVolatile(Object* obj, int offset, float val) {
173 union { s4 ival; float fval; } alias;
174 alias.fval = val;
175 dvmSetFieldIntVolatile(obj, offset, alias.ival);
176}
177INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800178 s8* addr = (s8*)BYTE_OFFSET(obj, offset);
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700179 ANDROID_MEMBAR_FULL();
180 dvmQuasiAtomicSwap64(val, addr);
181}
182INLINE void dvmSetFieldDoubleVolatile(Object* obj, int offset, double val) {
183 union { s8 lval; double dval; } alias;
184 alias.dval = val;
185 dvmSetFieldLongVolatile(obj, offset, alias.lval);
186}
Barry Hayes7ef07552010-06-25 13:36:37 -0700187INLINE void dvmSetFieldObjectVolatile(Object* obj, int offset, Object* val) {
188 void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
189 android_atomic_release_store((int32_t)val, (int32_t*)ptr);
Barry Hayes4ac66a92010-07-09 08:50:19 -0700190 if (val != NULL) {
191 dvmWriteBarrierField(obj, ptr);
192 }
Barry Hayes7ef07552010-06-25 13:36:37 -0700193}
Barry Hayes7ef07552010-06-25 13:36:37 -0700194
195/*
196 * Static field access functions.
197 */
198INLINE JValue* dvmStaticFieldPtr(const StaticField* sfield) {
199 return (JValue*)&sfield->value;
200}
201
202INLINE bool dvmGetStaticFieldBoolean(const StaticField* sfield) {
203 return sfield->value.z;
204}
205INLINE s1 dvmGetStaticFieldByte(const StaticField* sfield) {
206 return sfield->value.b;
207}
208INLINE s2 dvmGetStaticFieldShort(const StaticField* sfield) {
209 return sfield->value.s;
210}
211INLINE u2 dvmGetStaticFieldChar(const StaticField* sfield) {
212 return sfield->value.c;
213}
214INLINE s4 dvmGetStaticFieldInt(const StaticField* sfield) {
215 return sfield->value.i;
216}
Barry Hayes7ef07552010-06-25 13:36:37 -0700217INLINE float dvmGetStaticFieldFloat(const StaticField* sfield) {
218 return sfield->value.f;
219}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700220INLINE s8 dvmGetStaticFieldLong(const StaticField* sfield) {
221 return sfield->value.j;
222}
Barry Hayes7ef07552010-06-25 13:36:37 -0700223INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) {
224 return sfield->value.d;
225}
226INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800227 return (Object*)sfield->value.l;
Barry Hayes7ef07552010-06-25 13:36:37 -0700228}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700229INLINE bool dvmGetStaticFieldBooleanVolatile(const StaticField* sfield) {
230 const s4* ptr = &(sfield->value.i);
231 return (bool)android_atomic_acquire_load((s4*)ptr);
232}
233INLINE s1 dvmGetStaticFieldByteVolatile(const StaticField* sfield) {
234 const s4* ptr = &(sfield->value.i);
235 return (s1)android_atomic_acquire_load((s4*)ptr);
236}
237INLINE s2 dvmGetStaticFieldShortVolatile(const StaticField* sfield) {
238 const s4* ptr = &(sfield->value.i);
239 return (s2)android_atomic_acquire_load((s4*)ptr);
240}
241INLINE u2 dvmGetStaticFieldCharVolatile(const StaticField* sfield) {
242 const s4* ptr = &(sfield->value.i);
243 return (u2)android_atomic_acquire_load((s4*)ptr);
244}
Barry Hayes7ef07552010-06-25 13:36:37 -0700245INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) {
246 const s4* ptr = &(sfield->value.i);
247 return android_atomic_acquire_load((s4*)ptr);
248}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700249INLINE float dvmGetStaticFieldFloatVolatile(const StaticField* sfield) {
250 union { s4 ival; float fval; } alias;
251 const s4* ptr = &(sfield->value.i);
252 alias.ival = android_atomic_acquire_load((s4*)ptr);
253 return alias.fval;
Barry Hayes7ef07552010-06-25 13:36:37 -0700254}
255INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
256 const s8* addr = &sfield->value.j;
257 s8 val = dvmQuasiAtomicRead64(addr);
258 ANDROID_MEMBAR_FULL();
259 return val;
260}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700261INLINE double dvmGetStaticFieldDoubleVolatile(const StaticField* sfield) {
262 union { s8 lval; double dval; } alias;
263 const s8* addr = &sfield->value.j;
264 alias.lval = dvmQuasiAtomicRead64(addr);
265 ANDROID_MEMBAR_FULL();
266 return alias.dval;
267}
268INLINE Object* dvmGetStaticFieldObjectVolatile(const StaticField* sfield) {
269 void* const* ptr = &(sfield->value.l);
270 return (Object*)android_atomic_acquire_load((int32_t*)ptr);
271}
Barry Hayes7ef07552010-06-25 13:36:37 -0700272
273INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
274 sfield->value.i = val;
275}
276INLINE void dvmSetStaticFieldByte(StaticField* sfield, s1 val) {
277 sfield->value.i = val;
278}
279INLINE void dvmSetStaticFieldShort(StaticField* sfield, s2 val) {
280 sfield->value.i = val;
281}
282INLINE void dvmSetStaticFieldChar(StaticField* sfield, u2 val) {
283 sfield->value.i = val;
284}
285INLINE void dvmSetStaticFieldInt(StaticField* sfield, s4 val) {
286 sfield->value.i = val;
287}
Barry Hayes7ef07552010-06-25 13:36:37 -0700288INLINE void dvmSetStaticFieldFloat(StaticField* sfield, float val) {
289 sfield->value.f = val;
290}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700291INLINE void dvmSetStaticFieldLong(StaticField* sfield, s8 val) {
292 sfield->value.j = val;
293}
Barry Hayes7ef07552010-06-25 13:36:37 -0700294INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) {
295 sfield->value.d = val;
296}
297INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
298 sfield->value.l = val;
Barry Hayes4ac66a92010-07-09 08:50:19 -0700299 if (val != NULL) {
300 dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l);
301 }
Barry Hayes7ef07552010-06-25 13:36:37 -0700302}
303INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) {
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700304 s4* ptr = &sfield->value.i;
Barry Hayes7ef07552010-06-25 13:36:37 -0700305 android_atomic_release_store(val, ptr);
306}
Andy McFaddenf16cfef2010-08-18 15:51:37 -0700307INLINE void dvmSetStaticFieldBooleanVolatile(StaticField* sfield, bool val) {
308 dvmSetStaticFieldIntVolatile(sfield, val);
309}
310INLINE void dvmSetStaticFieldByteVolatile(StaticField* sfield, s1 val) {
311 dvmSetStaticFieldIntVolatile(sfield, val);
312}
313INLINE void dvmSetStaticFieldShortVolatile(StaticField* sfield, s2 val) {
314 dvmSetStaticFieldIntVolatile(sfield, val);
315}
316INLINE void dvmSetStaticFieldCharVolatile(StaticField* sfield, u2 val) {
317 dvmSetStaticFieldIntVolatile(sfield, val);
318}
319INLINE void dvmSetStaticFieldFloatVolatile(StaticField* sfield, float val) {
320 union { s4 ival; float fval; } alias;
321 alias.fval = val;
322 dvmSetStaticFieldIntVolatile(sfield, alias.ival);
323}
324INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
325 s8* addr = &sfield->value.j;
326 ANDROID_MEMBAR_FULL();
327 dvmQuasiAtomicSwap64(val, addr);
328}
329INLINE void dvmSetStaticFieldDoubleVolatile(StaticField* sfield, double val) {
330 union { s8 lval; double dval; } alias;
331 alias.dval = val;
332 dvmSetStaticFieldLongVolatile(sfield, alias.lval);
333}
Barry Hayes7ef07552010-06-25 13:36:37 -0700334INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
335 void** ptr = &(sfield->value.l);
336 android_atomic_release_store((int32_t)val, (int32_t*)ptr);
Barry Hayes4ac66a92010-07-09 08:50:19 -0700337 if (val != NULL) {
338 dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l);
339 }
Barry Hayes7ef07552010-06-25 13:36:37 -0700340}
Barry Hayes7ef07552010-06-25 13:36:37 -0700341
Barry Hayes0dfa7bf2010-06-25 13:50:29 -0700342#endif /*_DALVIK_OO_OBJECTINLINES*/