< 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 "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


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) {
1297           JavaThread* thr = java_lang_Thread::thread(java_thread);




  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 #if INCLUDE_JFR
  32 #include "jfr/jfrEvents.hpp"
  33 #endif
  34 #include "memory/allocation.inline.hpp"
  35 #include "prims/jni.h"
  36 #include "prims/jvm.h"
  37 #include "runtime/globals.hpp"
  38 #include "runtime/interfaceSupport.hpp"
  39 #include "runtime/prefetch.inline.hpp"
  40 #include "runtime/orderAccess.inline.hpp"
  41 #include "runtime/reflection.hpp"
  42 #include "runtime/synchronizer.hpp"
  43 #include "services/threadService.hpp"
  44 #include "utilities/copy.hpp"
  45 #include "utilities/dtrace.hpp"
  46 
  47 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  48 
  49 /*
  50  *      Implementation of class sun.misc.Unsafe
  51  */
  52 
  53 #ifndef USDT2


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


< prev index next >