275
276 UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
277 oop p = JNIHandles::resolve(obj);
278 assert_field_offset_sane(p, offset);
279 oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
280 return JNIHandles::make_local(env, v);
281 } UNSAFE_END
282
283 UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
284 oop x = JNIHandles::resolve(x_h);
285 oop p = JNIHandles::resolve(obj);
286 assert_field_offset_sane(p, offset);
287 HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
288 } UNSAFE_END
289
290 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
291 oop v = *(oop*) (address) addr;
292 return JNIHandles::make_local(env, v);
293 } UNSAFE_END
294
295 UNSAFE_LEAF(jboolean, Unsafe_isBigEndian0(JNIEnv *env, jobject unsafe)) {
296 #ifdef VM_LITTLE_ENDIAN
297 return false;
298 #else
299 return true;
300 #endif
301 } UNSAFE_END
302
303 UNSAFE_LEAF(jint, Unsafe_unalignedAccess0(JNIEnv *env, jobject unsafe)) {
304 return UseUnalignedAccesses;
305 } UNSAFE_END
306
307 #define DEFINE_GETSETOOP(java_type, Type) \
308 \
309 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
310 return MemoryAccess<java_type>(thread, obj, offset).get(); \
311 } UNSAFE_END \
312 \
313 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
314 MemoryAccess<java_type>(thread, obj, offset).put(x); \
315 } UNSAFE_END \
316 \
317 // END DEFINE_GETSETOOP.
318
319 DEFINE_GETSETOOP(jboolean, Boolean)
320 DEFINE_GETSETOOP(jbyte, Byte)
321 DEFINE_GETSETOOP(jshort, Short);
322 DEFINE_GETSETOOP(jchar, Char);
323 DEFINE_GETSETOOP(jint, Int);
324 DEFINE_GETSETOOP(jlong, Long);
325 DEFINE_GETSETOOP(jfloat, Float);
326 DEFINE_GETSETOOP(jdouble, Double);
429 address dst = (address)dstOffset;
430
431 Copy::conjoint_swap(src, dst, sz, esz);
432 } else {
433 // At least one of src/dst are on heap, transition to VM to access raw pointers
434
435 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
436 oop srcp = JNIHandles::resolve(srcObj);
437 oop dstp = JNIHandles::resolve(dstObj);
438
439 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
440 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
441
442 Copy::conjoint_swap(src, dst, sz, esz);
443 } JVM_END
444 }
445 } UNSAFE_END
446
447 ////// Random queries
448
449 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
450 return sizeof(void*);
451 } UNSAFE_END
452
453 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
454 return os::vm_page_size();
455 } UNSAFE_END
456
457 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
458 assert(clazz != NULL, "clazz must not be NULL");
459 assert(name != NULL, "name must not be NULL");
460
461 ResourceMark rm(THREAD);
462 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
463
464 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
465
466 jint offset = -1;
467 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
468 Symbol *name = fs.name();
469 if (name->equals(utf_name)) {
470 offset = fs.offset();
471 break;
472 }
473 }
474 if (offset < 0) {
475 THROW_0(vmSymbols::java_lang_InternalError());
476 }
1056 DECLARE_GETPUTOOP(Boolean, Z),
1057 DECLARE_GETPUTOOP(Byte, B),
1058 DECLARE_GETPUTOOP(Short, S),
1059 DECLARE_GETPUTOOP(Char, C),
1060 DECLARE_GETPUTOOP(Int, I),
1061 DECLARE_GETPUTOOP(Long, J),
1062 DECLARE_GETPUTOOP(Float, F),
1063 DECLARE_GETPUTOOP(Double, D),
1064
1065 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1066 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1067 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1068
1069 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1070 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1071 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1072 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1073 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1074 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1075 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1076 {CC "addressSize0", CC "()I", FN_PTR(Unsafe_AddressSize0)},
1077 {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
1078
1079 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1080 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1081 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1082 {CC "compareAndSetReference",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetReference)},
1083 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1084 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1085 {CC "compareAndExchangeReference", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeReference)},
1086 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1087 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1088
1089 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1090 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
1091
1092 {CC "getLoadAverage0", CC "([DI)I", FN_PTR(Unsafe_GetLoadAverage0)},
1093
1094 {CC "copyMemory0", CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1095 {CC "copySwapMemory0", CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1096 {CC "setMemory0", CC "(" OBJ "JJB)V", FN_PTR(Unsafe_SetMemory0)},
1097
1098 {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1099
1100 {CC "shouldBeInitialized0", CC "(" CLS ")Z", FN_PTR(Unsafe_ShouldBeInitialized0)},
1101
1102 {CC "loadFence", CC "()V", FN_PTR(Unsafe_LoadFence)},
1103 {CC "storeFence", CC "()V", FN_PTR(Unsafe_StoreFence)},
1104 {CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
1105
1106 {CC "isBigEndian0", CC "()Z", FN_PTR(Unsafe_isBigEndian0)},
1107 {CC "unalignedAccess0", CC "()Z", FN_PTR(Unsafe_unalignedAccess0)}
1108 };
1109
1110 #undef CC
1111 #undef FN_PTR
1112
1113 #undef ADR
1114 #undef LANG
1115 #undef OBJ
1116 #undef CLS
1117 #undef FLD
1118 #undef THR
1119 #undef DC_Args
1120 #undef DAC_Args
1121
1122 #undef DECLARE_GETPUTOOP
1123
1124
1125 // This function is exported, used by NativeLookup.
1126 // The Unsafe_xxx functions above are called only from the interpreter.
1127 // The optimizer looks at names and signatures to recognize
|
275
276 UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
277 oop p = JNIHandles::resolve(obj);
278 assert_field_offset_sane(p, offset);
279 oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
280 return JNIHandles::make_local(env, v);
281 } UNSAFE_END
282
283 UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
284 oop x = JNIHandles::resolve(x_h);
285 oop p = JNIHandles::resolve(obj);
286 assert_field_offset_sane(p, offset);
287 HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
288 } UNSAFE_END
289
290 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
291 oop v = *(oop*) (address) addr;
292 return JNIHandles::make_local(env, v);
293 } UNSAFE_END
294
295 #define DEFINE_GETSETOOP(java_type, Type) \
296 \
297 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
298 return MemoryAccess<java_type>(thread, obj, offset).get(); \
299 } UNSAFE_END \
300 \
301 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
302 MemoryAccess<java_type>(thread, obj, offset).put(x); \
303 } UNSAFE_END \
304 \
305 // END DEFINE_GETSETOOP.
306
307 DEFINE_GETSETOOP(jboolean, Boolean)
308 DEFINE_GETSETOOP(jbyte, Byte)
309 DEFINE_GETSETOOP(jshort, Short);
310 DEFINE_GETSETOOP(jchar, Char);
311 DEFINE_GETSETOOP(jint, Int);
312 DEFINE_GETSETOOP(jlong, Long);
313 DEFINE_GETSETOOP(jfloat, Float);
314 DEFINE_GETSETOOP(jdouble, Double);
417 address dst = (address)dstOffset;
418
419 Copy::conjoint_swap(src, dst, sz, esz);
420 } else {
421 // At least one of src/dst are on heap, transition to VM to access raw pointers
422
423 JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
424 oop srcp = JNIHandles::resolve(srcObj);
425 oop dstp = JNIHandles::resolve(dstObj);
426
427 address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
428 address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
429
430 Copy::conjoint_swap(src, dst, sz, esz);
431 } JVM_END
432 }
433 } UNSAFE_END
434
435 ////// Random queries
436
437 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
438 assert(clazz != NULL, "clazz must not be NULL");
439 assert(name != NULL, "name must not be NULL");
440
441 ResourceMark rm(THREAD);
442 char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
443
444 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
445
446 jint offset = -1;
447 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
448 Symbol *name = fs.name();
449 if (name->equals(utf_name)) {
450 offset = fs.offset();
451 break;
452 }
453 }
454 if (offset < 0) {
455 THROW_0(vmSymbols::java_lang_InternalError());
456 }
1036 DECLARE_GETPUTOOP(Boolean, Z),
1037 DECLARE_GETPUTOOP(Byte, B),
1038 DECLARE_GETPUTOOP(Short, S),
1039 DECLARE_GETPUTOOP(Char, C),
1040 DECLARE_GETPUTOOP(Int, I),
1041 DECLARE_GETPUTOOP(Long, J),
1042 DECLARE_GETPUTOOP(Float, F),
1043 DECLARE_GETPUTOOP(Double, D),
1044
1045 {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
1046 {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
1047 {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
1048
1049 {CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
1050 {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1051 {CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
1052 {CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
1053 {CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
1054 {CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
1055 {CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
1056
1057 {CC "defineClass0", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass0)},
1058 {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
1059 {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
1060 {CC "compareAndSetReference",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetReference)},
1061 {CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)},
1062 {CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)},
1063 {CC "compareAndExchangeReference", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeReference)},
1064 {CC "compareAndExchangeInt", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1065 {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1066
1067 {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
1068 {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
1069
1070 {CC "getLoadAverage0", CC "([DI)I", FN_PTR(Unsafe_GetLoadAverage0)},
1071
1072 {CC "copyMemory0", CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1073 {CC "copySwapMemory0", CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1074 {CC "setMemory0", CC "(" OBJ "JJB)V", FN_PTR(Unsafe_SetMemory0)},
1075
1076 {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1077
1078 {CC "shouldBeInitialized0", CC "(" CLS ")Z", FN_PTR(Unsafe_ShouldBeInitialized0)},
1079
1080 {CC "loadFence", CC "()V", FN_PTR(Unsafe_LoadFence)},
1081 {CC "storeFence", CC "()V", FN_PTR(Unsafe_StoreFence)},
1082 {CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
1083 };
1084
1085 #undef CC
1086 #undef FN_PTR
1087
1088 #undef ADR
1089 #undef LANG
1090 #undef OBJ
1091 #undef CLS
1092 #undef FLD
1093 #undef THR
1094 #undef DC_Args
1095 #undef DAC_Args
1096
1097 #undef DECLARE_GETPUTOOP
1098
1099
1100 // This function is exported, used by NativeLookup.
1101 // The Unsafe_xxx functions above are called only from the interpreter.
1102 // The optimizer looks at names and signatures to recognize
|