src/share/vm/prims/unsafe.cpp

Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
   1 /*
   2  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  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/reflection.hpp"
  37 #include "runtime/synchronizer.hpp"
  38 #include "services/threadService.hpp"

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


1189   jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
1190   return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
1191 UNSAFE_END
1192 
1193 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x))
1194   UnsafeWrapper("Unsafe_CompareAndSwapLong");
1195   Handle p (THREAD, JNIHandles::resolve(obj));
1196   jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
1197   if (VM_Version::supports_cx8())
1198     return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
1199   else {
1200     jboolean success = false;
1201     ObjectLocker ol(p, THREAD);
1202     if (*addr == e) { *addr = x; success = true; }
1203     return success;
1204   }
1205 UNSAFE_END
1206 
1207 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
1208   UnsafeWrapper("Unsafe_Park");

1209 #ifndef USDT2
1210   HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
1211 #else /* USDT2 */
1212    HOTSPOT_THREAD_PARK_BEGIN(
1213                              (uintptr_t) thread->parker(), (int) isAbsolute, time);
1214 #endif /* USDT2 */
1215   JavaThreadParkedState jtps(thread, time != 0);
1216   thread->parker()->park(isAbsolute != 0, time);
1217 #ifndef USDT2
1218   HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
1219 #else /* USDT2 */
1220   HOTSPOT_THREAD_PARK_END(
1221                           (uintptr_t) thread->parker());
1222 #endif /* USDT2 */







1223 UNSAFE_END
1224 
1225 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
1226   UnsafeWrapper("Unsafe_Unpark");
1227   Parker* p = NULL;
1228   if (jthread != NULL) {
1229     oop java_thread = JNIHandles::resolve_non_null(jthread);
1230     if (java_thread != NULL) {
1231       jlong lp = java_lang_Thread::park_event(java_thread);
1232       if (lp != 0) {
1233         // This cast is OK even though the jlong might have been read
1234         // non-atomically on 32bit systems, since there, one word will
1235         // always be zero anyway and the value set is always the same
1236         p = (Parker*)addr_from_java(lp);
1237       } else {
1238         // Grab lock if apparently null or using older version of library
1239         MutexLocker mu(Threads_lock);
1240         java_thread = JNIHandles::resolve_non_null(jthread);
1241         if (java_thread != NULL) {
1242           JavaThread* thr = java_lang_Thread::thread(java_thread);


   1 /*
   2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  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/reflection.hpp"
  37 #include "runtime/synchronizer.hpp"
  38 #include "services/threadService.hpp"
  39 #include "trace/tracing.hpp"
  40 #include "utilities/copy.hpp"
  41 #include "utilities/dtrace.hpp"
  42 
  43 /*
  44  *      Implementation of class sun.misc.Unsafe
  45  */
  46 
  47 #ifndef USDT2
  48 HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
  49 HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
  50 HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
  51 #endif /* !USDT2 */
  52 
  53 #define MAX_OBJECT_SIZE \
  54   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  55     + ((julong)max_jint * sizeof(double)) )
  56 
  57 
  58 #define UNSAFE_ENTRY(result_type, header) \
  59   JVM_ENTRY(result_type, header)


1190   jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
1191   return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
1192 UNSAFE_END
1193 
1194 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x))
1195   UnsafeWrapper("Unsafe_CompareAndSwapLong");
1196   Handle p (THREAD, JNIHandles::resolve(obj));
1197   jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
1198   if (VM_Version::supports_cx8())
1199     return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
1200   else {
1201     jboolean success = false;
1202     ObjectLocker ol(p, THREAD);
1203     if (*addr == e) { *addr = x; success = true; }
1204     return success;
1205   }
1206 UNSAFE_END
1207 
1208 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
1209   UnsafeWrapper("Unsafe_Park");
1210   EventThreadPark event;
1211 #ifndef USDT2
1212   HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
1213 #else /* USDT2 */
1214    HOTSPOT_THREAD_PARK_BEGIN(
1215                              (uintptr_t) thread->parker(), (int) isAbsolute, time);
1216 #endif /* USDT2 */
1217   JavaThreadParkedState jtps(thread, time != 0);
1218   thread->parker()->park(isAbsolute != 0, time);
1219 #ifndef USDT2
1220   HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
1221 #else /* USDT2 */
1222   HOTSPOT_THREAD_PARK_END(
1223                           (uintptr_t) thread->parker());
1224 #endif /* USDT2 */
1225   if (event.should_commit()) {
1226     oop obj = thread->current_park_blocker();
1227     event.set_klass(obj ? obj->klass() : NULL);
1228     event.set_timeout(time);
1229     event.set_address(obj ? (TYPE_ADDRESS) (uintptr_t) obj : 0);
1230     event.commit();
1231   }
1232 UNSAFE_END
1233 
1234 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
1235   UnsafeWrapper("Unsafe_Unpark");
1236   Parker* p = NULL;
1237   if (jthread != NULL) {
1238     oop java_thread = JNIHandles::resolve_non_null(jthread);
1239     if (java_thread != NULL) {
1240       jlong lp = java_lang_Thread::park_event(java_thread);
1241       if (lp != 0) {
1242         // This cast is OK even though the jlong might have been read
1243         // non-atomically on 32bit systems, since there, one word will
1244         // always be zero anyway and the value set is always the same
1245         p = (Parker*)addr_from_java(lp);
1246       } else {
1247         // Grab lock if apparently null or using older version of library
1248         MutexLocker mu(Threads_lock);
1249         java_thread = JNIHandles::resolve_non_null(jthread);
1250         if (java_thread != NULL) {
1251           JavaThread* thr = java_lang_Thread::thread(java_thread);