blob: 11920591d5b8123be314c8247552f0e0e21574bd [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/*
24 * Store a single value in the array, and note in the write barrier.
25 */
26INLINE void dvmSetObjectArrayElement(const ArrayObject* obj, int index,
27 Object* val) {
28 ((Object **)(obj)->contents)[index] = val;
29 dvmWriteBarrierArray(obj, index, index+1);
30}
31
32
33/*
34 * Field access functions. Pass in the word offset from Field->byteOffset.
35 *
36 * We guarantee that long/double field data is 64-bit aligned, so it's safe
37 * to access them with ldrd/strd on ARM.
38 *
39 * The VM treats all fields as 32 or 64 bits, so the field set functions
40 * write 32 bits even if the underlying type is smaller.
41 */
42#define BYTE_OFFSET(_ptr, _offset) ((void*) (((u1*)(_ptr)) + (_offset)))
43
44INLINE JValue* dvmFieldPtr(const Object* obj, int offset) {
45 return ((JValue*)BYTE_OFFSET(obj, offset));
46}
47
48INLINE bool dvmGetFieldBoolean(const Object* obj, int offset) {
49 return ((JValue*)BYTE_OFFSET(obj, offset))->z;
50}
51INLINE s1 dvmGetFieldByte(const Object* obj, int offset) {
52 return ((JValue*)BYTE_OFFSET(obj, offset))->b;
53}
54INLINE s2 dvmGetFieldShort(const Object* obj, int offset) {
55 return ((JValue*)BYTE_OFFSET(obj, offset))->s;
56}
57INLINE u2 dvmGetFieldChar(const Object* obj, int offset) {
58 return ((JValue*)BYTE_OFFSET(obj, offset))->c;
59}
60INLINE s4 dvmGetFieldInt(const Object* obj, int offset) {
61 return ((JValue*)BYTE_OFFSET(obj, offset))->i;
62}
63INLINE s8 dvmGetFieldLong(const Object* obj, int offset) {
64 return ((JValue*)BYTE_OFFSET(obj, offset))->j;
65}
66INLINE float dvmGetFieldFloat(const Object* obj, int offset) {
67 return ((JValue*)BYTE_OFFSET(obj, offset))->f;
68}
69INLINE double dvmGetFieldDouble(const Object* obj, int offset) {
70 return ((JValue*)BYTE_OFFSET(obj, offset))->d;
71}
72INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
73 return ((JValue*)BYTE_OFFSET(obj, offset))->l;
74}
75INLINE s4 dvmGetFieldIntVolatile(const Object* obj, int offset) {
76 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
77 return android_atomic_acquire_load(ptr);
78}
79INLINE Object* dvmGetFieldObjectVolatile(const Object* obj, int offset) {
80 void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
81 return (Object*) android_atomic_acquire_load((int32_t*)ptr);
82}
83INLINE s8 dvmGetFieldLongVolatile(const Object* obj, int offset) {
84 const s8* addr = BYTE_OFFSET(obj, offset);
85 s8 val = dvmQuasiAtomicRead64(addr);
86 ANDROID_MEMBAR_FULL();
87 return val;
88}
89
90INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
91 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
92}
93INLINE void dvmSetFieldByte(Object* obj, int offset, s1 val) {
94 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
95}
96INLINE void dvmSetFieldShort(Object* obj, int offset, s2 val) {
97 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
98}
99INLINE void dvmSetFieldChar(Object* obj, int offset, u2 val) {
100 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
101}
102INLINE void dvmSetFieldInt(Object* obj, int offset, s4 val) {
103 ((JValue*)BYTE_OFFSET(obj, offset))->i = val;
104}
105INLINE void dvmSetFieldLong(Object* obj, int offset, s8 val) {
106 ((JValue*)BYTE_OFFSET(obj, offset))->j = val;
107}
108INLINE void dvmSetFieldFloat(Object* obj, int offset, float val) {
109 ((JValue*)BYTE_OFFSET(obj, offset))->f = val;
110}
111INLINE void dvmSetFieldDouble(Object* obj, int offset, double val) {
112 ((JValue*)BYTE_OFFSET(obj, offset))->d = val;
113}
114INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
115 JValue* lhs = BYTE_OFFSET(obj, offset);
116 lhs->l = val;
117 dvmWriteBarrierField(obj, &lhs->l);
118}
119INLINE void dvmSetFieldIntVolatile(Object* obj, int offset, s4 val) {
120 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
121 android_atomic_release_store(val, ptr);
122}
123INLINE void dvmSetFieldObjectVolatile(Object* obj, int offset, Object* val) {
124 void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
125 android_atomic_release_store((int32_t)val, (int32_t*)ptr);
126 dvmWriteBarrierField(obj, ptr);
127}
128INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
129 s8* addr = BYTE_OFFSET(obj, offset);
130 ANDROID_MEMBAR_FULL();
131 dvmQuasiAtomicSwap64(val, addr);
132}
133
134/*
135 * Static field access functions.
136 */
137INLINE JValue* dvmStaticFieldPtr(const StaticField* sfield) {
138 return (JValue*)&sfield->value;
139}
140
141INLINE bool dvmGetStaticFieldBoolean(const StaticField* sfield) {
142 return sfield->value.z;
143}
144INLINE s1 dvmGetStaticFieldByte(const StaticField* sfield) {
145 return sfield->value.b;
146}
147INLINE s2 dvmGetStaticFieldShort(const StaticField* sfield) {
148 return sfield->value.s;
149}
150INLINE u2 dvmGetStaticFieldChar(const StaticField* sfield) {
151 return sfield->value.c;
152}
153INLINE s4 dvmGetStaticFieldInt(const StaticField* sfield) {
154 return sfield->value.i;
155}
156INLINE s8 dvmGetStaticFieldLong(const StaticField* sfield) {
157 return sfield->value.j;
158}
159INLINE float dvmGetStaticFieldFloat(const StaticField* sfield) {
160 return sfield->value.f;
161}
162INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) {
163 return sfield->value.d;
164}
165INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
166 return sfield->value.l;
167}
168INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) {
169 const s4* ptr = &(sfield->value.i);
170 return android_atomic_acquire_load((s4*)ptr);
171}
172INLINE Object* dvmGetStaticFieldObjectVolatile(const StaticField* sfield) {
173 void* const* ptr = &(sfield->value.l);
174 return (Object*) android_atomic_acquire_load((int32_t*)ptr);
175}
176INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
177 const s8* addr = &sfield->value.j;
178 s8 val = dvmQuasiAtomicRead64(addr);
179 ANDROID_MEMBAR_FULL();
180 return val;
181}
182
183INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
184 sfield->value.i = val;
185}
186INLINE void dvmSetStaticFieldByte(StaticField* sfield, s1 val) {
187 sfield->value.i = val;
188}
189INLINE void dvmSetStaticFieldShort(StaticField* sfield, s2 val) {
190 sfield->value.i = val;
191}
192INLINE void dvmSetStaticFieldChar(StaticField* sfield, u2 val) {
193 sfield->value.i = val;
194}
195INLINE void dvmSetStaticFieldInt(StaticField* sfield, s4 val) {
196 sfield->value.i = val;
197}
198INLINE void dvmSetStaticFieldLong(StaticField* sfield, s8 val) {
199 sfield->value.j = val;
200}
201INLINE void dvmSetStaticFieldFloat(StaticField* sfield, float val) {
202 sfield->value.f = val;
203}
204INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) {
205 sfield->value.d = val;
206}
207INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
208 sfield->value.l = val;
209 dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l);
210}
211INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) {
212 s4* ptr = &(sfield->value.i);
213 android_atomic_release_store(val, ptr);
214}
215INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
216 void** ptr = &(sfield->value.l);
217 android_atomic_release_store((int32_t)val, (int32_t*)ptr);
218 dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l);
219}
220INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
221 s8* addr = &sfield->value.j;
222 ANDROID_MEMBAR_FULL();
223 dvmQuasiAtomicSwap64(val, addr);
224}
225
Barry Hayes0dfa7bf2010-06-25 13:50:29 -0700226#endif /*_DALVIK_OO_OBJECTINLINES*/