OSDN Git Service

Merge "Fix inner class access flags and array modifiers."
[android-x86/dalvik.git] / vm / oo / ObjectInlines.h
1 /*
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  */
20 #ifndef DALVIK_OO_OBJECTINLINES_H_
21 #define DALVIK_OO_OBJECTINLINES_H_
22
23 /*
24  * Store a single value in the array, and if the value isn't null,
25  * note in the write barrier.
26  */
27 INLINE void dvmSetObjectArrayElement(const ArrayObject* obj, int index,
28                                      Object* val) {
29     ((Object **)(void *)(obj)->contents)[index] = val;
30     if (val != NULL) {
31         dvmWriteBarrierArray(obj, index, index + 1);
32     }
33 }
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.
44  *
45  * Setting Object types to non-null values includes a call to the
46  * write barrier.
47  */
48 #define BYTE_OFFSET(_ptr, _offset)  ((void*) (((u1*)(_ptr)) + (_offset)))
49
50 INLINE JValue* dvmFieldPtr(const Object* obj, int offset) {
51     return ((JValue*)BYTE_OFFSET(obj, offset));
52 }
53
54 INLINE bool dvmGetFieldBoolean(const Object* obj, int offset) {
55     return ((JValue*)BYTE_OFFSET(obj, offset))->z;
56 }
57 INLINE s1 dvmGetFieldByte(const Object* obj, int offset) {
58     return ((JValue*)BYTE_OFFSET(obj, offset))->b;
59 }
60 INLINE s2 dvmGetFieldShort(const Object* obj, int offset) {
61     return ((JValue*)BYTE_OFFSET(obj, offset))->s;
62 }
63 INLINE u2 dvmGetFieldChar(const Object* obj, int offset) {
64     return ((JValue*)BYTE_OFFSET(obj, offset))->c;
65 }
66 INLINE s4 dvmGetFieldInt(const Object* obj, int offset) {
67     return ((JValue*)BYTE_OFFSET(obj, offset))->i;
68 }
69 INLINE s8 dvmGetFieldLong(const Object* obj, int offset) {
70     return ((JValue*)BYTE_OFFSET(obj, offset))->j;
71 }
72 INLINE float dvmGetFieldFloat(const Object* obj, int offset) {
73     return ((JValue*)BYTE_OFFSET(obj, offset))->f;
74 }
75 INLINE double dvmGetFieldDouble(const Object* obj, int offset) {
76     return ((JValue*)BYTE_OFFSET(obj, offset))->d;
77 }
78 INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
79     return ((JValue*)BYTE_OFFSET(obj, offset))->l;
80 }
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);
84 }
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);
88 }
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);
92 }
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);
96 }
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);
100 }
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);
105     return alias.fval;
106 }
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();
111     return val;
112 }
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();
118     return alias.dval;
119 }
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);
123 }
124
125 INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
126     ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
127 }
128 INLINE void dvmSetFieldByte(Object* obj, int offset, s1 val) {
129     ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
130 }
131 INLINE void dvmSetFieldShort(Object* obj, int offset, s2 val) {
132     ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
133 }
134 INLINE void dvmSetFieldChar(Object* obj, int offset, u2 val) {
135     ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
136 }
137 INLINE void dvmSetFieldInt(Object* obj, int offset, s4 val) {
138     ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
139 }
140 INLINE void dvmSetFieldFloat(Object* obj, int offset, float val) {
141     ((JValue*)BYTE_OFFSET(obj, offset))->f = val;
142 }
143 INLINE void dvmSetFieldLong(Object* obj, int offset, s8 val) {
144     ((JValue*)BYTE_OFFSET(obj, offset))->j = val;
145 }
146 INLINE void dvmSetFieldDouble(Object* obj, int offset, double val) {
147     ((JValue*)BYTE_OFFSET(obj, offset))->d = val;
148 }
149 INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
150     JValue* lhs = (JValue*)BYTE_OFFSET(obj, offset);
151     lhs->l = val;
152     if (val != NULL) {
153         dvmWriteBarrierField(obj, &lhs->l);
154     }
155 }
156 INLINE void dvmSetFieldIntVolatile(Object* obj, int offset, s4 val) {
157     s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
158     /*
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.
162      */
163     ANDROID_MEMBAR_STORE();
164     *ptr = val;
165     ANDROID_MEMBAR_FULL();
166 }
167 INLINE void dvmSetFieldBooleanVolatile(Object* obj, int offset, bool val) {
168     dvmSetFieldIntVolatile(obj, offset, val);
169 }
170 INLINE void dvmSetFieldByteVolatile(Object* obj, int offset, s1 val) {
171     dvmSetFieldIntVolatile(obj, offset, val);
172 }
173 INLINE void dvmSetFieldShortVolatile(Object* obj, int offset, s2 val) {
174     dvmSetFieldIntVolatile(obj, offset, val);
175 }
176 INLINE void dvmSetFieldCharVolatile(Object* obj, int offset, u2 val) {
177     dvmSetFieldIntVolatile(obj, offset, val);
178 }
179 INLINE void dvmSetFieldFloatVolatile(Object* obj, int offset, float val) {
180     union { s4 ival; float fval; } alias;
181     alias.fval = val;
182     dvmSetFieldIntVolatile(obj, offset, alias.ival);
183 }
184 INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
185     s8* addr = (s8*)BYTE_OFFSET(obj, offset);
186     dvmQuasiAtomicSwap64Sync(val, addr);
187 }
188 INLINE void dvmSetFieldDoubleVolatile(Object* obj, int offset, double val) {
189     union { s8 lval; double dval; } alias;
190     alias.dval = val;
191     dvmSetFieldLongVolatile(obj, offset, alias.lval);
192 }
193 INLINE void dvmSetFieldObjectVolatile(Object* obj, int offset, Object* val) {
194     Object** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
195     ANDROID_MEMBAR_STORE();
196     *ptr = val;
197     ANDROID_MEMBAR_FULL();
198     if (val != NULL) {
199         dvmWriteBarrierField(obj, ptr);
200     }
201 }
202
203 /*
204  * Static field access functions.
205  */
206 INLINE JValue* dvmStaticFieldPtr(const StaticField* sfield) {
207     return (JValue*)&sfield->value;
208 }
209
210 INLINE bool dvmGetStaticFieldBoolean(const StaticField* sfield) {
211     return sfield->value.z;
212 }
213 INLINE s1 dvmGetStaticFieldByte(const StaticField* sfield) {
214     return sfield->value.b;
215 }
216 INLINE s2 dvmGetStaticFieldShort(const StaticField* sfield) {
217     return sfield->value.s;
218 }
219 INLINE u2 dvmGetStaticFieldChar(const StaticField* sfield) {
220     return sfield->value.c;
221 }
222 INLINE s4 dvmGetStaticFieldInt(const StaticField* sfield) {
223     return sfield->value.i;
224 }
225 INLINE float dvmGetStaticFieldFloat(const StaticField* sfield) {
226     return sfield->value.f;
227 }
228 INLINE s8 dvmGetStaticFieldLong(const StaticField* sfield) {
229     return sfield->value.j;
230 }
231 INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) {
232     return sfield->value.d;
233 }
234 INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
235     return sfield->value.l;
236 }
237 INLINE bool dvmGetStaticFieldBooleanVolatile(const StaticField* sfield) {
238     const s4* ptr = &(sfield->value.i);
239     return (bool)android_atomic_acquire_load((s4*)ptr);
240 }
241 INLINE s1 dvmGetStaticFieldByteVolatile(const StaticField* sfield) {
242     const s4* ptr = &(sfield->value.i);
243     return (s1)android_atomic_acquire_load((s4*)ptr);
244 }
245 INLINE s2 dvmGetStaticFieldShortVolatile(const StaticField* sfield) {
246     const s4* ptr = &(sfield->value.i);
247     return (s2)android_atomic_acquire_load((s4*)ptr);
248 }
249 INLINE u2 dvmGetStaticFieldCharVolatile(const StaticField* sfield) {
250     const s4* ptr = &(sfield->value.i);
251     return (u2)android_atomic_acquire_load((s4*)ptr);
252 }
253 INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) {
254     const s4* ptr = &(sfield->value.i);
255     return android_atomic_acquire_load((s4*)ptr);
256 }
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);
261     return alias.fval;
262 }
263 INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
264     const s8* addr = &sfield->value.j;
265     s8 val = dvmQuasiAtomicRead64(addr);
266     ANDROID_MEMBAR_FULL();
267     return val;
268 }
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();
274     return alias.dval;
275 }
276 INLINE Object* dvmGetStaticFieldObjectVolatile(const StaticField* sfield) {
277     Object* const* ptr = &(sfield->value.l);
278     return (Object*)android_atomic_acquire_load((int32_t*)ptr);
279 }
280
281 INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
282     sfield->value.i = val;
283 }
284 INLINE void dvmSetStaticFieldByte(StaticField* sfield, s1 val) {
285     sfield->value.i = val;
286 }
287 INLINE void dvmSetStaticFieldShort(StaticField* sfield, s2 val) {
288     sfield->value.i = val;
289 }
290 INLINE void dvmSetStaticFieldChar(StaticField* sfield, u2 val) {
291     sfield->value.i = val;
292 }
293 INLINE void dvmSetStaticFieldInt(StaticField* sfield, s4 val) {
294     sfield->value.i = val;
295 }
296 INLINE void dvmSetStaticFieldFloat(StaticField* sfield, float val) {
297     sfield->value.f = val;
298 }
299 INLINE void dvmSetStaticFieldLong(StaticField* sfield, s8 val) {
300     sfield->value.j = val;
301 }
302 INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) {
303     sfield->value.d = val;
304 }
305 INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
306     sfield->value.l = val;
307     if (val != NULL) {
308         dvmWriteBarrierField(sfield->clazz, &sfield->value.l);
309     }
310 }
311 INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) {
312     s4* ptr = &sfield->value.i;
313     ANDROID_MEMBAR_STORE();
314     *ptr = val;
315     ANDROID_MEMBAR_FULL();
316 }
317 INLINE void dvmSetStaticFieldBooleanVolatile(StaticField* sfield, bool val) {
318     dvmSetStaticFieldIntVolatile(sfield, val);
319 }
320 INLINE void dvmSetStaticFieldByteVolatile(StaticField* sfield, s1 val) {
321     dvmSetStaticFieldIntVolatile(sfield, val);
322 }
323 INLINE void dvmSetStaticFieldShortVolatile(StaticField* sfield, s2 val) {
324     dvmSetStaticFieldIntVolatile(sfield, val);
325 }
326 INLINE void dvmSetStaticFieldCharVolatile(StaticField* sfield, u2 val) {
327     dvmSetStaticFieldIntVolatile(sfield, val);
328 }
329 INLINE void dvmSetStaticFieldFloatVolatile(StaticField* sfield, float val) {
330     union { s4 ival; float fval; } alias;
331     alias.fval = val;
332     dvmSetStaticFieldIntVolatile(sfield, alias.ival);
333 }
334 INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
335     s8* addr = &sfield->value.j;
336     dvmQuasiAtomicSwap64Sync(val, addr);
337 }
338 INLINE void dvmSetStaticFieldDoubleVolatile(StaticField* sfield, double val) {
339     union { s8 lval; double dval; } alias;
340     alias.dval = val;
341     dvmSetStaticFieldLongVolatile(sfield, alias.lval);
342 }
343 INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
344     Object** ptr = &(sfield->value.l);
345     ANDROID_MEMBAR_STORE();
346     *ptr = val;
347     ANDROID_MEMBAR_FULL();
348     if (val != NULL) {
349         dvmWriteBarrierField(sfield->clazz, &sfield->value.l);
350     }
351 }
352
353 #endif  // DALVIK_OO_OBJECTINLINES_H_