< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/vmSymbols.hpp"
  27 #include "utilities/macros.hpp"
  28 #if INCLUDE_ALL_GCS
  29 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  30 #endif // INCLUDE_ALL_GCS

  31 #include "memory/allocation.inline.hpp"
  32 #include "prims/jni.h"
  33 #include "prims/jvm.h"
  34 #include "runtime/globals.hpp"
  35 #include "runtime/interfaceSupport.hpp"
  36 #include "runtime/prefetch.inline.hpp"
  37 #include "runtime/orderAccess.inline.hpp"
  38 #include "runtime/reflection.hpp"
  39 #include "runtime/synchronizer.hpp"
  40 #include "services/threadService.hpp"
  41 #include "trace/tracing.hpp"
  42 #include "utilities/copy.hpp"
  43 #include "utilities/dtrace.hpp"
  44 
  45 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  46 
  47 /*
  48  *      Implementation of class sun.misc.Unsafe
  49  */
  50 
  51 #ifndef USDT2
  52 HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
  53 HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
  54 HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
  55 #endif /* !USDT2 */
  56 
  57 #define MAX_OBJECT_SIZE \
  58   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  59     + ((julong)max_jint * sizeof(double)) )
  60 
  61 


1219 
1220 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x))
1221   UnsafeWrapper("Unsafe_CompareAndSwapLong");
1222   Handle p (THREAD, JNIHandles::resolve(obj));
1223   jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
1224 #ifdef SUPPORTS_NATIVE_CX8
1225   return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
1226 #else
1227   if (VM_Version::supports_cx8())
1228     return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
1229   else {
1230     jboolean success = false;
1231     MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
1232     jlong val = Atomic::load(addr);
1233     if (val == e) { Atomic::store(x, addr); success = true; }
1234     return success;
1235   }
1236 #endif
1237 UNSAFE_END
1238 










