hotspot/src/share/vm/prims/unsafe.cpp
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
child 1374 4c24294029a9
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Fri Apr 11 09:56:35 2008 -0400
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Sun Apr 13 17:43:42 2008 -0400
@@ -100,7 +100,7 @@
     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;
-      assert((void*)p->obj_field_addr((jint)byte_offset) == ptr_plus_disp,
+      assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
              "raw [ptr+disp] must be consistent with oop::field_base");
     }
   }
@@ -146,13 +146,36 @@
   *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \
   OrderAccess::fence();
 
+// Macros for oops that check UseCompressedOops
+
+#define GET_OOP_FIELD(obj, offset, v) \
+  oop p = JNIHandles::resolve(obj);   \
+  oop v;                              \
+  if (UseCompressedOops) {            \
+    narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
+    v = oopDesc::decode_heap_oop(n);                                \
+  } else {                            \
+    v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
+  }
+
+#define GET_OOP_FIELD_VOLATILE(obj, offset, v) \
+  oop p = JNIHandles::resolve(obj);   \
+  volatile oop v;                     \
+  if (UseCompressedOops) {            \
+    volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
+    v = oopDesc::decode_heap_oop(n);                               \
+  } else {                            \
+    v = *(volatile oop*)index_oop_from_field_offset_long(p, offset);       \
+  }
+
+
 // Get/SetObject must be special-cased, since it works with handles.
 
 // The xxx140 variants for backward compatibility do not allow a full-width offset.
 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
   UnsafeWrapper("Unsafe_GetObject");
   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
-  GET_FIELD(obj, offset, oop, v);
+  GET_OOP_FIELD(obj, offset, v)
   return JNIHandles::make_local(env, v);
 UNSAFE_END
 
@@ -162,11 +185,21 @@
   oop x = JNIHandles::resolve(x_h);
   //SET_FIELD(obj, offset, oop, x);
   oop p = JNIHandles::resolve(obj);
-  if (x != NULL) {
-    // If there is a heap base pointer, we are obliged to emit a store barrier.
-    oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  if (UseCompressedOops) {
+    if (x != NULL) {
+      // If there is a heap base pointer, we are obliged to emit a store barrier.
+      oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
+    } else {
+      narrowOop n = oopDesc::encode_heap_oop_not_null(x);
+      *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
+    }
   } else {
-    *(oop*)index_oop_from_field_offset_long(p, offset) = x;
+    if (x != NULL) {
+      // If there is a heap base pointer, we are obliged to emit a store barrier.
+      oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+    } else {
+      *(oop*)index_oop_from_field_offset_long(p, offset) = x;
+    }
   }
 UNSAFE_END
 
@@ -175,7 +208,7 @@
 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   UnsafeWrapper("Unsafe_GetObject");
-  GET_FIELD(obj, offset, oop, v);
+  GET_OOP_FIELD(obj, offset, v)
   return JNIHandles::make_local(env, v);
 UNSAFE_END
 
@@ -183,12 +216,16 @@
   UnsafeWrapper("Unsafe_SetObject");
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
-  oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  if (UseCompressedOops) {
+    oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
+  } else {
+    oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  }
 UNSAFE_END
 
 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   UnsafeWrapper("Unsafe_GetObjectVolatile");
-  GET_FIELD_VOLATILE(obj, offset, oop, v);
+  GET_OOP_FIELD_VOLATILE(obj, offset, v)
   return JNIHandles::make_local(env, v);
 UNSAFE_END
 
@@ -196,7 +233,11 @@
   UnsafeWrapper("Unsafe_SetObjectVolatile");
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
-  oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  if (UseCompressedOops) {
+    oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
+  } else {
+    oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  }
   OrderAccess::fence();
 UNSAFE_END
 
@@ -311,7 +352,11 @@
   UnsafeWrapper("Unsafe_SetOrderedObject");
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
-  oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  if (UseCompressedOops) {
+    oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
+  } else {
+    oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
+  }
   OrderAccess::fence();
 UNSAFE_END
 
@@ -647,7 +692,7 @@
     THROW(vmSymbols::java_lang_InvalidClassException());
   } else if (k->klass_part()->oop_is_objArray()) {
     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
-    scale = oopSize;
+    scale = heapOopSize;
   } else if (k->klass_part()->oop_is_typeArray()) {
     typeArrayKlass* tak = typeArrayKlass::cast(k);
     base  = tak->array_header_in_bytes();
@@ -845,11 +890,11 @@
   oop x = JNIHandles::resolve(x_h);
   oop e = JNIHandles::resolve(e_h);
   oop p = JNIHandles::resolve(obj);
-  intptr_t* addr = (intptr_t *)index_oop_from_field_offset_long(p, offset);
-  intptr_t res = Atomic::cmpxchg_ptr((intptr_t)x, addr, (intptr_t)e);
-  jboolean success  = (res == (intptr_t)e);
+  HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
+  oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e);
+  jboolean success  = (res == e);
   if (success)
-    update_barrier_set((oop*)addr, x);
+    update_barrier_set((void*)addr, x);
   return success;
 UNSAFE_END