25 #include "precompiled.hpp"
26 #include "jni.h"
27 #include "jvm.h"
28 #include "classfile/classFileStream.hpp"
29 #include "classfile/vmSymbols.hpp"
30 #include "jfr/jfrEvents.hpp"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/access.inline.hpp"
34 #include "oops/fieldStreams.hpp"
35 #include "oops/objArrayOop.inline.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "oops/typeArrayOop.inline.hpp"
38 #include "prims/unsafe.hpp"
39 #include "runtime/atomic.hpp"
40 #include "runtime/globals.hpp"
41 #include "runtime/interfaceSupport.inline.hpp"
42 #include "runtime/jniHandles.inline.hpp"
43 #include "runtime/orderAccess.hpp"
44 #include "runtime/reflection.hpp"
45 #include "runtime/thread.hpp"
46 #include "runtime/threadSMR.hpp"
47 #include "runtime/vm_version.hpp"
48 #include "services/threadService.hpp"
49 #include "utilities/align.hpp"
50 #include "utilities/copy.hpp"
51 #include "utilities/dtrace.hpp"
52 #include "utilities/macros.hpp"
53
54 /**
55 * Implementation of the jdk.internal.misc.Unsafe class
56 */
57
58
59 #define MAX_OBJECT_SIZE \
60 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
61 + ((julong)max_jint * sizeof(double)) )
62
63
64 #define UNSAFE_ENTRY(result_type, header) \
425 // Both src & dst are in native memory
426 address src = (address)srcOffset;
427 address dst = (address)dstOffset;
428
429 Copy::conjoint_swap(src, dst, sz, esz);
430 } else {
431 // At least one of src/dst are on heap, transition to VM to access raw pointers
432
433 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
434 oop srcp = JNIHandles::resolve(srcObj);
435 oop dstp = JNIHandles::resolve(dstObj);
436
437 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
438 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
439
440 Copy::conjoint_swap(src, dst, sz, esz);
441 } JVM_END
442 }
443 } UNSAFE_END
444
445 ////// Random queries
446
447 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
448 return sizeof(void*);
449 } UNSAFE_END
450
451 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
452 return os::vm_page_size();
453 } UNSAFE_END
454
455 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
456 assert(clazz != NULL, "clazz must not be NULL");
457 assert(name != NULL, "name must not be NULL");
458
459 ResourceMark rm(THREAD);
460 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
461
462 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
463
464 jint offset = -1;
1044 DECLARE_GETPUTOOP(Boolean, Z),
1045 DECLARE_GETPUTOOP(Byte, B),
1046 DECLARE_GETPUTOOP(Short, S),
1047 DECLARE_GETPUTOOP(Char, C),
1048 DECLARE_GETPUTOOP(Int, I),
1049 DECLARE_GETPUTOOP(Long, J),
1050 DECLARE_GETPUTOOP(Float, F),
1051 DECLARE_GETPUTOOP(Double, D),
1052
1053 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1054 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1055 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1056
1057 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1058 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1059 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1060 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1061 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1062 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1063 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1064 {CC "addressSize0", CC "()I", FN_PTR(Unsafe_AddressSize0)},
1065 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
1066
1067 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1068 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1069 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1070 {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1071 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1072 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1073 {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1074 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1075 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1076
1077 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1078 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
1079
1080 {CC "getLoadAverage0", CC "([DI)I", FN_PTR(Unsafe_GetLoadAverage0)},
1081
1082 {CC "copyMemory0", CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1083 {CC "copySwapMemory0", CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1084 {CC "setMemory0", CC "(" OBJ "JJB)V", FN_PTR(Unsafe_SetMemory0)},
1085
1086 {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1087
1088 {CC "shouldBeInitialized0", CC "(" CLS ")Z", FN_PTR(Unsafe_ShouldBeInitialized0)},
1089
1090 {CC "loadFence", CC "()V", FN_PTR(Unsafe_LoadFence)},
1091 {CC "storeFence", CC "()V", FN_PTR(Unsafe_StoreFence)},
1092 {CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
1093
1094 {CC "isBigEndian0", CC "()Z", FN_PTR(Unsafe_isBigEndian0)},
1095 {CC "unalignedAccess0", CC "()Z", FN_PTR(Unsafe_unalignedAccess0)}
1096 };
1097
1098 #undef CC
1099 #undef FN_PTR
1100
1101 #undef ADR
1102 #undef LANG
1103 #undef OBJ
|
25 #include "precompiled.hpp"
26 #include "jni.h"
27 #include "jvm.h"
28 #include "classfile/classFileStream.hpp"
29 #include "classfile/vmSymbols.hpp"
30 #include "jfr/jfrEvents.hpp"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/access.inline.hpp"
34 #include "oops/fieldStreams.hpp"
35 #include "oops/objArrayOop.inline.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "oops/typeArrayOop.inline.hpp"
38 #include "prims/unsafe.hpp"
39 #include "runtime/atomic.hpp"
40 #include "runtime/globals.hpp"
41 #include "runtime/interfaceSupport.inline.hpp"
42 #include "runtime/jniHandles.inline.hpp"
43 #include "runtime/orderAccess.hpp"
44 #include "runtime/reflection.hpp"
45 #include "runtime/sharedRuntime.hpp"
46 #include "runtime/thread.hpp"
47 #include "runtime/threadSMR.hpp"
48 #include "runtime/vm_version.hpp"
49 #include "services/threadService.hpp"
50 #include "utilities/align.hpp"
51 #include "utilities/copy.hpp"
52 #include "utilities/dtrace.hpp"
53 #include "utilities/macros.hpp"
54
55 /**
56 * Implementation of the jdk.internal.misc.Unsafe class
57 */
58
59
60 #define MAX_OBJECT_SIZE \
61 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
62 + ((julong)max_jint * sizeof(double)) )
63
64
65 #define UNSAFE_ENTRY(result_type, header) \
426 // Both src & dst are in native memory
427 address src = (address)srcOffset;
428 address dst = (address)dstOffset;
429
430 Copy::conjoint_swap(src, dst, sz, esz);
431 } else {
432 // At least one of src/dst are on heap, transition to VM to access raw pointers
433
434 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
435 oop srcp = JNIHandles::resolve(srcObj);
436 oop dstp = JNIHandles::resolve(dstObj);
437
438 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
439 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
440
441 Copy::conjoint_swap(src, dst, sz, esz);
442 } JVM_END
443 }
444 } UNSAFE_END
445
446 UNSAFE_LEAF (void, Unsafe_WriteBack0(JNIEnv *env, jobject unsafe, jlong line)) {
447 #ifndef PRODUCT
448 if (TraceMemoryWriteback) {
449 tty->print_cr("Unsafe: writeback 0x%p", addr_from_java(line));
450 }
451 #endif
452
453 // guard against currently unimplemented cases
454 #if !defined(LINUX) || !(defined(AARCH64) || defined(AMD64))
455 // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
456 JNU_ThrowRuntimeException(env, "writeback is not implemented");
457 return IOS_THROWN;
458 #else
459 void (*wb)(void *);
460 void *a = addr_from_java(line);
461 wb = (void (*)(void *)) StubRoutines::data_cache_writeback();
462 assert(wb != NULL, "generate writeback stub!");
463 (*wb)(a);
464 #endif
465 } UNSAFE_END
466
467 static void doWriteBackSync0(bool isPre)
468 {
469 void (*wbsync)(int);
470 wbsync = (void (*)(int)) StubRoutines::data_cache_writeback_sync();
471 assert(wbsync != NULL, "generate writeback sync stub!");
472 (*wbsync)(isPre);
473 }
474
475 UNSAFE_LEAF (void, Unsafe_WriteBackPreSync0(JNIEnv *env, jobject unsafe)) {
476 #ifndef PRODUCT
477 if (TraceMemoryWriteback) {
478 tty->print_cr("Unsafe: writeback pre-sync");
479 }
480 #endif
481 #if !defined(LINUX) || !(defined(AARCH64) || defined(AMD64))
482 // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
483 JNU_ThrowRuntimeException(env, "writeback sync is not implemented");
484 return IOS_THROWN;
485 #else
486 doWriteBackSync0(true);
487 #endif
488 } UNSAFE_END
489
490 UNSAFE_LEAF (void, Unsafe_WriteBackPostSync0(JNIEnv *env, jobject unsafe)) {
491 #ifndef PRODUCT
492 if (TraceMemoryWriteback) {
493 tty->print_cr("Unsafe: writeback pre-sync");
494 }
495 #endif
496 #if !defined(LINUX) || !(defined(AARCH64) || defined(AMD64))
497 // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
498 JNU_ThrowRuntimeException(env, "writeback sync is not implemented");
499 return IOS_THROWN;
500 #else
501 doWriteBackSync0(false);
502 #endif
503 } UNSAFE_END
504
505 UNSAFE_LEAF(jint, Unsafe_DataCacheLineFlushSize0()) {
506 jint size = (jint)VM_Version::data_cache_line_flush_size();
507 // TODO -- ensure every CPU actually sets this
508 if (size == 0) {
509 size = (jint)DEFAULT_CACHE_LINE_SIZE;
510 }
511 return size;
512 } UNSAFE_END
513
514 ////// Random queries
515
516 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
517 return sizeof(void*);
518 } UNSAFE_END
519
520 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
521 return os::vm_page_size();
522 } UNSAFE_END
523
524 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
525 assert(clazz != NULL, "clazz must not be NULL");
526 assert(name != NULL, "name must not be NULL");
527
528 ResourceMark rm(THREAD);
529 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
530
531 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
532
533 jint offset = -1;
1113 DECLARE_GETPUTOOP(Boolean, Z),
1114 DECLARE_GETPUTOOP(Byte, B),
1115 DECLARE_GETPUTOOP(Short, S),
1116 DECLARE_GETPUTOOP(Char, C),
1117 DECLARE_GETPUTOOP(Int, I),
1118 DECLARE_GETPUTOOP(Long, J),
1119 DECLARE_GETPUTOOP(Float, F),
1120 DECLARE_GETPUTOOP(Double, D),
1121
1122 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1123 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1124 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1125
1126 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1127 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1128 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1129 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1130 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1131 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1132 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1133 {CC "dataCacheLineFlushSize0", CC "()I", FN_PTR(Unsafe_DataCacheLineFlushSize0)},
1134 {CC "addressSize0", CC "()I", FN_PTR(Unsafe_AddressSize0)},
1135 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
1136
1137 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1138 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1139 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1140 {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1141 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1142 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1143 {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1144 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1145 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1146
1147 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1148 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
1149
1150 {CC "getLoadAverage0", CC "([DI)I", FN_PTR(Unsafe_GetLoadAverage0)},
1151
1152 {CC "copyMemory0", CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1153 {CC "copySwapMemory0", CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1154 {CC "writeback0", CC "(" "J" ")V", FN_PTR(Unsafe_WriteBack0)},
1155 {CC "writebackPreSync0", CC "()V", FN_PTR(Unsafe_WriteBackPreSync0)},
1156 {CC "writebackPostSync0", CC "()V", FN_PTR(Unsafe_WriteBackPostSync0)},
1157 {CC "setMemory0", CC "(" OBJ "JJB)V", FN_PTR(Unsafe_SetMemory0)},
1158
1159 {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1160
1161 {CC "shouldBeInitialized0", CC "(" CLS ")Z", FN_PTR(Unsafe_ShouldBeInitialized0)},
1162
1163 {CC "loadFence", CC "()V", FN_PTR(Unsafe_LoadFence)},
1164 {CC "storeFence", CC "()V", FN_PTR(Unsafe_StoreFence)},
1165 {CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
1166
1167 {CC "isBigEndian0", CC "()Z", FN_PTR(Unsafe_isBigEndian0)},
1168 {CC "unalignedAccess0", CC "()Z", FN_PTR(Unsafe_unalignedAccess0)}
1169 };
1170
1171 #undef CC
1172 #undef FN_PTR
1173
1174 #undef ADR
1175 #undef LANG
1176 #undef OBJ
|