mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
7009756: volatile variables could be broken throw reflection API
Use Atomic::load() and Atomic::store() to access a volatile long. Reviewed-by: iveresov, jrose, dholmes, never
This commit is contained in:
parent
26ddf9c14a
commit
afbf71368c
10 changed files with 154 additions and 62 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -154,12 +154,11 @@ jint Unsafe_invocation_key_to_method_slot(jint key) {
|
|||
|
||||
#define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
|
||||
oop p = JNIHandles::resolve(obj); \
|
||||
volatile type_name v = *(volatile type_name*)index_oop_from_field_offset_long(p, offset)
|
||||
volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
|
||||
|
||||
#define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
|
||||
oop p = JNIHandles::resolve(obj); \
|
||||
*(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \
|
||||
OrderAccess::fence();
|
||||
OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
|
||||
|
||||
// Macros for oops that check UseCompressedOops
|
||||
|
||||
|
@ -181,7 +180,8 @@ jint Unsafe_invocation_key_to_method_slot(jint key) {
|
|||
v = oopDesc::decode_heap_oop(n); \
|
||||
} else { \
|
||||
v = *(volatile oop*)index_oop_from_field_offset_long(p, offset); \
|
||||
}
|
||||
} \
|
||||
OrderAccess::acquire();
|
||||
|
||||
|
||||
// Get/SetObject must be special-cased, since it works with handles.
|
||||
|
@ -248,14 +248,22 @@ UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject
|
|||
UnsafeWrapper("Unsafe_SetObjectVolatile");
|
||||
oop x = JNIHandles::resolve(x_h);
|
||||
oop p = JNIHandles::resolve(obj);
|
||||
void* addr = index_oop_from_field_offset_long(p, offset);
|
||||
OrderAccess::release();
|
||||
if (UseCompressedOops) {
|
||||
oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
|
||||
oop_store((narrowOop*)addr, x);
|
||||
} else {
|
||||
oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
|
||||
oop_store((oop*)addr, x);
|
||||
}
|
||||
OrderAccess::fence();
|
||||
UNSAFE_END
|
||||
|
||||
#if defined(SPARC) || defined(X86)
|
||||
// Sparc and X86 have atomic jlong (8 bytes) instructions
|
||||
|
||||
#else
|
||||
// Keep old code for platforms which may not have atomic jlong (8 bytes) instructions
|
||||
|
||||
// Volatile long versions must use locks if !VM_Version::supports_cx8().
|
||||
// support_cx8 is a surrogate for 'supports atomic long memory ops'.
|
||||
|
||||
|
@ -291,6 +299,7 @@ UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject o
|
|||
}
|
||||
UNSAFE_END
|
||||
|
||||
#endif // not SPARC and not X86
|
||||
|
||||
#define DEFINE_GETSETOOP(jboolean, Boolean) \
|
||||
\
|
||||
|
@ -320,6 +329,16 @@ UNSAFE_END \
|
|||
\
|
||||
// END DEFINE_GETSETOOP.
|
||||
|
||||
DEFINE_GETSETOOP(jboolean, Boolean)
|
||||
DEFINE_GETSETOOP(jbyte, Byte)
|
||||
DEFINE_GETSETOOP(jshort, Short);
|
||||
DEFINE_GETSETOOP(jchar, Char);
|
||||
DEFINE_GETSETOOP(jint, Int);
|
||||
DEFINE_GETSETOOP(jlong, Long);
|
||||
DEFINE_GETSETOOP(jfloat, Float);
|
||||
DEFINE_GETSETOOP(jdouble, Double);
|
||||
|
||||
#undef DEFINE_GETSETOOP
|
||||
|
||||
#define DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) \
|
||||
\
|
||||
|
@ -336,47 +355,49 @@ UNSAFE_END \
|
|||
\
|
||||
// END DEFINE_GETSETOOP_VOLATILE.
|
||||
|
||||
DEFINE_GETSETOOP(jboolean, Boolean)
|
||||
DEFINE_GETSETOOP(jbyte, Byte)
|
||||
DEFINE_GETSETOOP(jshort, Short);
|
||||
DEFINE_GETSETOOP(jchar, Char);
|
||||
DEFINE_GETSETOOP(jint, Int);
|
||||
DEFINE_GETSETOOP(jlong, Long);
|
||||
DEFINE_GETSETOOP(jfloat, Float);
|
||||
DEFINE_GETSETOOP(jdouble, Double);
|
||||
|
||||
DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
|
||||
DEFINE_GETSETOOP_VOLATILE(jbyte, Byte)
|
||||
DEFINE_GETSETOOP_VOLATILE(jshort, Short);
|
||||
DEFINE_GETSETOOP_VOLATILE(jchar, Char);
|
||||
DEFINE_GETSETOOP_VOLATILE(jint, Int);
|
||||
// no long -- handled specially
|
||||
DEFINE_GETSETOOP_VOLATILE(jfloat, Float);
|
||||
DEFINE_GETSETOOP_VOLATILE(jdouble, Double);
|
||||
|
||||
#undef DEFINE_GETSETOOP
|
||||
#if defined(SPARC) || defined(X86)
|
||||
// Sparc and X86 have atomic jlong (8 bytes) instructions
|
||||
DEFINE_GETSETOOP_VOLATILE(jlong, Long);
|
||||
#endif
|
||||
|
||||
#undef DEFINE_GETSETOOP_VOLATILE
|
||||
|
||||
// The non-intrinsified versions of setOrdered just use setVolatile
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x)) \
|
||||
UnsafeWrapper("Unsafe_SetOrderedInt"); \
|
||||
SET_FIELD_VOLATILE(obj, offset, jint, x); \
|
||||
UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x))
|
||||
UnsafeWrapper("Unsafe_SetOrderedInt");
|
||||
SET_FIELD_VOLATILE(obj, offset, jint, x);
|
||||
UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
|
||||
UnsafeWrapper("Unsafe_SetOrderedObject");
|
||||
oop x = JNIHandles::resolve(x_h);
|
||||
oop p = JNIHandles::resolve(obj);
|
||||
void* addr = index_oop_from_field_offset_long(p, offset);
|
||||
OrderAccess::release();
|
||||
if (UseCompressedOops) {
|
||||
oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
|
||||
oop_store((narrowOop*)addr, x);
|
||||
} else {
|
||||
oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
|
||||
oop_store((oop*)addr, x);
|
||||
}
|
||||
OrderAccess::fence();
|
||||
UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x))
|
||||
UnsafeWrapper("Unsafe_SetOrderedLong");
|
||||
#if defined(SPARC) || defined(X86)
|
||||
// Sparc and X86 have atomic jlong (8 bytes) instructions
|
||||
SET_FIELD_VOLATILE(obj, offset, jlong, x);
|
||||
#else
|
||||
// Keep old code for platforms which may not have atomic long (8 bytes) instructions
|
||||
{
|
||||
if (VM_Version::supports_cx8()) {
|
||||
SET_FIELD_VOLATILE(obj, offset, jlong, x);
|
||||
|
@ -388,6 +409,7 @@ UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject ob
|
|||
*addr = x;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
UNSAFE_END
|
||||
|
||||
////// Data in the C heap.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue