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'. |
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"); |