1239 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
1240   UnsafeWrapper("Unsafe_Park");
1241   EventThreadPark event;
1242 #ifndef USDT2
1243   HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
1244 #else /* USDT2 */
1245    HOTSPOT_THREAD_PARK_BEGIN(
1246                              (uintptr_t) thread->parker(), (int) isAbsolute, time);
1247 #endif /* USDT2 */
1248   JavaThreadParkedState jtps(thread, time != 0);
1249   thread->parker()->park(isAbsolute != 0, time);
1250 #ifndef USDT2
1251   HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
1252 #else /* USDT2 */
1253   HOTSPOT_THREAD_PARK_END(
1254                           (uintptr_t) thread->parker());
1255 #endif /* USDT2 */
1256   if (event.should_commit()) {
1257     oop obj = thread->current_park_blocker();
1258     event.set_klass((obj != NULL) ? obj->klass() : NULL);
1259     event.set_timeout(time);
1260     event.set_address((obj != NULL) ? (TYPE_ADDRESS) cast_from_oop<uintptr_t>(obj) : 0);
1261     event.commit();





1262   }
1263 UNSAFE_END
1264 
1265 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
1266   UnsafeWrapper("Unsafe_Unpark");
1267   Parker* p = NULL;
1268   if (jthread != NULL) {
1269     oop java_thread = JNIHandles::resolve_non_null(jthread);
1270     if (java_thread != NULL) {
1271       jlong lp = java_lang_Thread::park_event(java_thread);
1272       if (lp != 0) {
1273         // This cast is OK even though the jlong might have been read
1274         // non-atomically on 32bit systems, since there, one word will
1275         // always be zero anyway and the value set is always the same
1276         p = (Parker*)addr_from_java(lp);
1277       } else {
1278         // Grab lock if apparently null or using older version of library
1279         MutexLocker mu(Threads_lock);
1280         java_thread = JNIHandles::resolve_non_null(jthread);
1281         if (java_thread != NULL) {




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/vmSymbols.hpp"
  27 #include "utilities/macros.hpp"
  28 #if INCLUDE_ALL_GCS
  29 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  30 #endif // INCLUDE_ALL_GCS
  31 #include "jfr/jfrEvents.hpp"
  32 #include "memory/allocation.inline.hpp"
  33 #include "prims/jni.h"
  34 #include "prims/jvm.h"
  35 #include "runtime/globals.hpp"
  36 #include "runtime/interfaceSupport.hpp"
  37 #include "runtime/prefetch.inline.hpp"
  38 #include "runtime/orderAccess.inline.hpp"
  39 #include "runtime/reflection.hpp"
  40 #include "runtime/synchronizer.hpp"
  41 #include "services/threadService.hpp"

  42 #include "utilities/copy.hpp"
  43 #include "utilities/dtrace.hpp"
  44 
  45 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  46 
  47 /*
  48  *      Implementation of class sun.misc.Unsafe
  49  */
  50 
  51 #ifndef USDT2
  52 HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
  53 HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
  54 HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
  55 #endif /* !USDT2 */
  56 
  57 #define MAX_OBJECT_SIZE \
  58   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  59     + ((julong)max_jint * sizeof(double)) )
  60 
  61 


1219 
1220 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x))
1221   UnsafeWrapper("Unsafe_CompareAndSwapLong");
1222   Handle p (THREAD, JNIHandles::resolve(obj));
1223   jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
1224 #ifdef SUPPORTS_NATIVE_CX8
1225   return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
1226 #else
1227   if (VM_Version::supports_cx8())
1228     return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
1229   else {
1230     jboolean success = false;
1231     MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
1232     jlong val = Atomic::load(addr);
1233     if (val == e) { Atomic::store(x, addr); success = true; }
1234     return success;
1235   }
1236 #endif
1237 UNSAFE_END
1238 
1239 static void post_thread_park_event(EventThreadPark* event, const oop obj, jlong timeout_nanos, jlong until_epoch_millis) {
1240   assert(event != NULL, "invariant");
1241   assert(event->should_commit(), "invariant");
1242   event->set_parkedClass((obj != NULL) ? obj->klass() : NULL);
1243   event->set_timeout(timeout_nanos);
1244   event->set_until(until_epoch_millis);
1245   event->set_address((obj != NULL) ? (u8)cast_from_oop<uintptr_t>(obj) : 0);
1246   event->commit();
1247 }
1248 
1249 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
1250   UnsafeWrapper("Unsafe_Park");
1251   EventThreadPark event;
1252 #ifndef USDT2
1253   HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
1254 #else /* USDT2 */
1255    HOTSPOT_THREAD_PARK_BEGIN(
1256                              (uintptr_t) thread->parker(), (int) isAbsolute, time);
1257 #endif /* USDT2 */
1258   JavaThreadParkedState jtps(thread, time != 0);
1259   thread->parker()->park(isAbsolute != 0, time);
1260 #ifndef USDT2
1261   HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
1262 #else /* USDT2 */
1263   HOTSPOT_THREAD_PARK_END(
1264                           (uintptr_t) thread->parker());
1265 #endif /* USDT2 */
1266   if (event.should_commit()) {
1267     const oop obj = thread->current_park_blocker();
1268     if (time == 0) {
1269       post_thread_park_event(&event, obj, min_jlong, min_jlong);
1270     } else {
1271       if (isAbsolute != 0) {
1272         post_thread_park_event(&event, obj, min_jlong, time);
1273       } else {
1274         post_thread_park_event(&event, obj, time, min_jlong);
1275       }
1276     }
1277   }
1278 UNSAFE_END
1279 
1280 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
1281   UnsafeWrapper("Unsafe_Unpark");
1282   Parker* p = NULL;
1283   if (jthread != NULL) {
1284     oop java_thread = JNIHandles::resolve_non_null(jthread);
1285     if (java_thread != NULL) {
1286       jlong lp = java_lang_Thread::park_event(java_thread);
1287       if (lp != 0) {
1288         // This cast is OK even though the jlong might have been read
1289         // non-atomically on 32bit systems, since there, one word will
1290         // always be zero anyway and the value set is always the same
1291         p = (Parker*)addr_from_java(lp);
1292       } else {
1293         // Grab lock if apparently null or using older version of library
1294         MutexLocker mu(Threads_lock);
1295         java_thread = JNIHandles::resolve_non_null(jthread);
1296         if (java_thread != NULL) {


< prev index next >