< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page




  41 #include "runtime/vm_version.hpp"
  42 #include "services/threadService.hpp"
  43 #include "trace/tracing.hpp"
  44 #include "utilities/align.hpp"
  45 #include "utilities/copy.hpp"
  46 #include "utilities/dtrace.hpp"
  47 #include "utilities/macros.hpp"
  48 #if INCLUDE_ALL_GCS
  49 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  50 #endif // INCLUDE_ALL_GCS
  51 
  52 /**
  53  * Implementation of the jdk.internal.misc.Unsafe class
  54  */
  55 
  56 
  57 #define MAX_OBJECT_SIZE \
  58   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  59     + ((julong)max_jint * sizeof(double)) )
  60 
  61 
  62 #define UNSAFE_ENTRY(result_type, header) \
  63   JVM_ENTRY(static result_type, header)
  64 




  65 #define UNSAFE_LEAF(result_type, header) \
  66   JVM_LEAF(static result_type, header)
  67 
  68 #define UNSAFE_END JVM_END







  69 

  70 
  71 static inline void* addr_from_java(jlong addr) {
  72   // This assert fails in a variety of ways on 32-bit systems.
  73   // It is impossible to predict whether native code that converts
  74   // pointers to longs will sign-extend or zero-extend the addresses.
  75   //assert(addr == (uintptr_t)addr, "must not be odd high bits");
  76   return (void*)(uintptr_t)addr;
  77 }
  78 
  79 static inline jlong addr_to_java(void* p) {
  80   assert(p == (void*)(uintptr_t)p, "must not be odd high bits");
  81   return (uintptr_t)p;
  82 }
  83 
  84 
  85 // Note: The VM's obj_field and related accessors use byte-scaled
  86 // ("unscaled") offsets, just as the unsafe methods do.
  87 
  88 // However, the method Unsafe.fieldOffset explicitly declines to
  89 // guarantee this.  The field offset values manipulated by the Java user


 508 
 509   return addr_to_java(x);
 510 } UNSAFE_END
 511 
 512 UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory0(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) {
 513   void* p = addr_from_java(addr);
 514   size_t sz = (size_t)size;
 515   sz = align_up(sz, HeapWordSize);
 516 
 517   void* x = os::realloc(p, sz, mtInternal);
 518 
 519   return addr_to_java(x);
 520 } UNSAFE_END
 521 
 522 UNSAFE_ENTRY(void, Unsafe_FreeMemory0(JNIEnv *env, jobject unsafe, jlong addr)) {
 523   void* p = addr_from_java(addr);
 524 
 525   os::free(p);
 526 } UNSAFE_END
 527 
 528 UNSAFE_ENTRY(void, Unsafe_SetMemory0(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) {
 529   size_t sz = (size_t)size;
 530 
 531   oop base = JNIHandles::resolve(obj);
 532   void* p = index_oop_from_field_offset_long(base, offset);
 533 
 534   Copy::fill_to_memory_atomic(p, sz, value);
 535 } UNSAFE_END
 536 
 537 UNSAFE_ENTRY(void, Unsafe_CopyMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) {
 538   size_t sz = (size_t)size;
 539 
 540   oop srcp = JNIHandles::resolve(srcObj);
 541   oop dstp = JNIHandles::resolve(dstObj);
 542 
 543   void* src = index_oop_from_field_offset_long(srcp, srcOffset);
 544   void* dst = index_oop_from_field_offset_long(dstp, dstOffset);
 545 
 546   Copy::conjoint_memory_atomic(src, dst, sz);
 547 } UNSAFE_END
 548 
 549 // This function is a leaf since if the source and destination are both in native memory
 550 // the copy may potentially be very large, and we don't want to disable GC if we can avoid it.
 551 // If either source or destination (or both) are on the heap, the function will enter VM using
 552 // JVM_ENTRY_FROM_LEAF
 553 UNSAFE_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size, jlong elemSize)) {
 554   size_t sz = (size_t)size;
 555   size_t esz = (size_t)elemSize;
 556 
 557   if (srcObj == NULL && dstObj == NULL) {
 558     // Both src & dst are in native memory
 559     address src = (address)srcOffset;
 560     address dst = (address)dstOffset;
 561 
 562     Copy::conjoint_swap(src, dst, sz, esz);
 563   } else {
 564     // At least one of src/dst are on heap, transition to VM to access raw pointers
 565 
 566     JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
 567       oop srcp = JNIHandles::resolve(srcObj);
 568       oop dstp = JNIHandles::resolve(dstObj);
 569 
 570       address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
 571       address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
 572 
 573       Copy::conjoint_swap(src, dst, sz, esz);
 574     } JVM_END
 575   }
 576 } UNSAFE_END
 577 
 578 ////// Random queries
 579 
 580 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
 581   return sizeof(void*);
 582 } UNSAFE_END
 583 
 584 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
 585   return os::vm_page_size();
 586 } UNSAFE_END
 587 
 588 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
 589   assert(clazz != NULL, "clazz must not be NULL");
 590   assert(name != NULL, "name must not be NULL");
 591 
 592   ResourceMark rm(THREAD);
 593   char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 594 
 595   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 596 




  41 #include "runtime/vm_version.hpp"
  42 #include "services/threadService.hpp"
  43 #include "trace/tracing.hpp"
  44 #include "utilities/align.hpp"
  45 #include "utilities/copy.hpp"
  46 #include "utilities/dtrace.hpp"
  47 #include "utilities/macros.hpp"
  48 #if INCLUDE_ALL_GCS
  49 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  50 #endif // INCLUDE_ALL_GCS
  51 
  52 /**
  53  * Implementation of the jdk.internal.misc.Unsafe class
  54  */
  55 
  56 
  57 #define MAX_OBJECT_SIZE \
  58   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  59     + ((julong)max_jint * sizeof(double)) )
  60 

  61 #define UNSAFE_ENTRY(result_type, header) \
  62   JVM_ENTRY(static result_type, header)
  63   
  64 #define UNSAFE_ACCESS_ENTRY(result_type, header) \
  65   JVM_ENTRY(static result_type, header) \
  66   thread->set_doing_unsafe_access(true);
  67   
  68 #define UNSAFE_LEAF(result_type, header) \
  69   JVM_LEAF(static result_type, header)
  70 
  71 #define UNSAFE_ACCESS_LEAF(result_type, header) \
  72   JVM_LEAF(static result_type, header) \
  73   JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
  74   thread->set_doing_unsafe_access(true);  
  75 
  76 #define UNSAFE_ACCESS_END \
  77   thread->set_doing_unsafe_access(false); \
  78   JVM_END
  79 
  80 #define UNSAFE_END JVM_END
  81 
  82 static inline void* addr_from_java(jlong addr) {
  83   // This assert fails in a variety of ways on 32-bit systems.
  84   // It is impossible to predict whether native code that converts
  85   // pointers to longs will sign-extend or zero-extend the addresses.
  86   //assert(addr == (uintptr_t)addr, "must not be odd high bits");
  87   return (void*)(uintptr_t)addr;
  88 }
  89 
  90 static inline jlong addr_to_java(void* p) {
  91   assert(p == (void*)(uintptr_t)p, "must not be odd high bits");
  92   return (uintptr_t)p;
  93 }
  94 
  95 
  96 // Note: The VM's obj_field and related accessors use byte-scaled
  97 // ("unscaled") offsets, just as the unsafe methods do.
  98 
  99 // However, the method Unsafe.fieldOffset explicitly declines to
 100 // guarantee this.  The field offset values manipulated by the Java user


 519 
 520   return addr_to_java(x);
 521 } UNSAFE_END
 522 
 523 UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory0(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) {
 524   void* p = addr_from_java(addr);
 525   size_t sz = (size_t)size;
 526   sz = align_up(sz, HeapWordSize);
 527 
 528   void* x = os::realloc(p, sz, mtInternal);
 529 
 530   return addr_to_java(x);
 531 } UNSAFE_END
 532 
 533 UNSAFE_ENTRY(void, Unsafe_FreeMemory0(JNIEnv *env, jobject unsafe, jlong addr)) {
 534   void* p = addr_from_java(addr);
 535 
 536   os::free(p);
 537 } UNSAFE_END
 538 
 539 UNSAFE_ACCESS_ENTRY(void, Unsafe_SetMemory0(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) {
 540   size_t sz = (size_t)size;
 541 
 542   oop base = JNIHandles::resolve(obj);
 543   void* p = index_oop_from_field_offset_long(base, offset);
 544 
 545   Copy::fill_to_memory_atomic(p, sz, value);
 546 } UNSAFE_ACCESS_END
 547 
 548 UNSAFE_ACCESS_ENTRY(void, Unsafe_CopyMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) {
 549   size_t sz = (size_t)size;
 550 
 551   oop srcp = JNIHandles::resolve(srcObj);
 552   oop dstp = JNIHandles::resolve(dstObj);
 553 
 554   void* src = index_oop_from_field_offset_long(srcp, srcOffset);
 555   void* dst = index_oop_from_field_offset_long(dstp, dstOffset);
 556 
 557   Copy::conjoint_memory_atomic(src, dst, sz);
 558 } UNSAFE_ACCESS_END
 559 
 560 // This function is a leaf since if the source and destination are both in native memory
 561 // the copy may potentially be very large, and we don't want to disable GC if we can avoid it.
 562 // If either source or destination (or both) are on the heap, the function will enter VM using
 563 // JVM_ENTRY_FROM_LEAF
 564 UNSAFE_ACCESS_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size, jlong elemSize)) {
 565   size_t sz = (size_t)size;
 566   size_t esz = (size_t)elemSize;
 567 
 568   if (srcObj == NULL && dstObj == NULL) {
 569     // Both src & dst are in native memory
 570     address src = (address)srcOffset;
 571     address dst = (address)dstOffset;
 572 
 573     Copy::conjoint_swap(src, dst, sz, esz);
 574   } else {
 575     // At least one of src/dst are on heap, transition to VM to access raw pointers
 576 
 577     JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
 578       oop srcp = JNIHandles::resolve(srcObj);
 579       oop dstp = JNIHandles::resolve(dstObj);
 580 
 581       address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
 582       address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
 583 
 584       Copy::conjoint_swap(src, dst, sz, esz);
 585     } JVM_END
 586   }
 587 } UNSAFE_ACCESS_END
 588 
 589 ////// Random queries
 590 
 591 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
 592   return sizeof(void*);
 593 } UNSAFE_END
 594 
 595 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
 596   return os::vm_page_size();
 597 } UNSAFE_END
 598 
 599 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
 600   assert(clazz != NULL, "clazz must not be NULL");
 601   assert(name != NULL, "name must not be NULL");
 602 
 603   ResourceMark rm(THREAD);
 604   char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 605 
 606   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 607 


< prev index next >