Mercurial > hg > graal-jvmci-8
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"); |