< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page

        

*** 27,36 **** --- 27,37 ---- #include "memory/allocation.inline.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "prims/jni.h" #include "prims/jvm.h" + #include "prims/unsafe.hpp" #include "runtime/atomic.inline.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/reflection.hpp"
*** 38,47 **** --- 39,49 ---- #include "services/threadService.hpp" #include "trace/tracing.hpp" #include "utilities/copy.hpp" #include "utilities/dtrace.hpp" #include "utilities/macros.hpp" + #include "code/dependencies.hpp" #if INCLUDE_ALL_GCS #include "gc/g1/g1SATBCardTableModRefBS.hpp" #endif // INCLUDE_ALL_GCS PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
*** 72,82 **** #define UNSAFE_END JVM_END #define UnsafeWrapper(arg) /*nothing, for the present*/ - inline void* addr_from_java(jlong addr) { // This assert fails in a variety of ways on 32-bit systems. // It is impossible to predict whether native code that converts // pointers to longs will sign-extend or zero-extend the addresses. //assert(addr == (uintptr_t)addr, "must not be odd high bits"); --- 74,83 ----
*** 86,124 **** inline jlong addr_to_java(void* p) { assert(p == (void*)(uintptr_t)p, "must not be odd high bits"); return (uintptr_t)p; } - - // Note: The VM's obj_field and related accessors use byte-scaled - // ("unscaled") offsets, just as the unsafe methods do. - - // However, the method Unsafe.fieldOffset explicitly declines to - // guarantee this. The field offset values manipulated by the Java user - // through the Unsafe API are opaque cookies that just happen to be byte - // offsets. We represent this state of affairs by passing the cookies - // through conversion functions when going between the VM and the Unsafe API. - // The conversion functions just happen to be no-ops at present. - - inline jlong field_offset_to_byte_offset(jlong field_offset) { - return field_offset; - } - - inline jlong field_offset_from_byte_offset(jlong byte_offset) { - return byte_offset; - } - - inline jint invocation_key_from_method_slot(jint slot) { - return slot; - } - - inline jint invocation_key_to_method_slot(jint key) { - return key; - } - inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) { ! jlong byte_offset = field_offset_to_byte_offset(field_offset); #ifdef ASSERT if (p != NULL) { assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset"); if (byte_offset == (jint)byte_offset) { void* ptr_plus_disp = (address)p + byte_offset; --- 87,103 ---- inline jlong addr_to_java(void* p) { assert(p == (void*)(uintptr_t)p, "must not be odd high bits"); return (uintptr_t)p; } inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) { ! jlong byte_offset = 0; ! if (oopDesc::is_null(p)) { ! byte_offset = field_offset; ! } else { ! byte_offset = Unsafe::field_offset_to_byte_offset(field_offset); ! } #ifdef ASSERT if (p != NULL) { assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset"); if (byte_offset == (jint)byte_offset) { void* ptr_plus_disp = (address)p + byte_offset;
*** 133,165 **** return (address)p + (jint) byte_offset; else return (address)p + byte_offset; } ! // Externally callable versions: ! // (Use these in compiler intrinsics which emulate unsafe primitives.) ! jlong Unsafe_field_offset_to_byte_offset(jlong field_offset) { ! return field_offset; ! } ! jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) { ! return byte_offset; ! } ! jint Unsafe_invocation_key_from_method_slot(jint slot) { ! return invocation_key_from_method_slot(slot); ! } ! jint Unsafe_invocation_key_to_method_slot(jint key) { ! return invocation_key_to_method_slot(key); } - ///// Data in the Java heap. #define GET_FIELD(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) #define SET_FIELD(obj, offset, type_name, x) \ oop p = JNIHandles::resolve(obj); \ *(type_name*)index_oop_from_field_offset_long(p, offset) = x #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ --- 112,142 ---- return (address)p + (jint) byte_offset; else return (address)p + byte_offset; } ! static void check_final_field(jobject obj, jlong field_offset, TRAPS) { ! if (TrustFinalNonStaticFields && ! (field_offset & Unsafe::final_mask) != 0) { ! Handle recv(THREAD, JNIHandles::resolve(obj)); ! if (!recv.is_null()) { ! instanceKlassHandle ctxk(THREAD, InstanceKlass::cast(recv->klass())); ! jlong byte_offset = Unsafe::field_offset_to_byte_offset(field_offset); ! ConstantFieldDepChange changes(recv, byte_offset); ! Dependencies::invalidate_dependent_nmethods(ctxk, changes, THREAD); ! } ! } } ///// Data in the Java heap. #define GET_FIELD(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) #define SET_FIELD(obj, offset, type_name, x) \ + check_final_field(obj, offset, THREAD); \ oop p = JNIHandles::resolve(obj); \ *(type_name*)index_oop_from_field_offset_long(p, offset) = x #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \
*** 167,176 **** --- 144,154 ---- OrderAccess::fence(); \ } \ volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset)); #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ + check_final_field(obj, offset, THREAD); \ oop p = JNIHandles::resolve(obj); \ OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x); // Get/SetObject must be special-cased, since it works with handles.
*** 216,225 **** --- 194,204 ---- return ret; UNSAFE_END UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) UnsafeWrapper("Unsafe_SetObject"); + check_final_field(obj, offset, THREAD); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); if (UseCompressedOops) { oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); } else {
*** 242,251 **** --- 221,231 ---- return JNIHandles::make_local(env, v); UNSAFE_END UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) UnsafeWrapper("Unsafe_SetObjectVolatile"); + check_final_field(obj, offset, THREAD); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); void* addr = index_oop_from_field_offset_long(p, offset); OrderAccess::release(); if (UseCompressedOops) {
*** 695,705 **** THROW_0(vmSymbols::java_lang_IllegalArgumentException()); } } int offset = InstanceKlass::cast(k)->field_offset(slot); ! return field_offset_from_byte_offset(offset); } UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field)) UnsafeWrapper("Unsafe_ObjectFieldOffset"); return find_field_offset(field, 0, THREAD); --- 675,686 ---- THROW_0(vmSymbols::java_lang_IllegalArgumentException()); } } int offset = InstanceKlass::cast(k)->field_offset(slot); ! bool is_final = (modifiers & JVM_ACC_FINAL) != 0; ! return Unsafe::field_offset_from_byte_offset(offset, is_final); } UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field)) UnsafeWrapper("Unsafe_ObjectFieldOffset"); return find_field_offset(field, 0, THREAD);
*** 785,795 **** UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls)) UnsafeWrapper("Unsafe_ArrayBaseOffset"); int base, scale; getBaseAndScale(base, scale, acls, CHECK_0); ! return field_offset_from_byte_offset(base); UNSAFE_END UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls)) UnsafeWrapper("Unsafe_ArrayIndexScale"); --- 766,776 ---- UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls)) UnsafeWrapper("Unsafe_ArrayBaseOffset"); int base, scale; getBaseAndScale(base, scale, acls, CHECK_0); ! return Unsafe::field_offset_from_byte_offset(base); UNSAFE_END UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls)) UnsafeWrapper("Unsafe_ArrayIndexScale");
*** 807,817 **** // // Code for unpacked fields: // if (scale < wordSize) return 0; // The following allows for a pretty general fieldOffset cookie scheme, // but requires it to be linear in byte offset. ! return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0); UNSAFE_END static inline void throw_new(JNIEnv *env, const char *ename) { char buf[100]; --- 788,798 ---- // // Code for unpacked fields: // if (scale < wordSize) return 0; // The following allows for a pretty general fieldOffset cookie scheme, // but requires it to be linear in byte offset. ! return Unsafe::field_offset_from_byte_offset(scale) - Unsafe::field_offset_from_byte_offset(0); UNSAFE_END static inline void throw_new(JNIEnv *env, const char *ename) { char buf[100];
*** 1197,1207 **** case 1: a->double_at_put(0, (jdouble)la[0]); break; } return ret; UNSAFE_END - /// JVM_RegisterUnsafeMethods #define ADR "J" #define LANG "Ljava/lang/" --- 1178,1187 ----
< prev index next >