< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page




 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   }


 932       if (isAbsolute != 0) {
 933         post_thread_park_event(&event, obj, min_jlong, time);
 934       } else {
 935         post_thread_park_event(&event, obj, time, min_jlong);
 936       }
 937     }
 938   }
 939   HOTSPOT_THREAD_PARK_END((uintptr_t) thread->parker());
 940 } UNSAFE_END
 941 
 942 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) {
 943   Parker* p = NULL;
 944 
 945   if (jthread != NULL) {
 946     ThreadsListHandle tlh;
 947     JavaThread* thr = NULL;
 948     oop java_thread = NULL;
 949     (void) tlh.cv_internal_thread_to_JavaThread(jthread, &thr, &java_thread);
 950     if (java_thread != NULL) {
 951       // This is a valid oop.
 952       if (thr != NULL) {
 953         // The JavaThread is alive.
 954         p = thr->parker();














 955       }
 956     }
 957   } // ThreadsListHandle is destroyed here.
 958 
 959   // 'p' points to type-stable-memory if non-NULL. If the target
 960   // thread terminates before we get here the new user of this
 961   // Parker will get a 'spurious' unpark - which is perfectly valid.
 962   if (p != NULL) {
 963     HOTSPOT_THREAD_UNPARK((uintptr_t) p);
 964     p->unpark();
 965   }
 966 } UNSAFE_END
 967 
 968 UNSAFE_ENTRY(jint, Unsafe_GetLoadAverage0(JNIEnv *env, jobject unsafe, jdoubleArray loadavg, jint nelem)) {
 969   const int max_nelem = 3;
 970   double la[max_nelem];
 971   jint ret;
 972 
 973   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(loadavg));
 974   assert(a->is_typeArray(), "must be type array");
 975 
 976   ret = os::loadavg(la, nelem);
 977   if (ret == -1) {
 978     return -1;
 979   }
 980 
 981   // if successful, ret is the number of samples actually retrieved.


1025     DECLARE_GETPUTOOP(Boolean, Z),
1026     DECLARE_GETPUTOOP(Byte, B),
1027     DECLARE_GETPUTOOP(Short, S),
1028     DECLARE_GETPUTOOP(Char, C),
1029     DECLARE_GETPUTOOP(Int, I),
1030     DECLARE_GETPUTOOP(Long, J),
1031     DECLARE_GETPUTOOP(Float, F),
1032     DECLARE_GETPUTOOP(Double, D),
1033 
1034     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
1035     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
1036     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
1037 
1038     {CC "objectFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_ObjectFieldOffset0)},
1039     {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1040     {CC "staticFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_StaticFieldOffset0)},
1041     {CC "staticFieldBase0",   CC "(" FLD ")" OBJ,        FN_PTR(Unsafe_StaticFieldBase0)},
1042     {CC "ensureClassInitialized0", CC "(" CLS ")V",      FN_PTR(Unsafe_EnsureClassInitialized0)},
1043     {CC "arrayBaseOffset0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayBaseOffset0)},
1044     {CC "arrayIndexScale0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayIndexScale0)},


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



1072 };
1073 
1074 #undef CC
1075 #undef FN_PTR
1076 
1077 #undef ADR
1078 #undef LANG
1079 #undef OBJ
1080 #undef CLS
1081 #undef FLD
1082 #undef THR
1083 #undef DC_Args
1084 #undef DAC_Args
1085 
1086 #undef DECLARE_GETPUTOOP
1087 
1088 
1089 // This function is exported, used by NativeLookup.
1090 // The Unsafe_xxx functions above are called only from the interpreter.
1091 // 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 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   }


 952       if (isAbsolute != 0) {
 953         post_thread_park_event(&event, obj, min_jlong, time);
 954       } else {
 955         post_thread_park_event(&event, obj, time, min_jlong);
 956       }
 957     }
 958   }
 959   HOTSPOT_THREAD_PARK_END((uintptr_t) thread->parker());
 960 } UNSAFE_END
 961 
 962 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) {
 963   Parker* p = NULL;
 964 
 965   if (jthread != NULL) {
 966     ThreadsListHandle tlh;
 967     JavaThread* thr = NULL;
 968     oop java_thread = NULL;
 969     (void) tlh.cv_internal_thread_to_JavaThread(jthread, &thr, &java_thread);
 970     if (java_thread != NULL) {
 971       // This is a valid oop.
 972       jlong lp = java_lang_Thread::park_event(java_thread);
 973       if (lp != 0) {
 974         // This cast is OK even though the jlong might have been read
 975         // non-atomically on 32bit systems, since there, one word will
 976         // always be zero anyway and the value set is always the same
 977         p = (Parker*)addr_from_java(lp);
 978       } else {
 979         // Not cached in the java.lang.Thread oop yet (could be an
 980         // older version of library).
 981         if (thr != NULL) {
 982           // The JavaThread is alive.
 983           p = thr->parker();
 984           if (p != NULL) {
 985             // Cache the Parker in the java.lang.Thread oop for next time.
 986             java_lang_Thread::set_park_event(java_thread, addr_to_java(p));
 987           }
 988         }
 989       }
 990     }
 991   } // ThreadsListHandle is destroyed here.
 992 



 993   if (p != NULL) {
 994     HOTSPOT_THREAD_UNPARK((uintptr_t) p);
 995     p->unpark();
 996   }
 997 } UNSAFE_END
 998 
 999 UNSAFE_ENTRY(jint, Unsafe_GetLoadAverage0(JNIEnv *env, jobject unsafe, jdoubleArray loadavg, jint nelem)) {
1000   const int max_nelem = 3;
1001   double la[max_nelem];
1002   jint ret;
1003 
1004   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(loadavg));
1005   assert(a->is_typeArray(), "must be type array");
1006 
1007   ret = os::loadavg(la, nelem);
1008   if (ret == -1) {
1009     return -1;
1010   }
1011 
1012   // if successful, ret is the number of samples actually retrieved.


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