< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page
rev 54303 : 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: duke


 274 
 275 UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
 276   oop p = JNIHandles::resolve(obj);
 277   assert_field_offset_sane(p, offset);
 278   oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
 279   return JNIHandles::make_local(env, v);
 280 } UNSAFE_END
 281 
 282 UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
 283   oop x = JNIHandles::resolve(x_h);
 284   oop p = JNIHandles::resolve(obj);
 285   assert_field_offset_sane(p, offset);
 286   HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 287 } UNSAFE_END
 288 
 289 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
 290   oop v = *(oop*) (address) addr;
 291   return JNIHandles::make_local(env, v);
 292 } UNSAFE_END
 293 
 294 UNSAFE_LEAF(jboolean, Unsafe_isBigEndian0(JNIEnv *env, jobject unsafe)) {
 295 #ifdef VM_LITTLE_ENDIAN
 296   return false;
 297 #else
 298   return true;
 299 #endif
 300 } UNSAFE_END
 301 
 302 UNSAFE_LEAF(jint, Unsafe_unalignedAccess0(JNIEnv *env, jobject unsafe)) {
 303   return UseUnalignedAccesses;
 304 } UNSAFE_END
 305 
 306 #define DEFINE_GETSETOOP(java_type, Type) \
 307  \
 308 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
 309   return MemoryAccess<java_type>(thread, obj, offset).get(); \
 310 } UNSAFE_END \
 311  \
 312 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
 313   MemoryAccess<java_type>(thread, obj, offset).put(x); \
 314 } UNSAFE_END \
 315  \
 316 // END DEFINE_GETSETOOP.
 317 
 318 DEFINE_GETSETOOP(jboolean, Boolean)
 319 DEFINE_GETSETOOP(jbyte, Byte)
 320 DEFINE_GETSETOOP(jshort, Short);
 321 DEFINE_GETSETOOP(jchar, Char);
 322 DEFINE_GETSETOOP(jint, Int);
 323 DEFINE_GETSETOOP(jlong, Long);
 324 DEFINE_GETSETOOP(jfloat, Float);
 325 DEFINE_GETSETOOP(jdouble, Double);


 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 ////// Random queries
 447 
 448 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
 449   return sizeof(void*);
 450 } UNSAFE_END
 451 
 452 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
 453   return os::vm_page_size();
 454 } UNSAFE_END
 455 
 456 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
 457   assert(clazz != NULL, "clazz must not be NULL");
 458   assert(name != NULL, "name must not be NULL");
 459 
 460   ResourceMark rm(THREAD);
 461   char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 462 
 463   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 464 
 465   jint offset = -1;
 466   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
 467     Symbol *name = fs.name();
 468     if (name->equals(utf_name)) {
 469       offset = fs.offset();
 470       break;
 471     }
 472   }
 473   if (offset < 0) {
 474     THROW_0(vmSymbols::java_lang_InternalError());
 475   }


