< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page




  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 "memory/allocation.inline.hpp"
  28 #include "oops/objArrayOop.inline.hpp"
  29 #include "oops/oop.inline.hpp"
  30 #include "prims/jni.h"
  31 #include "prims/jvm.h"

  32 #include "runtime/atomic.inline.hpp"
  33 #include "runtime/globals.hpp"
  34 #include "runtime/interfaceSupport.hpp"
  35 #include "runtime/orderAccess.inline.hpp"
  36 #include "runtime/reflection.hpp"
  37 #include "runtime/vm_version.hpp"
  38 #include "services/threadService.hpp"
  39 #include "trace/tracing.hpp"
  40 #include "utilities/copy.hpp"
  41 #include "utilities/dtrace.hpp"
  42 #include "utilities/macros.hpp"

  43 #if INCLUDE_ALL_GCS
  44 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  45 #endif // INCLUDE_ALL_GCS
  46 
  47 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  48 
  49 /*
  50  *      Implementation of class sun.misc.Unsafe
  51  */
  52 
  53 
  54 #define MAX_OBJECT_SIZE \
  55   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  56     + ((julong)max_jint * sizeof(double)) )
  57 
  58 
  59 #define UNSAFE_ENTRY(result_type, header) \
  60   JVM_ENTRY(result_type, header)
  61 
  62 // Can't use UNSAFE_LEAF because it has the signature of a straight
  63 // call into the runtime (just like JVM_LEAF, funny that) but it's
  64 // called like a Java Native and thus the wrapper built for it passes
  65 // arguments like a JNI call.  It expects those arguments to be popped
  66 // from the stack on Intel like all good JNI args are, and adjusts the
  67 // stack according.  Since the JVM_LEAF call expects no extra
  68 // arguments the stack isn't popped in the C code, is pushed by the
  69 // wrapper and we get sick.
  70 //#define UNSAFE_LEAF(result_type, header) \
  71 //  JVM_LEAF(result_type, header)
  72 
  73 #define UNSAFE_END JVM_END
  74 
  75 #define UnsafeWrapper(arg) /*nothing, for the present*/
  76 
  77 
  78 inline void* addr_from_java(jlong addr) {
  79   // This assert fails in a variety of ways on 32-bit systems.
  80   // It is impossible to predict whether native code that converts
  81   // pointers to longs will sign-extend or zero-extend the addresses.
  82   //assert(addr == (uintptr_t)addr, "must not be odd high bits");
  83   return (void*)(uintptr_t)addr;
  84 }
  85 
  86 inline jlong addr_to_java(void* p) {
  87   assert(p == (void*)(uintptr_t)p, "must not be odd high bits");
  88   return (uintptr_t)p;
  89 }
  90 
  91 
  92 // Note: The VM's obj_field and related accessors use byte-scaled
  93 // ("unscaled") offsets, just as the unsafe methods do.
  94 
  95 // However, the method Unsafe.fieldOffset explicitly declines to
  96 // guarantee this.  The field offset values manipulated by the Java user
  97 // through the Unsafe API are opaque cookies that just happen to be byte
  98 // offsets.  We represent this state of affairs by passing the cookies
  99 // through conversion functions when going between the VM and the Unsafe API.
 100 // The conversion functions just happen to be no-ops at present.
 101 
 102 inline jlong field_offset_to_byte_offset(jlong field_offset) {
 103   return field_offset;
 104 }
 105 
 106 inline jlong field_offset_from_byte_offset(jlong byte_offset) {
 107   return byte_offset;
 108 }
 109 
 110 inline jint invocation_key_from_method_slot(jint slot) {
 111   return slot;
 112 }
 113 
 114 inline jint invocation_key_to_method_slot(jint key) {
 115   return key;
 116 }
 117 
 118 inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) {
 119   jlong byte_offset = field_offset_to_byte_offset(field_offset);





 120 #ifdef ASSERT
 121   if (p != NULL) {
 122     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
 123     if (byte_offset == (jint)byte_offset) {
 124       void* ptr_plus_disp = (address)p + byte_offset;
 125       assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
 126              "raw [ptr+disp] must be consistent with oop::field_base");
 127     }
 128     jlong p_size = HeapWordSize * (jlong)(p->size());
 129     assert(byte_offset < p_size, err_msg("Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, byte_offset, p_size));
 130   }
 131 #endif
 132   if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
 133     return (address)p + (jint) byte_offset;
 134   else
 135     return (address)p +        byte_offset;
 136 }
 137 
 138 // Externally callable versions:
 139 // (Use these in compiler intrinsics which emulate unsafe primitives.)
 140 jlong Unsafe_field_offset_to_byte_offset(jlong field_offset) {
 141   return field_offset;
 142 }
 143 jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) {
 144   return byte_offset;
 145 }
 146 jint Unsafe_invocation_key_from_method_slot(jint slot) {
 147   return invocation_key_from_method_slot(slot);
 148 }
 149 jint Unsafe_invocation_key_to_method_slot(jint key) {
 150   return invocation_key_to_method_slot(key);
 151 }
 152 
 153 
 154 ///// Data in the Java heap.
 155 
 156 #define GET_FIELD(obj, offset, type_name, v) \
 157   oop p = JNIHandles::resolve(obj); \
 158   type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
 159 
 160 #define SET_FIELD(obj, offset, type_name, x) \

 161   oop p = JNIHandles::resolve(obj); \
 162   *(type_name*)index_oop_from_field_offset_long(p, offset) = x
 163 
 164 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
 165   oop p = JNIHandles::resolve(obj); \
 166   if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \
 167     OrderAccess::fence(); \
 168   } \
 169   volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
 170 
 171 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \

 172   oop p = JNIHandles::resolve(obj); \
 173   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
 174 
 175 
 176 // Get/SetObject must be special-cased, since it works with handles.
 177 
 178 // These functions allow a null base pointer with an arbitrary address.
 179 // But if the base pointer is non-null, the offset should make some sense.
 180 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 181 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 182   UnsafeWrapper("Unsafe_GetObject");
 183   oop p = JNIHandles::resolve(obj);
 184   oop v;
 185   if (UseCompressedOops) {
 186     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset);
 187     v = oopDesc::decode_heap_oop(n);
 188   } else {
 189     v = *(oop*)index_oop_from_field_offset_long(p, offset);
 190   }
 191   jobject ret = JNIHandles::make_local(env, v);


 201         oop o = JNIHandles::resolve(obj);
 202         Klass* k = o->klass();
 203         if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 204           assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 205           needs_barrier = true;
 206         }
 207       }
 208     }
 209 
 210     if (needs_barrier) {
 211       oop referent = JNIHandles::resolve(ret);
 212       G1SATBCardTableModRefBS::enqueue(referent);
 213     }
 214   }
 215 #endif // INCLUDE_ALL_GCS
 216   return ret;
 217 UNSAFE_END
 218 
 219 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 220   UnsafeWrapper("Unsafe_SetObject");

 221   oop x = JNIHandles::resolve(x_h);
 222   oop p = JNIHandles::resolve(obj);
 223   if (UseCompressedOops) {
 224     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 225   } else {
 226     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 227   }
 228 UNSAFE_END
 229 
 230 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 231   UnsafeWrapper("Unsafe_GetObjectVolatile");
 232   oop p = JNIHandles::resolve(obj);
 233   void* addr = index_oop_from_field_offset_long(p, offset);
 234   volatile oop v;
 235   if (UseCompressedOops) {
 236     volatile narrowOop n = *(volatile narrowOop*) addr;
 237     (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
 238   } else {
 239     (void)const_cast<oop&>(v = *(volatile oop*) addr);
 240   }
 241   OrderAccess::acquire();
 242   return JNIHandles::make_local(env, v);
 243 UNSAFE_END
 244 
 245 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 246   UnsafeWrapper("Unsafe_SetObjectVolatile");

 247   oop x = JNIHandles::resolve(x_h);
 248   oop p = JNIHandles::resolve(obj);
 249   void* addr = index_oop_from_field_offset_long(p, offset);
 250   OrderAccess::release();
 251   if (UseCompressedOops) {
 252     oop_store((narrowOop*)addr, x);
 253   } else {
 254     oop_store((oop*)addr, x);
 255   }
 256   OrderAccess::fence();
 257 UNSAFE_END
 258 
 259 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr))
 260   UnsafeWrapper("Unsafe_GetUncompressedObject");
 261   oop v = *(oop*) (address) addr;
 262   return JNIHandles::make_local(env, v);
 263 UNSAFE_END
 264 
 265 UNSAFE_ENTRY(jclass, Unsafe_GetJavaMirror(JNIEnv *env, jobject unsafe, jlong metaspace_klass))
 266   UnsafeWrapper("Unsafe_GetJavaMirror");


 680 
 681 jint find_field_offset(jobject field, int must_be_static, TRAPS) {
 682   if (field == NULL) {
 683     THROW_0(vmSymbols::java_lang_NullPointerException());
 684   }
 685 
 686   oop reflected   = JNIHandles::resolve_non_null(field);
 687   oop mirror      = java_lang_reflect_Field::clazz(reflected);
 688   Klass* k      = java_lang_Class::as_Klass(mirror);
 689   int slot        = java_lang_reflect_Field::slot(reflected);
 690   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 691 
 692   if (must_be_static >= 0) {
 693     int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
 694     if (must_be_static != really_is_static) {
 695       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
 696     }
 697   }
 698 
 699   int offset = InstanceKlass::cast(k)->field_offset(slot);
 700   return field_offset_from_byte_offset(offset);

 701 }
 702 
 703 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
 704   UnsafeWrapper("Unsafe_ObjectFieldOffset");
 705   return find_field_offset(field, 0, THREAD);
 706 UNSAFE_END
 707 
 708 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
 709   UnsafeWrapper("Unsafe_StaticFieldOffset");
 710   return find_field_offset(field, 1, THREAD);
 711 UNSAFE_END
 712 
 713 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromField(JNIEnv *env, jobject unsafe, jobject field))
 714   UnsafeWrapper("Unsafe_StaticFieldBase");
 715   // Note:  In this VM implementation, a field address is always a short
 716   // offset from the base of a a klass metaobject.  Thus, the full dynamic
 717   // range of the return type is never used.  However, some implementations
 718   // might put the static field inside an array shared by many classes,
 719   // or even at a fixed address, in which case the address could be quite
 720   // large.  In that last case, this function would return NULL, since


 770   Klass* k      = java_lang_Class::as_Klass(mirror);
 771   if (k == NULL || !k->oop_is_array()) {
 772     THROW(vmSymbols::java_lang_InvalidClassException());
 773   } else if (k->oop_is_objArray()) {
 774     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
 775     scale = heapOopSize;
 776   } else if (k->oop_is_typeArray()) {
 777     TypeArrayKlass* tak = TypeArrayKlass::cast(k);
 778     base  = tak->array_header_in_bytes();
 779     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
 780     scale = (1 << tak->log2_element_size());
 781   } else {
 782     ShouldNotReachHere();
 783   }
 784 }
 785 
 786 UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls))
 787   UnsafeWrapper("Unsafe_ArrayBaseOffset");
 788   int base, scale;
 789   getBaseAndScale(base, scale, acls, CHECK_0);
 790   return field_offset_from_byte_offset(base);
 791 UNSAFE_END
 792 
 793 
 794 UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls))
 795   UnsafeWrapper("Unsafe_ArrayIndexScale");
 796   int base, scale;
 797   getBaseAndScale(base, scale, acls, CHECK_0);
 798   // This VM packs both fields and array elements down to the byte.
 799   // But watch out:  If this changes, so that array references for
 800   // a given primitive type (say, T_BOOLEAN) use different memory units
 801   // than fields, this method MUST return zero for such arrays.
 802   // For example, the VM used to store sub-word sized fields in full
 803   // words in the object layout, so that accessors like getByte(Object,int)
 804   // did not really do what one might expect for arrays.  Therefore,
 805   // this function used to report a zero scale factor, so that the user
 806   // would know not to attempt to access sub-word array elements.
 807   // // Code for unpacked fields:
 808   // if (scale < wordSize)  return 0;
 809 
 810   // The following allows for a pretty general fieldOffset cookie scheme,
 811   // but requires it to be linear in byte offset.
 812   return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0);
 813 UNSAFE_END
 814 
 815 
 816 static inline void throw_new(JNIEnv *env, const char *ename) {
 817   char buf[100];
 818   jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
 819   jclass cls = env->FindClass(buf);
 820   if (env->ExceptionCheck()) {
 821     env->ExceptionClear();
 822     tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf);
 823     return;
 824   }
 825   char* msg = NULL;
 826   env->ThrowNew(cls, msg);
 827 }
 828 
 829 static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
 830   {
 831     // Code lifted from JDK 1.3 ClassLoader.c
 832 


1182 
1183   if (nelem < 0 || nelem > max_nelem || a->length() < nelem) {
1184     ThreadToNativeFromVM ttnfv(thread);
1185     throw_new(env, "ArrayIndexOutOfBoundsException");
1186     return -1;
1187   }
1188 
1189   ret = os::loadavg(la, nelem);
1190   if (ret == -1) return -1;
1191 
1192   // if successful, ret is the number of samples actually retrieved.
1193   assert(ret >= 0 && ret <= max_nelem, "Unexpected loadavg return value");
1194   switch(ret) {
1195     case 3: a->double_at_put(2, (jdouble)la[2]); // fall through
1196     case 2: a->double_at_put(1, (jdouble)la[1]); // fall through
1197     case 1: a->double_at_put(0, (jdouble)la[0]); break;
1198   }
1199   return ret;
1200 UNSAFE_END
1201 
1202 
1203 /// JVM_RegisterUnsafeMethods
1204 
1205 #define ADR "J"
1206 
1207 #define LANG "Ljava/lang/"
1208 
1209 #define OBJ LANG"Object;"
1210 #define CLS LANG"Class;"
1211 #define FLD LANG"reflect/Field;"
1212 #define THR LANG"Throwable;"
1213 
1214 #define DC_Args  LANG"String;[BII" LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
1215 #define DAC_Args CLS"[B["OBJ
1216 
1217 #define CC (char*)  /*cast a literal from (const char*)*/
1218 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1219 
1220 #define DECLARE_GETPUTOOP(Boolean, Z) \
1221     {CC"get"#Boolean,      CC"("OBJ"J)"#Z,      FN_PTR(Unsafe_Get##Boolean)}, \
1222     {CC"put"#Boolean,      CC"("OBJ"J"#Z")V",   FN_PTR(Unsafe_Set##Boolean)}, \




  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 "memory/allocation.inline.hpp"
  28 #include "oops/objArrayOop.inline.hpp"
  29 #include "oops/oop.inline.hpp"
  30 #include "prims/jni.h"
  31 #include "prims/jvm.h"
  32 #include "prims/unsafe.hpp"
  33 #include "runtime/atomic.inline.hpp"
  34 #include "runtime/globals.hpp"
  35 #include "runtime/interfaceSupport.hpp"
  36 #include "runtime/orderAccess.inline.hpp"
  37 #include "runtime/reflection.hpp"
  38 #include "runtime/vm_version.hpp"
  39 #include "services/threadService.hpp"
  40 #include "trace/tracing.hpp"
  41 #include "utilities/copy.hpp"
  42 #include "utilities/dtrace.hpp"
  43 #include "utilities/macros.hpp"
  44 #include "code/dependencies.hpp"
  45 #if INCLUDE_ALL_GCS
  46 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  47 #endif // INCLUDE_ALL_GCS
  48 
  49 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  50 
  51 /*
  52  *      Implementation of class sun.misc.Unsafe
  53  */
  54 
  55 
  56 #define MAX_OBJECT_SIZE \
  57   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  58     + ((julong)max_jint * sizeof(double)) )
  59 
  60 
  61 #define UNSAFE_ENTRY(result_type, header) \
  62   JVM_ENTRY(result_type, header)
  63 
  64 // Can't use UNSAFE_LEAF because it has the signature of a straight
  65 // call into the runtime (just like JVM_LEAF, funny that) but it's
  66 // called like a Java Native and thus the wrapper built for it passes
  67 // arguments like a JNI call.  It expects those arguments to be popped
  68 // from the stack on Intel like all good JNI args are, and adjusts the
  69 // stack according.  Since the JVM_LEAF call expects no extra
  70 // arguments the stack isn't popped in the C code, is pushed by the
  71 // wrapper and we get sick.
  72 //#define UNSAFE_LEAF(result_type, header) \
  73 //  JVM_LEAF(result_type, header)
  74 
  75 #define UNSAFE_END JVM_END
  76 
  77 #define UnsafeWrapper(arg) /*nothing, for the present*/
  78 

  79 inline void* addr_from_java(jlong addr) {
  80   // This assert fails in a variety of ways on 32-bit systems.
  81   // It is impossible to predict whether native code that converts
  82   // pointers to longs will sign-extend or zero-extend the addresses.
  83   //assert(addr == (uintptr_t)addr, "must not be odd high bits");
  84   return (void*)(uintptr_t)addr;
  85 }
  86 
  87 inline jlong addr_to_java(void* p) {
  88   assert(p == (void*)(uintptr_t)p, "must not be odd high bits");
  89   return (uintptr_t)p;
  90 }
  91 



























  92 inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) {
  93   jlong byte_offset = 0;
  94   if (oopDesc::is_null(p)) {
  95     byte_offset = field_offset;
  96   } else {
  97     byte_offset = Unsafe::field_offset_to_byte_offset(field_offset);
  98   }
  99 #ifdef ASSERT
 100   if (p != NULL) {
 101     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
 102     if (byte_offset == (jint)byte_offset) {
 103       void* ptr_plus_disp = (address)p + byte_offset;
 104       assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
 105              "raw [ptr+disp] must be consistent with oop::field_base");
 106     }
 107     jlong p_size = HeapWordSize * (jlong)(p->size());
 108     assert(byte_offset < p_size, err_msg("Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, byte_offset, p_size));
 109   }
 110 #endif
 111   if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
 112     return (address)p + (jint) byte_offset;
 113   else
 114     return (address)p +        byte_offset;
 115 }
 116 
 117 static void check_final_field(jobject obj, jlong field_offset, TRAPS) {
 118   if (TrustFinalNonStaticFields &&
 119       (field_offset & Unsafe::final_mask) != 0) {
 120     Handle recv(THREAD, JNIHandles::resolve(obj));
 121     if (!recv.is_null()) {
 122       instanceKlassHandle ctxk(THREAD, InstanceKlass::cast(recv->klass()));
 123       jlong byte_offset = Unsafe::field_offset_to_byte_offset(field_offset);
 124       ConstantFieldDepChange changes(recv, byte_offset);
 125       Dependencies::invalidate_dependent_nmethods(ctxk, changes, THREAD);
 126     }
 127   }


 128 }
 129 

 130 ///// Data in the Java heap.
 131 
 132 #define GET_FIELD(obj, offset, type_name, v) \
 133   oop p = JNIHandles::resolve(obj); \
 134   type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
 135 
 136 #define SET_FIELD(obj, offset, type_name, x) \
 137   check_final_field(obj, offset, THREAD); \
 138   oop p = JNIHandles::resolve(obj); \
 139   *(type_name*)index_oop_from_field_offset_long(p, offset) = x
 140 
 141 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
 142   oop p = JNIHandles::resolve(obj); \
 143   if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \
 144     OrderAccess::fence(); \
 145   } \
 146   volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
 147 
 148 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
 149   check_final_field(obj, offset, THREAD); \
 150   oop p = JNIHandles::resolve(obj); \
 151   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
 152 
 153 
 154 // Get/SetObject must be special-cased, since it works with handles.
 155 
 156 // These functions allow a null base pointer with an arbitrary address.
 157 // But if the base pointer is non-null, the offset should make some sense.
 158 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 159 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 160   UnsafeWrapper("Unsafe_GetObject");
 161   oop p = JNIHandles::resolve(obj);
 162   oop v;
 163   if (UseCompressedOops) {
 164     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset);
 165     v = oopDesc::decode_heap_oop(n);
 166   } else {
 167     v = *(oop*)index_oop_from_field_offset_long(p, offset);
 168   }
 169   jobject ret = JNIHandles::make_local(env, v);


 179         oop o = JNIHandles::resolve(obj);
 180         Klass* k = o->klass();
 181         if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 182           assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 183           needs_barrier = true;
 184         }
 185       }
 186     }
 187 
 188     if (needs_barrier) {
 189       oop referent = JNIHandles::resolve(ret);
 190       G1SATBCardTableModRefBS::enqueue(referent);
 191     }
 192   }
 193 #endif // INCLUDE_ALL_GCS
 194   return ret;
 195 UNSAFE_END
 196 
 197 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 198   UnsafeWrapper("Unsafe_SetObject");
 199   check_final_field(obj, offset, THREAD);
 200   oop x = JNIHandles::resolve(x_h);
 201   oop p = JNIHandles::resolve(obj);
 202   if (UseCompressedOops) {
 203     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 204   } else {
 205     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 206   }
 207 UNSAFE_END
 208 
 209 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 210   UnsafeWrapper("Unsafe_GetObjectVolatile");
 211   oop p = JNIHandles::resolve(obj);
 212   void* addr = index_oop_from_field_offset_long(p, offset);
 213   volatile oop v;
 214   if (UseCompressedOops) {
 215     volatile narrowOop n = *(volatile narrowOop*) addr;
 216     (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
 217   } else {
 218     (void)const_cast<oop&>(v = *(volatile oop*) addr);
 219   }
 220   OrderAccess::acquire();
 221   return JNIHandles::make_local(env, v);
 222 UNSAFE_END
 223 
 224 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 225   UnsafeWrapper("Unsafe_SetObjectVolatile");
 226   check_final_field(obj, offset, THREAD);
 227   oop x = JNIHandles::resolve(x_h);
 228   oop p = JNIHandles::resolve(obj);
 229   void* addr = index_oop_from_field_offset_long(p, offset);
 230   OrderAccess::release();
 231   if (UseCompressedOops) {
 232     oop_store((narrowOop*)addr, x);
 233   } else {
 234     oop_store((oop*)addr, x);
 235   }
 236   OrderAccess::fence();
 237 UNSAFE_END
 238 
 239 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr))
 240   UnsafeWrapper("Unsafe_GetUncompressedObject");
 241   oop v = *(oop*) (address) addr;
 242   return JNIHandles::make_local(env, v);
 243 UNSAFE_END
 244 
 245 UNSAFE_ENTRY(jclass, Unsafe_GetJavaMirror(JNIEnv *env, jobject unsafe, jlong metaspace_klass))
 246   UnsafeWrapper("Unsafe_GetJavaMirror");


 660 
 661 jint find_field_offset(jobject field, int must_be_static, TRAPS) {
 662   if (field == NULL) {
 663     THROW_0(vmSymbols::java_lang_NullPointerException());
 664   }
 665 
 666   oop reflected   = JNIHandles::resolve_non_null(field);
 667   oop mirror      = java_lang_reflect_Field::clazz(reflected);
 668   Klass* k        = java_lang_Class::as_Klass(mirror);
 669   int slot        = java_lang_reflect_Field::slot(reflected);
 670   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 671 
 672   if (must_be_static >= 0) {
 673     int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
 674     if (must_be_static != really_is_static) {
 675       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
 676     }
 677   }
 678 
 679   int offset = InstanceKlass::cast(k)->field_offset(slot);
 680   bool is_final = (modifiers & JVM_ACC_FINAL) != 0;
 681   return Unsafe::field_offset_from_byte_offset(offset, is_final);
 682 }
 683 
 684 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
 685   UnsafeWrapper("Unsafe_ObjectFieldOffset");
 686   return find_field_offset(field, 0, THREAD);
 687 UNSAFE_END
 688 
 689 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
 690   UnsafeWrapper("Unsafe_StaticFieldOffset");
 691   return find_field_offset(field, 1, THREAD);
 692 UNSAFE_END
 693 
 694 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromField(JNIEnv *env, jobject unsafe, jobject field))
 695   UnsafeWrapper("Unsafe_StaticFieldBase");
 696   // Note:  In this VM implementation, a field address is always a short
 697   // offset from the base of a a klass metaobject.  Thus, the full dynamic
 698   // range of the return type is never used.  However, some implementations
 699   // might put the static field inside an array shared by many classes,
 700   // or even at a fixed address, in which case the address could be quite
 701   // large.  In that last case, this function would return NULL, since


 751   Klass* k      = java_lang_Class::as_Klass(mirror);
 752   if (k == NULL || !k->oop_is_array()) {
 753     THROW(vmSymbols::java_lang_InvalidClassException());
 754   } else if (k->oop_is_objArray()) {
 755     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
 756     scale = heapOopSize;
 757   } else if (k->oop_is_typeArray()) {
 758     TypeArrayKlass* tak = TypeArrayKlass::cast(k);
 759     base  = tak->array_header_in_bytes();
 760     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
 761     scale = (1 << tak->log2_element_size());
 762   } else {
 763     ShouldNotReachHere();
 764   }
 765 }
 766 
 767 UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls))
 768   UnsafeWrapper("Unsafe_ArrayBaseOffset");
 769   int base, scale;
 770   getBaseAndScale(base, scale, acls, CHECK_0);
 771   return Unsafe::field_offset_from_byte_offset(base);
 772 UNSAFE_END
 773 
 774 
 775 UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls))
 776   UnsafeWrapper("Unsafe_ArrayIndexScale");
 777   int base, scale;
 778   getBaseAndScale(base, scale, acls, CHECK_0);
 779   // This VM packs both fields and array elements down to the byte.
 780   // But watch out:  If this changes, so that array references for
 781   // a given primitive type (say, T_BOOLEAN) use different memory units
 782   // than fields, this method MUST return zero for such arrays.
 783   // For example, the VM used to store sub-word sized fields in full
 784   // words in the object layout, so that accessors like getByte(Object,int)
 785   // did not really do what one might expect for arrays.  Therefore,
 786   // this function used to report a zero scale factor, so that the user
 787   // would know not to attempt to access sub-word array elements.
 788   // // Code for unpacked fields:
 789   // if (scale < wordSize)  return 0;
 790 
 791   // The following allows for a pretty general fieldOffset cookie scheme,
 792   // but requires it to be linear in byte offset.
 793   return Unsafe::field_offset_from_byte_offset(scale) - Unsafe::field_offset_from_byte_offset(0);
 794 UNSAFE_END
 795 
 796 
 797 static inline void throw_new(JNIEnv *env, const char *ename) {
 798   char buf[100];
 799   jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
 800   jclass cls = env->FindClass(buf);
 801   if (env->ExceptionCheck()) {
 802     env->ExceptionClear();
 803     tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf);
 804     return;
 805   }
 806   char* msg = NULL;
 807   env->ThrowNew(cls, msg);
 808 }
 809 
 810 static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
 811   {
 812     // Code lifted from JDK 1.3 ClassLoader.c
 813 


1163 
1164   if (nelem < 0 || nelem > max_nelem || a->length() < nelem) {
1165     ThreadToNativeFromVM ttnfv(thread);
1166     throw_new(env, "ArrayIndexOutOfBoundsException");
1167     return -1;
1168   }
1169 
1170   ret = os::loadavg(la, nelem);
1171   if (ret == -1) return -1;
1172 
1173   // if successful, ret is the number of samples actually retrieved.
1174   assert(ret >= 0 && ret <= max_nelem, "Unexpected loadavg return value");
1175   switch(ret) {
1176     case 3: a->double_at_put(2, (jdouble)la[2]); // fall through
1177     case 2: a->double_at_put(1, (jdouble)la[1]); // fall through
1178     case 1: a->double_at_put(0, (jdouble)la[0]); break;
1179   }
1180   return ret;
1181 UNSAFE_END
1182 

1183 /// JVM_RegisterUnsafeMethods
1184 
1185 #define ADR "J"
1186 
1187 #define LANG "Ljava/lang/"
1188 
1189 #define OBJ LANG"Object;"
1190 #define CLS LANG"Class;"
1191 #define FLD LANG"reflect/Field;"
1192 #define THR LANG"Throwable;"
1193 
1194 #define DC_Args  LANG"String;[BII" LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
1195 #define DAC_Args CLS"[B["OBJ
1196 
1197 #define CC (char*)  /*cast a literal from (const char*)*/
1198 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1199 
1200 #define DECLARE_GETPUTOOP(Boolean, Z) \
1201     {CC"get"#Boolean,      CC"("OBJ"J)"#Z,      FN_PTR(Unsafe_Get##Boolean)}, \
1202     {CC"put"#Boolean,      CC"("OBJ"J"#Z")V",   FN_PTR(Unsafe_Set##Boolean)}, \


< prev index next >