182
183 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
184 oop p = JNIHandles::resolve(obj); \
185 OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
186
187 // Macros for oops that check UseCompressedOops
188
189 #define GET_OOP_FIELD(obj, offset, v) \
190 oop p = JNIHandles::resolve(obj); \
191 oop v; \
192 if (UseCompressedOops) { \
193 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
194 v = oopDesc::decode_heap_oop(n); \
195 } else { \
196 v = *(oop*)index_oop_from_field_offset_long(p, offset); \
197 }
198
199
200 // Get/SetObject must be special-cased, since it works with handles.
201
202 // The xxx140 variants for backward compatibility do not allow a full-width offset.
203 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
204 UnsafeWrapper("Unsafe_GetObject");
205 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
206 GET_OOP_FIELD(obj, offset, v)
207 jobject ret = JNIHandles::make_local(env, v);
208 #if INCLUDE_ALL_GCS
209 // We could be accessing the referent field in a reference
210 // object. If G1 is enabled then we need to register a non-null
211 // referent with the SATB barrier.
212 if (UseG1GC) {
213 bool needs_barrier = false;
214
215 if (ret != NULL) {
216 if (offset == java_lang_ref_Reference::referent_offset) {
217 oop o = JNIHandles::resolve_non_null(obj);
218 Klass* k = o->klass();
219 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
220 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
221 needs_barrier = true;
222 }
223 }
224 }
225
226 if (needs_barrier) {
227 oop referent = JNIHandles::resolve(ret);
228 G1SATBCardTableModRefBS::enqueue(referent);
229 }
230 }
231 #endif // INCLUDE_ALL_GCS
232 return ret;
233 UNSAFE_END
234
235 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
236 UnsafeWrapper("Unsafe_SetObject");
237 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
238 oop x = JNIHandles::resolve(x_h);
239 //SET_FIELD(obj, offset, oop, x);
240 oop p = JNIHandles::resolve(obj);
241 if (UseCompressedOops) {
242 if (x != NULL) {
243 // If there is a heap base pointer, we are obliged to emit a store barrier.
244 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
245 } else {
246 narrowOop n = oopDesc::encode_heap_oop_not_null(x);
247 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
248 }
249 } else {
250 if (x != NULL) {
251 // If there is a heap base pointer, we are obliged to emit a store barrier.
252 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
253 } else {
254 *(oop*)index_oop_from_field_offset_long(p, offset) = x;
255 }
256 }
257 UNSAFE_END
258
259 // The normal variants allow a null base pointer with an arbitrary address.
260 // But if the base pointer is non-null, the offset should make some sense.
261 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
262 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
263 UnsafeWrapper("Unsafe_GetObject");
264 GET_OOP_FIELD(obj, offset, v)
265 jobject ret = JNIHandles::make_local(env, v);
266 #if INCLUDE_ALL_GCS
267 // We could be accessing the referent field in a reference
268 // object. If G1 is enabled then we need to register non-null
269 // referent with the SATB barrier.
270 if (UseG1GC) {
271 bool needs_barrier = false;
272
273 if (ret != NULL) {
274 if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
275 oop o = JNIHandles::resolve(obj);
276 Klass* k = o->klass();
277 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
278 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
279 needs_barrier = true;
280 }
281 }
282 }
283
284 if (needs_barrier) {
285 oop referent = JNIHandles::resolve(ret);
286 G1SATBCardTableModRefBS::enqueue(referent);
287 }
288 }
289 #endif // INCLUDE_ALL_GCS
290 return ret;
291 UNSAFE_END
292
293 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
294 UnsafeWrapper("Unsafe_SetObject");
295 oop x = JNIHandles::resolve(x_h);
296 oop p = JNIHandles::resolve(obj);
297 if (UseCompressedOops) {
298 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
299 } else {
300 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
301 }
302 UNSAFE_END
303
304 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
305 UnsafeWrapper("Unsafe_GetObjectVolatile");
306 oop p = JNIHandles::resolve(obj);
307 void* addr = index_oop_from_field_offset_long(p, offset);
308 volatile oop v;
309 if (UseCompressedOops) {
310 volatile narrowOop n = *(volatile narrowOop*) addr;
311 (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
312 } else {
313 (void)const_cast<oop&>(v = *(volatile oop*) addr);
314 }
315 OrderAccess::acquire();
316 return JNIHandles::make_local(env, v);
317 UNSAFE_END
318
319 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
320 UnsafeWrapper("Unsafe_SetObjectVolatile");
321 oop x = JNIHandles::resolve(x_h);
322 oop p = JNIHandles::resolve(obj);
323 void* addr = index_oop_from_field_offset_long(p, offset);
324 OrderAccess::release();
325 if (UseCompressedOops) {
326 oop_store((narrowOop*)addr, x);
327 } else {
328 oop_store((oop*)addr, x);
329 }
330 OrderAccess::fence();
331 UNSAFE_END
332
333 #ifndef SUPPORTS_NATIVE_CX8
334
|
182
183 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
184 oop p = JNIHandles::resolve(obj); \
185 OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
186
187 // Macros for oops that check UseCompressedOops
188
189 #define GET_OOP_FIELD(obj, offset, v) \
190 oop p = JNIHandles::resolve(obj); \
191 oop v; \
192 if (UseCompressedOops) { \
193 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
194 v = oopDesc::decode_heap_oop(n); \
195 } else { \
196 v = *(oop*)index_oop_from_field_offset_long(p, offset); \
197 }
198
199
200 // Get/SetObject must be special-cased, since it works with handles.
201
202 // We could be accessing the referent field in a reference
203 // object. If G1 is enabled then we need to register non-null
204 // referent with the SATB barrier.
205
206 #if INCLUDE_ALL_GCS
207 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
208 if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
209 Klass* k = o->klass();
210 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
211 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
212 return true;
213 }
214 }
215 return false;
216 }
217 #endif
218
219 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
220 #if INCLUDE_ALL_GCS
221 if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
222 G1SATBCardTableModRefBS::enqueue(v);
223 }
224 #endif
225 }
226
227 // The xxx140 variants for backward compatibility do not allow a full-width offset.
228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
229 UnsafeWrapper("Unsafe_GetObject");
230 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
231 GET_OOP_FIELD(obj, offset, v)
232
233 ensure_satb_referent_alive(p, offset, v);
234
235 return JNIHandles::make_local(env, v);
236 UNSAFE_END
237
238 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
239 UnsafeWrapper("Unsafe_SetObject");
240 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
241 oop x = JNIHandles::resolve(x_h);
242 //SET_FIELD(obj, offset, oop, x);
243 oop p = JNIHandles::resolve(obj);
244 if (UseCompressedOops) {
245 if (x != NULL) {
246 // If there is a heap base pointer, we are obliged to emit a store barrier.
247 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
248 } else {
249 narrowOop n = oopDesc::encode_heap_oop_not_null(x);
250 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
251 }
252 } else {
253 if (x != NULL) {
254 // If there is a heap base pointer, we are obliged to emit a store barrier.
255 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
256 } else {
257 *(oop*)index_oop_from_field_offset_long(p, offset) = x;
258 }
259 }
260 UNSAFE_END
261
262 // The normal variants allow a null base pointer with an arbitrary address.
263 // But if the base pointer is non-null, the offset should make some sense.
264 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
265 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
266 UnsafeWrapper("Unsafe_GetObject");
267 GET_OOP_FIELD(obj, offset, v)
268
269 ensure_satb_referent_alive(p, offset, v);
270
271 return JNIHandles::make_local(env, v);
272 UNSAFE_END
273
274 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
275 UnsafeWrapper("Unsafe_SetObject");
276 oop x = JNIHandles::resolve(x_h);
277 oop p = JNIHandles::resolve(obj);
278 if (UseCompressedOops) {
279 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
280 } else {
281 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
282 }
283 UNSAFE_END
284
285 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
286 UnsafeWrapper("Unsafe_GetObjectVolatile");
287 oop p = JNIHandles::resolve(obj);
288 void* addr = index_oop_from_field_offset_long(p, offset);
289 volatile oop v;
290 if (UseCompressedOops) {
291 volatile narrowOop n = *(volatile narrowOop*) addr;
292 (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
293 } else {
294 (void)const_cast<oop&>(v = *(volatile oop*) addr);
295 }
296
297 ensure_satb_referent_alive(p, offset, v);
298
299 OrderAccess::acquire();
300 return JNIHandles::make_local(env, v);
301 UNSAFE_END
302
303 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
304 UnsafeWrapper("Unsafe_SetObjectVolatile");
305 oop x = JNIHandles::resolve(x_h);
306 oop p = JNIHandles::resolve(obj);
307 void* addr = index_oop_from_field_offset_long(p, offset);
308 OrderAccess::release();
309 if (UseCompressedOops) {
310 oop_store((narrowOop*)addr, x);
311 } else {
312 oop_store((oop*)addr, x);
313 }
314 OrderAccess::fence();
315 UNSAFE_END
316
317 #ifndef SUPPORTS_NATIVE_CX8
318
|