197 } |
197 } |
198 |
198 |
199 |
199 |
200 // Get/SetObject must be special-cased, since it works with handles. |
200 // Get/SetObject must be special-cased, since it works with handles. |
201 |
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 |
202 // The xxx140 variants for backward compatibility do not allow a full-width offset. |
227 // 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)) |
228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) |
204 UnsafeWrapper("Unsafe_GetObject"); |
229 UnsafeWrapper("Unsafe_GetObject"); |
205 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); |
230 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); |
206 GET_OOP_FIELD(obj, offset, v) |
231 GET_OOP_FIELD(obj, offset, v) |
207 jobject ret = JNIHandles::make_local(env, v); |
232 |
208 #if INCLUDE_ALL_GCS |
233 ensure_satb_referent_alive(p, offset, v); |
209 // We could be accessing the referent field in a reference |
234 |
210 // object. If G1 is enabled then we need to register a non-null |
235 return JNIHandles::make_local(env, v); |
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 |
236 UNSAFE_END |
234 |
237 |
235 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) |
238 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) |
236 UnsafeWrapper("Unsafe_SetObject"); |
239 UnsafeWrapper("Unsafe_SetObject"); |
237 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); |
240 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); |
260 // But if the base pointer is non-null, the offset should make some sense. |
263 // 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]. |
264 // 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)) |
265 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) |
263 UnsafeWrapper("Unsafe_GetObject"); |
266 UnsafeWrapper("Unsafe_GetObject"); |
264 GET_OOP_FIELD(obj, offset, v) |
267 GET_OOP_FIELD(obj, offset, v) |
265 jobject ret = JNIHandles::make_local(env, v); |
268 |
266 #if INCLUDE_ALL_GCS |
269 ensure_satb_referent_alive(p, offset, v); |
267 // We could be accessing the referent field in a reference |
270 |
268 // object. If G1 is enabled then we need to register non-null |
271 return JNIHandles::make_local(env, v); |
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 |
272 UNSAFE_END |
292 |
273 |
293 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) |
274 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) |
294 UnsafeWrapper("Unsafe_SetObject"); |
275 UnsafeWrapper("Unsafe_SetObject"); |
295 oop x = JNIHandles::resolve(x_h); |
276 oop x = JNIHandles::resolve(x_h); |
310 volatile narrowOop n = *(volatile narrowOop*) addr; |
291 volatile narrowOop n = *(volatile narrowOop*) addr; |
311 (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n)); |
292 (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n)); |
312 } else { |
293 } else { |
313 (void)const_cast<oop&>(v = *(volatile oop*) addr); |
294 (void)const_cast<oop&>(v = *(volatile oop*) addr); |
314 } |
295 } |
|
296 |
|
297 ensure_satb_referent_alive(p, offset, v); |
|
298 |
315 OrderAccess::acquire(); |
299 OrderAccess::acquire(); |
316 return JNIHandles::make_local(env, v); |
300 return JNIHandles::make_local(env, v); |
317 UNSAFE_END |
301 UNSAFE_END |
318 |
302 |
319 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) |
303 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) |