28 #include "memory/allocation.inline.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "oops/fieldStreams.hpp"
31 #include "oops/objArrayOop.inline.hpp"
32 #include "oops/oop.inline.hpp"
33 #include "prims/jni.h"
34 #include "prims/jvm.h"
35 #include "prims/unsafe.hpp"
36 #include "runtime/atomic.hpp"
37 #include "runtime/globals.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/orderAccess.inline.hpp"
40 #include "runtime/reflection.hpp"
41 #include "runtime/vm_version.hpp"
42 #include "services/threadService.hpp"
43 #include "trace/tracing.hpp"
44 #include "utilities/align.hpp"
45 #include "utilities/copy.hpp"
46 #include "utilities/dtrace.hpp"
47 #include "utilities/macros.hpp"
48 #if INCLUDE_ALL_GCS
49 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
50 #endif // INCLUDE_ALL_GCS
51
52 /**
53 * Implementation of the jdk.internal.misc.Unsafe class
54 */
55
56
57 #define MAX_OBJECT_SIZE \
58 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
59 + ((julong)max_jint * sizeof(double)) )
60
61
62 #define UNSAFE_ENTRY(result_type, header) \
63 JVM_ENTRY(static result_type, header)
64
65 #define UNSAFE_LEAF(result_type, header) \
66 JVM_LEAF(static result_type, header)
67
68 #define UNSAFE_END JVM_END
69
70
280
281 // We could be accessing the referent field in a reference
282 // object. If G1 is enabled then we need to register non-null
283 // referent with the SATB barrier.
284
285 #if INCLUDE_ALL_GCS
286 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
287 if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
288 Klass* k = o->klass();
289 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
290 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
291 return true;
292 }
293 }
294 return false;
295 }
296 #endif
297
298 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
299 #if INCLUDE_ALL_GCS
300 if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
301 G1SATBCardTableModRefBS::enqueue(v);
302 }
303 #endif
304 }
305
306 // These functions allow a null base pointer with an arbitrary address.
307 // But if the base pointer is non-null, the offset should make some sense.
308 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
309 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
310 oop p = JNIHandles::resolve(obj);
311 p = oopDesc::bs()->read_barrier(p);
312 oop v;
313
314 if (UseCompressedOops) {
315 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset);
316 v = oopDesc::decode_heap_oop(n);
317 } else {
318 v = *(oop*)index_oop_from_field_offset_long(p, offset);
319 }
320
321 ensure_satb_referent_alive(p, offset, v);
|
28 #include "memory/allocation.inline.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "oops/fieldStreams.hpp"
31 #include "oops/objArrayOop.inline.hpp"
32 #include "oops/oop.inline.hpp"
33 #include "prims/jni.h"
34 #include "prims/jvm.h"
35 #include "prims/unsafe.hpp"
36 #include "runtime/atomic.hpp"
37 #include "runtime/globals.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/orderAccess.inline.hpp"
40 #include "runtime/reflection.hpp"
41 #include "runtime/vm_version.hpp"
42 #include "services/threadService.hpp"
43 #include "trace/tracing.hpp"
44 #include "utilities/align.hpp"
45 #include "utilities/copy.hpp"
46 #include "utilities/dtrace.hpp"
47 #include "utilities/macros.hpp"
48
49 /**
50 * Implementation of the jdk.internal.misc.Unsafe class
51 */
52
53
54 #define MAX_OBJECT_SIZE \
55 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
56 + ((julong)max_jint * sizeof(double)) )
57
58
59 #define UNSAFE_ENTRY(result_type, header) \
60 JVM_ENTRY(static result_type, header)
61
62 #define UNSAFE_LEAF(result_type, header) \
63 JVM_LEAF(static result_type, header)
64
65 #define UNSAFE_END JVM_END
66
67
277
278 // We could be accessing the referent field in a reference
279 // object. If G1 is enabled then we need to register non-null
280 // referent with the SATB barrier.
281
282 #if INCLUDE_ALL_GCS
283 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
284 if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
285 Klass* k = o->klass();
286 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
287 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
288 return true;
289 }
290 }
291 return false;
292 }
293 #endif
294
295 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
296 #if INCLUDE_ALL_GCS
297 if (v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
298 oopDesc::bs()->keep_alive_barrier(v);
299 }
300 #endif
301 }
302
303 // These functions allow a null base pointer with an arbitrary address.
304 // But if the base pointer is non-null, the offset should make some sense.
305 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
306 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
307 oop p = JNIHandles::resolve(obj);
308 p = oopDesc::bs()->read_barrier(p);
309 oop v;
310
311 if (UseCompressedOops) {
312 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset);
313 v = oopDesc::decode_heap_oop(n);
314 } else {
315 v = *(oop*)index_oop_from_field_offset_long(p, offset);
316 }
317
318 ensure_satb_referent_alive(p, offset, v);
|