comparison src/share/vm/prims/unsafe.cpp @ 113:ba764ed4b6f2

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
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents a61af66fc99e
children d1605aabd0a1 37f87013dfd8
comparison
equal deleted inserted replaced
110:a49a647afe9a 113:ba764ed4b6f2
98 #ifdef ASSERT 98 #ifdef ASSERT
99 if (p != NULL) { 99 if (p != NULL) {
100 assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset"); 100 assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
101 if (byte_offset == (jint)byte_offset) { 101 if (byte_offset == (jint)byte_offset) {
102 void* ptr_plus_disp = (address)p + byte_offset; 102 void* ptr_plus_disp = (address)p + byte_offset;
103 assert((void*)p->obj_field_addr((jint)byte_offset) == ptr_plus_disp, 103 assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
104 "raw [ptr+disp] must be consistent with oop::field_base"); 104 "raw [ptr+disp] must be consistent with oop::field_base");
105 } 105 }
106 } 106 }
107 #endif 107 #endif
108 if (sizeof(char*) == sizeof(jint)) // (this constant folds!) 108 if (sizeof(char*) == sizeof(jint)) // (this constant folds!)
144 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ 144 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
145 oop p = JNIHandles::resolve(obj); \ 145 oop p = JNIHandles::resolve(obj); \
146 *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \ 146 *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \
147 OrderAccess::fence(); 147 OrderAccess::fence();
148 148
149 // Macros for oops that check UseCompressedOops
150
151 #define GET_OOP_FIELD(obj, offset, v) \
152 oop p = JNIHandles::resolve(obj); \
153 oop v; \
154 if (UseCompressedOops) { \
155 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
156 v = oopDesc::decode_heap_oop(n); \
157 } else { \
158 v = *(oop*)index_oop_from_field_offset_long(p, offset); \
159 }
160
161 #define GET_OOP_FIELD_VOLATILE(obj, offset, v) \
162 oop p = JNIHandles::resolve(obj); \
163 volatile oop v; \
164 if (UseCompressedOops) { \
165 volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
166 v = oopDesc::decode_heap_oop(n); \
167 } else { \
168 v = *(volatile oop*)index_oop_from_field_offset_long(p, offset); \
169 }
170
171
149 // Get/SetObject must be special-cased, since it works with handles. 172 // Get/SetObject must be special-cased, since it works with handles.
150 173
151 // The xxx140 variants for backward compatibility do not allow a full-width offset. 174 // The xxx140 variants for backward compatibility do not allow a full-width offset.
152 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) 175 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
153 UnsafeWrapper("Unsafe_GetObject"); 176 UnsafeWrapper("Unsafe_GetObject");
154 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); 177 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
155 GET_FIELD(obj, offset, oop, v); 178 GET_OOP_FIELD(obj, offset, v)
156 return JNIHandles::make_local(env, v); 179 return JNIHandles::make_local(env, v);
157 UNSAFE_END 180 UNSAFE_END
158 181
159 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) 182 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
160 UnsafeWrapper("Unsafe_SetObject"); 183 UnsafeWrapper("Unsafe_SetObject");
161 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); 184 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
162 oop x = JNIHandles::resolve(x_h); 185 oop x = JNIHandles::resolve(x_h);
163 //SET_FIELD(obj, offset, oop, x); 186 //SET_FIELD(obj, offset, oop, x);
164 oop p = JNIHandles::resolve(obj); 187 oop p = JNIHandles::resolve(obj);
165 if (x != NULL) { 188 if (UseCompressedOops) {
166 // If there is a heap base pointer, we are obliged to emit a store barrier. 189 if (x != NULL) {
167 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); 190 // If there is a heap base pointer, we are obliged to emit a store barrier.
191 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
192 } else {
193 narrowOop n = oopDesc::encode_heap_oop_not_null(x);
194 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
195 }
168 } else { 196 } else {
169 *(oop*)index_oop_from_field_offset_long(p, offset) = x; 197 if (x != NULL) {
198 // If there is a heap base pointer, we are obliged to emit a store barrier.
199 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
200 } else {
201 *(oop*)index_oop_from_field_offset_long(p, offset) = x;
202 }
170 } 203 }
171 UNSAFE_END 204 UNSAFE_END
172 205
173 // The normal variants allow a null base pointer with an arbitrary address. 206 // The normal variants allow a null base pointer with an arbitrary address.
174 // But if the base pointer is non-null, the offset should make some sense. 207 // But if the base pointer is non-null, the offset should make some sense.
175 // That is, it should be in the range [0, MAX_OBJECT_SIZE]. 208 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
176 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) 209 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
177 UnsafeWrapper("Unsafe_GetObject"); 210 UnsafeWrapper("Unsafe_GetObject");
178 GET_FIELD(obj, offset, oop, v); 211 GET_OOP_FIELD(obj, offset, v)
179 return JNIHandles::make_local(env, v); 212 return JNIHandles::make_local(env, v);
180 UNSAFE_END 213 UNSAFE_END
181 214
182 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) 215 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
183 UnsafeWrapper("Unsafe_SetObject"); 216 UnsafeWrapper("Unsafe_SetObject");
184 oop x = JNIHandles::resolve(x_h); 217 oop x = JNIHandles::resolve(x_h);
185 oop p = JNIHandles::resolve(obj); 218 oop p = JNIHandles::resolve(obj);
186 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); 219 if (UseCompressedOops) {
220 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
221 } else {
222 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
223 }
187 UNSAFE_END 224 UNSAFE_END
188 225
189 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) 226 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
190 UnsafeWrapper("Unsafe_GetObjectVolatile"); 227 UnsafeWrapper("Unsafe_GetObjectVolatile");
191 GET_FIELD_VOLATILE(obj, offset, oop, v); 228 GET_OOP_FIELD_VOLATILE(obj, offset, v)
192 return JNIHandles::make_local(env, v); 229 return JNIHandles::make_local(env, v);
193 UNSAFE_END 230 UNSAFE_END
194 231
195 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) 232 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
196 UnsafeWrapper("Unsafe_SetObjectVolatile"); 233 UnsafeWrapper("Unsafe_SetObjectVolatile");
197 oop x = JNIHandles::resolve(x_h); 234 oop x = JNIHandles::resolve(x_h);
198 oop p = JNIHandles::resolve(obj); 235 oop p = JNIHandles::resolve(obj);
199 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); 236 if (UseCompressedOops) {
237 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
238 } else {
239 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
240 }
200 OrderAccess::fence(); 241 OrderAccess::fence();
201 UNSAFE_END 242 UNSAFE_END
202 243
203 // Volatile long versions must use locks if !VM_Version::supports_cx8(). 244 // Volatile long versions must use locks if !VM_Version::supports_cx8().
204 // support_cx8 is a surrogate for 'supports atomic long memory ops'. 245 // support_cx8 is a surrogate for 'supports atomic long memory ops'.
309 350
310 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) 351 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
311 UnsafeWrapper("Unsafe_SetOrderedObject"); 352 UnsafeWrapper("Unsafe_SetOrderedObject");
312 oop x = JNIHandles::resolve(x_h); 353 oop x = JNIHandles::resolve(x_h);
313 oop p = JNIHandles::resolve(obj); 354 oop p = JNIHandles::resolve(obj);
314 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); 355 if (UseCompressedOops) {
356 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
357 } else {
358 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
359 }
315 OrderAccess::fence(); 360 OrderAccess::fence();
316 UNSAFE_END 361 UNSAFE_END
317 362
318 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) 363 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x))
319 UnsafeWrapper("Unsafe_SetOrderedLong"); 364 UnsafeWrapper("Unsafe_SetOrderedLong");
645 klassOop k = java_lang_Class::as_klassOop(mirror); 690 klassOop k = java_lang_Class::as_klassOop(mirror);
646 if (k == NULL || !k->klass_part()->oop_is_array()) { 691 if (k == NULL || !k->klass_part()->oop_is_array()) {
647 THROW(vmSymbols::java_lang_InvalidClassException()); 692 THROW(vmSymbols::java_lang_InvalidClassException());
648 } else if (k->klass_part()->oop_is_objArray()) { 693 } else if (k->klass_part()->oop_is_objArray()) {
649 base = arrayOopDesc::base_offset_in_bytes(T_OBJECT); 694 base = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
650 scale = oopSize; 695 scale = heapOopSize;
651 } else if (k->klass_part()->oop_is_typeArray()) { 696 } else if (k->klass_part()->oop_is_typeArray()) {
652 typeArrayKlass* tak = typeArrayKlass::cast(k); 697 typeArrayKlass* tak = typeArrayKlass::cast(k);
653 base = tak->array_header_in_bytes(); 698 base = tak->array_header_in_bytes();
654 assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok"); 699 assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
655 scale = (1 << tak->log2_element_size()); 700 scale = (1 << tak->log2_element_size());
843 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) 888 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
844 UnsafeWrapper("Unsafe_CompareAndSwapObject"); 889 UnsafeWrapper("Unsafe_CompareAndSwapObject");
845 oop x = JNIHandles::resolve(x_h); 890 oop x = JNIHandles::resolve(x_h);
846 oop e = JNIHandles::resolve(e_h); 891 oop e = JNIHandles::resolve(e_h);
847 oop p = JNIHandles::resolve(obj); 892 oop p = JNIHandles::resolve(obj);
848 intptr_t* addr = (intptr_t *)index_oop_from_field_offset_long(p, offset); 893 HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
849 intptr_t res = Atomic::cmpxchg_ptr((intptr_t)x, addr, (intptr_t)e); 894 oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e);
850 jboolean success = (res == (intptr_t)e); 895 jboolean success = (res == e);
851 if (success) 896 if (success)
852 update_barrier_set((oop*)addr, x); 897 update_barrier_set((void*)addr, x);
853 return success; 898 return success;
854 UNSAFE_END 899 UNSAFE_END
855 900
856 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) 901 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
857 UnsafeWrapper("Unsafe_CompareAndSwapInt"); 902 UnsafeWrapper("Unsafe_CompareAndSwapInt");