< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page
rev 54422 : 8221477: Inject os/cpu-specific constants into Unsafe from JVM
Summary: Initialize Unsafe os/cpu-specific constants using injection instead of native callouts
Reviewed-by: stuefe, coleenp, dholmes


 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
< prev index next >