< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page




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


 179     OrderAccess::fence(); \
 180   } \
 181   volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
 182 
 183 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
 184   oop p = JNIHandles::resolve(obj); \
 185   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
 186 
 187 // Macros for oops that check UseCompressedOops
 188 
 189 #define GET_OOP_FIELD(obj, offset, v) \
 190   oop p = JNIHandles::resolve(obj);   \
 191   oop v;                              \
 192   if (UseCompressedOops) {            \
 193     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
 194     v = oopDesc::decode_heap_oop(n);                                \
 195   } else {                            \
 196     v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
 197   }
 198 
 199 
 200 // Get/SetObject must be special-cased, since it works with handles.
 201 
 202 // We could be accessing the referent field in a reference
 203 // object. If G1 is enabled then we need to register non-null
 204 // referent with the SATB barrier.
 205 
 206 #if INCLUDE_ALL_GCS
 207 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
 208   if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
 209     Klass* k = o->klass();
 210     if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 211       assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 212       return true;
 213     }
 214   }
 215  return false;
 216 }
 217 #endif
 218 
 219 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
 220 #if INCLUDE_ALL_GCS
 221   if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
 222     G1SATBCardTableModRefBS::enqueue(v);
 223   }
 224 #endif
 225 }
 226 
 227 // The xxx140 variants for backward compatibility do not allow a full-width offset.
 228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
 229   UnsafeWrapper("Unsafe_GetObject");
 230   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
 231   GET_OOP_FIELD(obj, offset, v)
 232 






 233   ensure_satb_referent_alive(p, offset, v);
 234 
 235   return JNIHandles::make_local(env, v);
 236 UNSAFE_END
 237 
 238 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
 239   UnsafeWrapper("Unsafe_SetObject");
 240   if (obj == NULL)  THROW(vmSymbols::java_lang_NullPointerException());
 241   oop x = JNIHandles::resolve(x_h);
 242   //SET_FIELD(obj, offset, oop, x);
 243   oop p = JNIHandles::resolve(obj);
 244   if (UseCompressedOops) {
 245     if (x != NULL) {
 246       // If there is a heap base pointer, we are obliged to emit a store barrier.
 247       oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 248     } else {
 249       narrowOop n = oopDesc::encode_heap_oop_not_null(x);
 250       *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
 251     }
 252   } else {
 253     if (x != NULL) {
 254       // If there is a heap base pointer, we are obliged to emit a store barrier.
 255       oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 256     } else {
 257       *(oop*)index_oop_from_field_offset_long(p, offset) = x;
 258     }
 259   }
 260 UNSAFE_END
 261 
 262 // The normal variants allow a null base pointer with an arbitrary address.
 263 // But if the base pointer is non-null, the offset should make some sense.
 264 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 265 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 266   UnsafeWrapper("Unsafe_GetObject");
 267   GET_OOP_FIELD(obj, offset, v)
 268 






 269   ensure_satb_referent_alive(p, offset, v);
 270 
 271   return JNIHandles::make_local(env, v);
 272 UNSAFE_END
 273 
 274 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 275   UnsafeWrapper("Unsafe_SetObject");
 276   oop x = JNIHandles::resolve(x_h);
 277   oop p = JNIHandles::resolve(obj);
 278   if (UseCompressedOops) {
 279     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 280   } else {
 281     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 282   }
 283 UNSAFE_END
 284 
 285 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 286   UnsafeWrapper("Unsafe_GetObjectVolatile");
 287   oop p = JNIHandles::resolve(obj);
 288   void* addr = index_oop_from_field_offset_long(p, offset);
 289   volatile oop v;
 290   if (UseCompressedOops) {
 291     volatile narrowOop n = *(volatile narrowOop*) addr;
 292     (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
 293   } else {
 294     (void)const_cast<oop&>(v = *(volatile oop*) addr);
 295   }






 296 
 297   ensure_satb_referent_alive(p, offset, v);
 298 
 299   OrderAccess::acquire();
 300   return JNIHandles::make_local(env, v);
 301 UNSAFE_END
 302 
 303 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 304   UnsafeWrapper("Unsafe_SetObjectVolatile");
 305   oop x = JNIHandles::resolve(x_h);
 306   oop p = JNIHandles::resolve(obj);
 307   void* addr = index_oop_from_field_offset_long(p, offset);
 308   OrderAccess::release();
 309   if (UseCompressedOops) {
 310     oop_store((narrowOop*)addr, x);
 311   } else {
 312     oop_store((oop*)addr, x);
 313   }
 314   OrderAccess::fence();
 315 UNSAFE_END




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


 180     OrderAccess::fence(); \
 181   } \
 182   volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
 183 
 184 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
 185   oop p = JNIHandles::resolve(obj); \
 186   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
 187 
 188 // Macros for oops that check UseCompressedOops
 189 
 190 #define GET_OOP_FIELD(obj, offset, v) \
 191   oop p = JNIHandles::resolve(obj);   \
 192   oop v;                              \
 193   if (UseCompressedOops) {            \
 194     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
 195     v = oopDesc::decode_heap_oop(n);                                \
 196   } else {                            \
 197     v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
 198   }
 199 

 200 // Get/SetObject must be special-cased, since it works with handles.
 201 
 202 // We could be accessing the referent field in a reference
 203 // object. If G1 is enabled then we need to register non-null
 204 // referent with the SATB barrier.
 205 
 206 #if INCLUDE_ALL_GCS
 207 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
 208   if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
 209     Klass* k = o->klass();
 210     if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 211       assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 212       return true;
 213     }
 214   }
 215  return false;
 216 }
 217 #endif
 218 
 219 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
 220 #if INCLUDE_ALL_GCS
 221   if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
 222     G1SATBCardTableModRefBS::enqueue(v);
 223   }
 224 #endif
 225 }
 226 
 227 // The xxx140 variants for backward compatibility do not allow a full-width offset.
 228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
 229   UnsafeWrapper("Unsafe_GetObject");
 230   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
 231   GET_OOP_FIELD(obj, offset, v)
 232 
 233 #if INCLUDE_ALL_GCS
 234   if (UseShenandoahGC) {
 235     v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v);
 236   }
 237 #endif
 238 
 239   ensure_satb_referent_alive(p, offset, v);
 240 
 241   return JNIHandles::make_local(env, v);
 242 UNSAFE_END
 243 
 244 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
 245   UnsafeWrapper("Unsafe_SetObject");
 246   if (obj == NULL)  THROW(vmSymbols::java_lang_NullPointerException());
 247   oop x = JNIHandles::resolve(x_h);
 248   //SET_FIELD(obj, offset, oop, x);
 249   oop p = JNIHandles::resolve(obj);
 250   if (UseCompressedOops) {
 251     if (x != NULL) {
 252       // If there is a heap base pointer, we are obliged to emit a store barrier.
 253       oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 254     } else {
 255       narrowOop n = oopDesc::encode_heap_oop_not_null(x);
 256       *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
 257     }
 258   } else {
 259     if (x != NULL) {
 260       // If there is a heap base pointer, we are obliged to emit a store barrier.
 261       oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 262     } else {
 263       *(oop*)index_oop_from_field_offset_long(p, offset) = x;
 264     }
 265   }
 266 UNSAFE_END
 267 
 268 // The normal variants allow a null base pointer with an arbitrary address.
 269 // But if the base pointer is non-null, the offset should make some sense.
 270 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 271 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 272   UnsafeWrapper("Unsafe_GetObject");
 273   GET_OOP_FIELD(obj, offset, v)
 274 
 275 #if INCLUDE_ALL_GCS
 276   if (UseShenandoahGC) {
 277     v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v);
 278   }
 279 #endif
 280 
 281   ensure_satb_referent_alive(p, offset, v);
 282 
 283   return JNIHandles::make_local(env, v);
 284 UNSAFE_END
 285 
 286 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 287   UnsafeWrapper("Unsafe_SetObject");
 288   oop x = JNIHandles::resolve(x_h);
 289   oop p = JNIHandles::resolve(obj);
 290   if (UseCompressedOops) {
 291     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 292   } else {
 293     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 294   }
 295 UNSAFE_END
 296 
 297 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 298   UnsafeWrapper("Unsafe_GetObjectVolatile");
 299   oop p = JNIHandles::resolve(obj);
 300   void* addr = index_oop_from_field_offset_long(p, offset);
 301   volatile oop v;
 302   if (UseCompressedOops) {
 303     volatile narrowOop n = *(volatile narrowOop*) addr;
 304     (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
 305   } else {
 306     (void)const_cast<oop&>(v = *(volatile oop*) addr);
 307   }
 308 
 309 #if INCLUDE_ALL_GCS
 310   if (UseShenandoahGC) {
 311     (void)const_cast<oop&>(v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v));
 312   }
 313 #endif
 314 
 315   ensure_satb_referent_alive(p, offset, v);
 316 
 317   OrderAccess::acquire();
 318   return JNIHandles::make_local(env, v);
 319 UNSAFE_END
 320 
 321 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 322   UnsafeWrapper("Unsafe_SetObjectVolatile");
 323   oop x = JNIHandles::resolve(x_h);
 324   oop p = JNIHandles::resolve(obj);
 325   void* addr = index_oop_from_field_offset_long(p, offset);
 326   OrderAccess::release();
 327   if (UseCompressedOops) {
 328     oop_store((narrowOop*)addr, x);
 329   } else {
 330     oop_store((oop*)addr, x);
 331   }
 332   OrderAccess::fence();
 333 UNSAFE_END


< prev index next >