10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/vmSymbols.hpp"
27 #include "utilities/macros.hpp"
28 #if INCLUDE_ALL_GCS
29 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
30 #endif // INCLUDE_ALL_GCS
31 #include "jfr/jfrEvents.hpp"
32 #include "memory/allocation.inline.hpp"
33 #include "prims/jni.h"
34 #include "prims/jvm.h"
35 #include "runtime/globals.hpp"
36 #include "runtime/interfaceSupport.hpp"
37 #include "runtime/prefetch.inline.hpp"
38 #include "runtime/orderAccess.inline.hpp"
39 #include "runtime/reflection.hpp"
40 #include "runtime/synchronizer.hpp"
41 #include "services/threadService.hpp"
42 #include "utilities/copy.hpp"
43 #include "utilities/dtrace.hpp"
44
45 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
46
47 /*
48 * Implementation of class sun.misc.Unsafe
49 */
179 OrderAccess::fence(); \
180 } \
181 volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
182
183 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
184 oop p = JNIHandles::resolve(obj); \
185 OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
186
187 // Macros for oops that check UseCompressedOops
188
189 #define GET_OOP_FIELD(obj, offset, v) \
190 oop p = JNIHandles::resolve(obj); \
191 oop v; \
192 if (UseCompressedOops) { \
193 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
194 v = oopDesc::decode_heap_oop(n); \
195 } else { \
196 v = *(oop*)index_oop_from_field_offset_long(p, offset); \
197 }
198
199
200 // Get/SetObject must be special-cased, since it works with handles.
201
202 // We could be accessing the referent field in a reference
203 // object. If G1 is enabled then we need to register non-null
204 // referent with the SATB barrier.
205
206 #if INCLUDE_ALL_GCS
207 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
208 if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
209 Klass* k = o->klass();
210 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
211 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
212 return true;
213 }
214 }
215 return false;
216 }
217 #endif
218
219 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
220 #if INCLUDE_ALL_GCS
221 if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
222 G1SATBCardTableModRefBS::enqueue(v);
223 }
224 #endif
225 }
226
227 // The xxx140 variants for backward compatibility do not allow a full-width offset.
228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
229 UnsafeWrapper("Unsafe_GetObject");
230 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
231 GET_OOP_FIELD(obj, offset, v)
232
233 ensure_satb_referent_alive(p, offset, v);
234
235 return JNIHandles::make_local(env, v);
236 UNSAFE_END
237
238 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
239 UnsafeWrapper("Unsafe_SetObject");
240 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
241 oop x = JNIHandles::resolve(x_h);
242 //SET_FIELD(obj, offset, oop, x);
243 oop p = JNIHandles::resolve(obj);
244 if (UseCompressedOops) {
245 if (x != NULL) {
246 // If there is a heap base pointer, we are obliged to emit a store barrier.
247 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
248 } else {
249 narrowOop n = oopDesc::encode_heap_oop_not_null(x);
250 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
251 }
252 } else {
253 if (x != NULL) {
254 // If there is a heap base pointer, we are obliged to emit a store barrier.
255 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
256 } else {
257 *(oop*)index_oop_from_field_offset_long(p, offset) = x;
258 }
259 }
260 UNSAFE_END
261
262 // The normal variants allow a null base pointer with an arbitrary address.
263 // But if the base pointer is non-null, the offset should make some sense.
264 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
265 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
266 UnsafeWrapper("Unsafe_GetObject");
267 GET_OOP_FIELD(obj, offset, v)
268
269 ensure_satb_referent_alive(p, offset, v);
270
271 return JNIHandles::make_local(env, v);
272 UNSAFE_END
273
274 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
275 UnsafeWrapper("Unsafe_SetObject");
276 oop x = JNIHandles::resolve(x_h);
277 oop p = JNIHandles::resolve(obj);
278 if (UseCompressedOops) {
279 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
280 } else {
281 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
282 }
283 UNSAFE_END
284
285 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
286 UnsafeWrapper("Unsafe_GetObjectVolatile");
287 oop p = JNIHandles::resolve(obj);
288 void* addr = index_oop_from_field_offset_long(p, offset);
289 volatile oop v;
290 if (UseCompressedOops) {
291 volatile narrowOop n = *(volatile narrowOop*) addr;
292 (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
293 } else {
294 (void)const_cast<oop&>(v = *(volatile oop*) addr);
295 }
296
297 ensure_satb_referent_alive(p, offset, v);
298
299 OrderAccess::acquire();
300 return JNIHandles::make_local(env, v);
301 UNSAFE_END
302
303 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
304 UnsafeWrapper("Unsafe_SetObjectVolatile");
305 oop x = JNIHandles::resolve(x_h);
306 oop p = JNIHandles::resolve(obj);
307 void* addr = index_oop_from_field_offset_long(p, offset);
308 OrderAccess::release();
309 if (UseCompressedOops) {
310 oop_store((narrowOop*)addr, x);
311 } else {
312 oop_store((oop*)addr, x);
313 }
314 OrderAccess::fence();
315 UNSAFE_END
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/vmSymbols.hpp"
27 #include "utilities/macros.hpp"
28 #if INCLUDE_ALL_GCS
29 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
30 #include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp"
31 #endif // INCLUDE_ALL_GCS
32 #include "jfr/jfrEvents.hpp"
33 #include "memory/allocation.inline.hpp"
34 #include "prims/jni.h"
35 #include "prims/jvm.h"
36 #include "runtime/globals.hpp"
37 #include "runtime/interfaceSupport.hpp"
38 #include "runtime/prefetch.inline.hpp"
39 #include "runtime/orderAccess.inline.hpp"
40 #include "runtime/reflection.hpp"
41 #include "runtime/synchronizer.hpp"
42 #include "services/threadService.hpp"
43 #include "utilities/copy.hpp"
44 #include "utilities/dtrace.hpp"
45
46 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
47
48 /*
49 * Implementation of class sun.misc.Unsafe
50 */
180 OrderAccess::fence(); \
181 } \
182 volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
183
184 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
185 oop p = JNIHandles::resolve(obj); \
186 OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
187
188 // Macros for oops that check UseCompressedOops
189
190 #define GET_OOP_FIELD(obj, offset, v) \
191 oop p = JNIHandles::resolve(obj); \
192 oop v; \
193 if (UseCompressedOops) { \
194 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
195 v = oopDesc::decode_heap_oop(n); \
196 } else { \
197 v = *(oop*)index_oop_from_field_offset_long(p, offset); \
198 }
199
200 // Get/SetObject must be special-cased, since it works with handles.
201
202 // We could be accessing the referent field in a reference
203 // object. If G1 is enabled then we need to register non-null
204 // referent with the SATB barrier.
205
206 #if INCLUDE_ALL_GCS
207 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
208 if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
209 Klass* k = o->klass();
210 if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
211 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
212 return true;
213 }
214 }
215 return false;
216 }
217 #endif
218
219 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
220 #if INCLUDE_ALL_GCS
221 if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
222 G1SATBCardTableModRefBS::enqueue(v);
223 }
224 #endif
225 }
226
227 // The xxx140 variants for backward compatibility do not allow a full-width offset.
228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
229 UnsafeWrapper("Unsafe_GetObject");
230 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
231 GET_OOP_FIELD(obj, offset, v)
232
233 #if INCLUDE_ALL_GCS
234 if (UseShenandoahGC) {
235 v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v);
236 }
237 #endif
238
239 ensure_satb_referent_alive(p, offset, v);
240
241 return JNIHandles::make_local(env, v);
242 UNSAFE_END
243
244 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
245 UnsafeWrapper("Unsafe_SetObject");
246 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
247 oop x = JNIHandles::resolve(x_h);
248 //SET_FIELD(obj, offset, oop, x);
249 oop p = JNIHandles::resolve(obj);
250 if (UseCompressedOops) {
251 if (x != NULL) {
252 // If there is a heap base pointer, we are obliged to emit a store barrier.
253 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
254 } else {
255 narrowOop n = oopDesc::encode_heap_oop_not_null(x);
256 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
257 }
258 } else {
259 if (x != NULL) {
260 // If there is a heap base pointer, we are obliged to emit a store barrier.
261 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
262 } else {
263 *(oop*)index_oop_from_field_offset_long(p, offset) = x;
264 }
265 }
266 UNSAFE_END
267
268 // The normal variants allow a null base pointer with an arbitrary address.
269 // But if the base pointer is non-null, the offset should make some sense.
270 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
271 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
272 UnsafeWrapper("Unsafe_GetObject");
273 GET_OOP_FIELD(obj, offset, v)
274
275 #if INCLUDE_ALL_GCS
276 if (UseShenandoahGC) {
277 v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v);
278 }
279 #endif
280
281 ensure_satb_referent_alive(p, offset, v);
282
283 return JNIHandles::make_local(env, v);
284 UNSAFE_END
285
286 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
287 UnsafeWrapper("Unsafe_SetObject");
288 oop x = JNIHandles::resolve(x_h);
289 oop p = JNIHandles::resolve(obj);
290 if (UseCompressedOops) {
291 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
292 } else {
293 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
294 }
295 UNSAFE_END
296
297 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
298 UnsafeWrapper("Unsafe_GetObjectVolatile");
299 oop p = JNIHandles::resolve(obj);
300 void* addr = index_oop_from_field_offset_long(p, offset);
301 volatile oop v;
302 if (UseCompressedOops) {
303 volatile narrowOop n = *(volatile narrowOop*) addr;
304 (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
305 } else {
306 (void)const_cast<oop&>(v = *(volatile oop*) addr);
307 }
308
309 #if INCLUDE_ALL_GCS
310 if (UseShenandoahGC) {
311 (void)const_cast<oop&>(v = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(v));
312 }
313 #endif
314
315 ensure_satb_referent_alive(p, offset, v);
316
317 OrderAccess::acquire();
318 return JNIHandles::make_local(env, v);
319 UNSAFE_END
320
321 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
322 UnsafeWrapper("Unsafe_SetObjectVolatile");
323 oop x = JNIHandles::resolve(x_h);
324 oop p = JNIHandles::resolve(obj);
325 void* addr = index_oop_from_field_offset_long(p, offset);
326 OrderAccess::release();
327 if (UseCompressedOops) {
328 oop_store((narrowOop*)addr, x);
329 } else {
330 oop_store((oop*)addr, x);
331 }
332 OrderAccess::fence();
333 UNSAFE_END
|