aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/prims
diff options
context:
space:
mode:
authorcoleenp <none@none>2008-04-13 17:43:42 -0400
committercoleenp <none@none>2008-04-13 17:43:42 -0400
commit10ccf1a80915ef4ed623d4d62e582bcc190a1990 (patch)
tree3ef8c64ec2efcfbeec6e46f6a3775a60c122e5df /src/share/vm/prims
parent32e3fd6141baa47eee388d7f95b5e715a2ea2d9a (diff)
downloadjdk8u_hotspot-10ccf1a80915ef4ed623d4d62e582bcc190a1990.tar.gz
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
Diffstat (limited to 'src/share/vm/prims')
-rw-r--r--src/share/vm/prims/jni.cpp5
-rw-r--r--src/share/vm/prims/jvmtiTagMap.cpp20
-rw-r--r--src/share/vm/prims/unsafe.cpp77
3 files changed, 75 insertions, 27 deletions
diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp
index 6f31afc98..91fb8cb3c 100644
--- a/src/share/vm/prims/jni.cpp
+++ b/src/share/vm/prims/jni.cpp
@@ -135,7 +135,10 @@ intptr_t jfieldIDWorkaround::encode_klass_hash(klassOop k, intptr_t offset) {
if (offset <= small_offset_mask) {
klassOop field_klass = k;
klassOop super_klass = Klass::cast(field_klass)->super();
- while (instanceKlass::cast(super_klass)->contains_field_offset(offset)) {
+ // With compressed oops the most super class with nonstatic fields would
+ // be the owner of fields embedded in the header.
+ while (instanceKlass::cast(super_klass)->has_nonstatic_fields() &&
+ instanceKlass::cast(super_klass)->contains_field_offset(offset)) {
field_klass = super_klass; // super contains the field also
super_klass = Klass::cast(field_klass)->super();
}
diff --git a/src/share/vm/prims/jvmtiTagMap.cpp b/src/share/vm/prims/jvmtiTagMap.cpp
index 23e46ede8..30d9fee46 100644
--- a/src/share/vm/prims/jvmtiTagMap.cpp
+++ b/src/share/vm/prims/jvmtiTagMap.cpp
@@ -2662,6 +2662,7 @@ class SimpleRootsClosure : public OopClosure {
_continue = CallbackInvoker::report_simple_root(kind, o);
}
+ virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
};
// A supporting closure used to process JNI locals
@@ -2704,6 +2705,7 @@ class JNILocalRootsClosure : public OopClosure {
// invoke the callback
_continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
}
+ virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
};
@@ -2878,9 +2880,11 @@ inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
}
// verify that a static oop field is in range
-static inline bool verify_static_oop(instanceKlass* ik, oop* obj_p) {
- oop* start = ik->start_of_static_fields();
- oop* end = start + ik->static_oop_field_size();
+static inline bool verify_static_oop(instanceKlass* ik,
+ klassOop k, int offset) {
+ address obj_p = (address)k + offset;
+ address start = (address)ik->start_of_static_fields();
+ address end = start + (ik->static_oop_field_size() * heapOopSize);
assert(end >= start, "sanity check");
if (obj_p >= start && obj_p < end) {
@@ -2981,10 +2985,8 @@ inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) {
ClassFieldDescriptor* field = field_map->field_at(i);
char type = field->field_type();
if (!is_primitive_field_type(type)) {
- address addr = (address)k + field->field_offset();
- oop* f = (oop*)addr;
- assert(verify_static_oop(ik, f), "sanity check");
- oop fld_o = *f;
+ oop fld_o = k->obj_field(field->field_offset());
+ assert(verify_static_oop(ik, k, field->field_offset()), "sanity check");
if (fld_o != NULL) {
int slot = field->field_index();
if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
@@ -3026,9 +3028,7 @@ inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
ClassFieldDescriptor* field = field_map->field_at(i);
char type = field->field_type();
if (!is_primitive_field_type(type)) {
- address addr = (address)o + field->field_offset();
- oop* f = (oop*)addr;
- oop fld_o = *f;
+ oop fld_o = o->obj_field(field->field_offset());
if (fld_o != NULL) {
// reflection code may have a reference to a klassOop.
// - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp
index adea25098..899a99296 100644
--- a/src/share/vm/prims/unsafe.cpp
+++ b/src/share/vm/prims/unsafe.cpp
@@ -100,7 +100,7 @@ inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) {
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 @@ jint Unsafe_invocation_key_to_method_slot(jint key) {
*(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 @@ UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj,
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 @@ UNSAFE_END
// 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 @@ UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jl
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 @@ UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject
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 @@ UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject
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 @@ static void getBaseAndScale(int& base, int& scale, jclass acls, TRAPS) {
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 @@ UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe,
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