1055     DECLARE_GETPUTOOP(Boolean, Z),
1056     DECLARE_GETPUTOOP(Byte, B),
1057     DECLARE_GETPUTOOP(Short, S),
1058     DECLARE_GETPUTOOP(Char, C),
1059     DECLARE_GETPUTOOP(Int, I),
1060     DECLARE_GETPUTOOP(Long, J),
1061     DECLARE_GETPUTOOP(Float, F),
1062     DECLARE_GETPUTOOP(Double, D),
1063 
1064     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
1065     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
1066     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
1067 
1068     {CC "objectFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_ObjectFieldOffset0)},
1069     {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1070     {CC "staticFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_StaticFieldOffset0)},
1071     {CC "staticFieldBase0",   CC "(" FLD ")" OBJ,        FN_PTR(Unsafe_StaticFieldBase0)},
1072     {CC "ensureClassInitialized0", CC "(" CLS ")V",      FN_PTR(Unsafe_EnsureClassInitialized0)},
1073     {CC "arrayBaseOffset0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayBaseOffset0)},
1074     {CC "arrayIndexScale0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayIndexScale0)},
1075     {CC "addressSize0",       CC "()I",                  FN_PTR(Unsafe_AddressSize0)},
1076     {CC "pageSize",           CC "()I",                  FN_PTR(Unsafe_PageSize)},
1077 
1078     {CC "defineClass0",       CC "(" DC_Args ")" CLS,    FN_PTR(Unsafe_DefineClass0)},
1079     {CC "allocateInstance",   CC "(" CLS ")" OBJ,        FN_PTR(Unsafe_AllocateInstance)},
1080     {CC "throwException",     CC "(" THR ")V",           FN_PTR(Unsafe_ThrowException)},
1081     {CC "compareAndSetReference",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetReference)},
1082     {CC "compareAndSetInt",   CC "(" OBJ "J""I""I"")Z",  FN_PTR(Unsafe_CompareAndSetInt)},
1083     {CC "compareAndSetLong",  CC "(" OBJ "J""J""J"")Z",  FN_PTR(Unsafe_CompareAndSetLong)},
1084     {CC "compareAndExchangeReference", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeReference)},
1085     {CC "compareAndExchangeInt",  CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1086     {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1087 
1088     {CC "park",               CC "(ZJ)V",                FN_PTR(Unsafe_Park)},
1089     {CC "unpark",             CC "(" OBJ ")V",           FN_PTR(Unsafe_Unpark)},
1090 
1091     {CC "getLoadAverage0",    CC "([DI)I",               FN_PTR(Unsafe_GetLoadAverage0)},
1092 
1093     {CC "copyMemory0",        CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1094     {CC "copySwapMemory0",    CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1095     {CC "setMemory0",         CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory0)},
1096 
1097     {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1098 
1099     {CC "shouldBeInitialized0", CC "(" CLS ")Z",         FN_PTR(Unsafe_ShouldBeInitialized0)},
1100 
1101     {CC "loadFence",          CC "()V",                  FN_PTR(Unsafe_LoadFence)},
1102     {CC "storeFence",         CC "()V",                  FN_PTR(Unsafe_StoreFence)},
1103     {CC "fullFence",          CC "()V",                  FN_PTR(Unsafe_FullFence)},
1104 
1105     {CC "isBigEndian0",       CC "()Z",                  FN_PTR(Unsafe_isBigEndian0)},
1106     {CC "unalignedAccess0",   CC "()Z",                  FN_PTR(Unsafe_unalignedAccess0)}
1107 };
1108 
1109 #undef CC
1110 #undef FN_PTR
1111 
1112 #undef ADR
1113 #undef LANG
1114 #undef OBJ
1115 #undef CLS
1116 #undef FLD
1117 #undef THR
1118 #undef DC_Args
1119 #undef DAC_Args
1120 
1121 #undef DECLARE_GETPUTOOP
1122 
1123 
1124 // This function is exported, used by NativeLookup.
1125 // The Unsafe_xxx functions above are called only from the interpreter.
1126 // The optimizer looks at names and signatures to recognize


 274 
 275 UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
 276   oop p = JNIHandles::resolve(obj);
 277   assert_field_offset_sane(p, offset);
 278   oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
 279   return JNIHandles::make_local(env, v);
 280 } UNSAFE_END
 281 
 282 UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
 283   oop x = JNIHandles::resolve(x_h);
 284   oop p = JNIHandles::resolve(obj);
 285   assert_field_offset_sane(p, offset);
 286   HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 287 } UNSAFE_END
 288 
 289 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
 290   oop v = *(oop*) (address) addr;
 291   return JNIHandles::make_local(env, v);
 292 } UNSAFE_END
 293 












 294 #define DEFINE_GETSETOOP(java_type, Type) \
 295  \
 296 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
 297   return MemoryAccess<java_type>(thread, obj, offset).get(); \
 298 } UNSAFE_END \
 299  \
 300 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
 301   MemoryAccess<java_type>(thread, obj, offset).put(x); \
 302 } UNSAFE_END \
 303  \
 304 // END DEFINE_GETSETOOP.
 305 
 306 DEFINE_GETSETOOP(jboolean, Boolean)
 307 DEFINE_GETSETOOP(jbyte, Byte)
 308 DEFINE_GETSETOOP(jshort, Short);
 309 DEFINE_GETSETOOP(jchar, Char);
 310 DEFINE_GETSETOOP(jint, Int);
 311 DEFINE_GETSETOOP(jlong, Long);
 312 DEFINE_GETSETOOP(jfloat, Float);
 313 DEFINE_GETSETOOP(jdouble, Double);


 416     address dst = (address)dstOffset;
 417 
 418     Copy::conjoint_swap(src, dst, sz, esz);
 419   } else {
 420     // At least one of src/dst are on heap, transition to VM to access raw pointers
 421 
 422     JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
 423       oop srcp = JNIHandles::resolve(srcObj);
 424       oop dstp = JNIHandles::resolve(dstObj);
 425 
 426       address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
 427       address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
 428 
 429       Copy::conjoint_swap(src, dst, sz, esz);
 430     } JVM_END
 431   }
 432 } UNSAFE_END
 433 
 434 ////// Random queries
 435 








 436 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
 437   assert(clazz != NULL, "clazz must not be NULL");
 438   assert(name != NULL, "name must not be NULL");
 439 
 440   ResourceMark rm(THREAD);
 441   char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 442 
 443   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 444 
 445   jint offset = -1;
 446   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
 447     Symbol *name = fs.name();
 448     if (name->equals(utf_name)) {
 449       offset = fs.offset();
 450       break;
 451     }
 452   }
 453   if (offset < 0) {
 454     THROW_0(vmSymbols::java_lang_InternalError());
 455   }


