ObjectInlines.h revision fc75f3ed87b55d625b6054e18645da5cbdba31c6
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 21#define _DALVIK_OO_OBJECTINLINES 22 23/* 24 * Store a single value in the array, and if the value isn't null, 25 * note in the write barrier. 26 */ 27INLINE 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 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) { 79 return (Object*)((JValue*)BYTE_OFFSET(obj, offset))->l; 80} 81INLINE 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} 97INLINE s4 dvmGetFieldIntVolatile(const Object* obj, int offset) { 98 s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i; 99 return android_atomic_acquire_load(ptr); 100} 101INLINE 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} 107INLINE 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} 113INLINE 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} 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} 124 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} 140INLINE void dvmSetFieldFloat(Object* obj, int offset, float val) { 141 ((JValue*)BYTE_OFFSET(obj, offset))->f = val; 142} 143INLINE void dvmSetFieldLong(Object* obj, int offset, s8 val) { 144 ((JValue*)BYTE_OFFSET(obj, offset))->j = val; 145} 146INLINE 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) { 150 JValue* lhs = (JValue*)BYTE_OFFSET(obj, offset); 151 lhs->l = val; 152 if (val != NULL) { 153 dvmWriteBarrierField(obj, &lhs->l); 154 } 155} 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} 160INLINE 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) { 178 s8* addr = (s8*)BYTE_OFFSET(obj, offset); 179 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} 187INLINE 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); 190 if (val != NULL) { 191 dvmWriteBarrierField(obj, ptr); 192 } 193} 194 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} 217INLINE float dvmGetStaticFieldFloat(const StaticField* sfield) { 218 return sfield->value.f; 219} 220INLINE s8 dvmGetStaticFieldLong(const StaticField* sfield) { 221 return sfield->value.j; 222} 223INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) { 224 return sfield->value.d; 225} 226INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) { 227 return (Object*)sfield->value.l; 228} 229INLINE 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} 245INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) { 246 const s4* ptr = &(sfield->value.i); 247 return android_atomic_acquire_load((s4*)ptr); 248} 249INLINE 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; 254} 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} 261INLINE 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} 272 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} 288INLINE void dvmSetStaticFieldFloat(StaticField* sfield, float val) { 289 sfield->value.f = val; 290} 291INLINE void dvmSetStaticFieldLong(StaticField* sfield, s8 val) { 292 sfield->value.j = val; 293} 294INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) { 295 sfield->value.d = val; 296} 297INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) { 298 sfield->value.l = val; 299 if (val != NULL) { 300 dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l); 301 } 302} 303INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) { 304 s4* ptr = &sfield->value.i; 305 android_atomic_release_store(val, ptr); 306} 307INLINE 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} 334INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) { 335 void** ptr = &(sfield->value.l); 336 android_atomic_release_store((int32_t)val, (int32_t*)ptr); 337 if (val != NULL) { 338 dvmWriteBarrierField((Object *)sfield->field.clazz, &sfield->value.l); 339 } 340} 341 342#endif /*_DALVIK_OO_OBJECTINLINES*/ 343