1035     DECLARE_GETPUTOOP(Boolean, Z),
1036     DECLARE_GETPUTOOP(Byte, B),
1037     DECLARE_GETPUTOOP(Short, S),
1038     DECLARE_GETPUTOOP(Char, C),
1039     DECLARE_GETPUTOOP(Int, I),
1040     DECLARE_GETPUTOOP(Long, J),
1041     DECLARE_GETPUTOOP(Float, F),
1042     DECLARE_GETPUTOOP(Double, D),
1043 
1044     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
1045     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
1046     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
1047 
1048     {CC "objectFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_ObjectFieldOffset0)},
1049     {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1050     {CC "staticFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_StaticFieldOffset0)},
1051     {CC "staticFieldBase0",   CC "(" FLD ")" OBJ,        FN_PTR(Unsafe_StaticFieldBase0)},
1052     {CC "ensureClassInitialized0", CC "(" CLS ")V",      FN_PTR(Unsafe_EnsureClassInitialized0)},
1053     {CC "arrayBaseOffset0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayBaseOffset0)},
1054     {CC "arrayIndexScale0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayIndexScale0)},


1055 
1056     {CC "defineClass0",       CC "(" DC_Args ")" CLS,    FN_PTR(Unsafe_DefineClass0)},
1057     {CC "allocateInstance",   CC "(" CLS ")" OBJ,        FN_PTR(Unsafe_AllocateInstance)},
1058     {CC "throwException",     CC "(" THR ")V",           FN_PTR(Unsafe_ThrowException)},
1059     {CC "compareAndSetReference",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetReference)},
1060     {CC "compareAndSetInt",   CC "(" OBJ "J""I""I"")Z",  FN_PTR(Unsafe_CompareAndSetInt)},
1061     {CC "compareAndSetLong",  CC "(" OBJ "J""J""J"")Z",  FN_PTR(Unsafe_CompareAndSetLong)},
1062     {CC "compareAndExchangeReference", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeReference)},
1063     {CC "compareAndExchangeInt",  CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1064     {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1065 
1066     {CC "park",               CC "(ZJ)V",                FN_PTR(Unsafe_Park)},
1067     {CC "unpark",             CC "(" OBJ ")V",           FN_PTR(Unsafe_Unpark)},
1068 
1069     {CC "getLoadAverage0",    CC "([DI)I",               FN_PTR(Unsafe_GetLoadAverage0)},
1070 
1071     {CC "copyMemory0",        CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1072     {CC "copySwapMemory0",    CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1073     {CC "setMemory0",         CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory0)},
1074 
1075     {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1076 
1077     {CC "shouldBeInitialized0", CC "(" CLS ")Z",         FN_PTR(Unsafe_ShouldBeInitialized0)},
1078 
1079     {CC "loadFence",          CC "()V",                  FN_PTR(Unsafe_LoadFence)},
1080     {CC "storeFence",         CC "()V",                  FN_PTR(Unsafe_StoreFence)},
1081     {CC "fullFence",          CC "()V",                  FN_PTR(Unsafe_FullFence)},



1082 };
1083 
1084 #undef CC
1085 #undef FN_PTR
1086 
1087 #undef ADR
1088 #undef LANG
1089 #undef OBJ
1090 #undef CLS
1091 #undef FLD
1092 #undef THR
1093 #undef DC_Args
1094 #undef DAC_Args
1095 
1096 #undef DECLARE_GETPUTOOP
1097 
1098 
1099 // This function is exported, used by NativeLookup.
1100 // The Unsafe_xxx functions above are called only from the interpreter.
1101 // The optimizer looks at names and signatures to recognize
< prev index next >