8162101: C2: Handle "wide" aliases for unsafe accesses
Reviewed-by: kvn
This commit is contained in:
parent
0eb2d4511b
commit
bf0209ffa9
hotspot
@ -2309,25 +2309,27 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
|
||||
if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) {
|
||||
heap_base_oop = base;
|
||||
}
|
||||
|
||||
// Can base be NULL? Otherwise, always on-heap access.
|
||||
bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop));
|
||||
|
||||
val = is_store ? argument(4) : NULL;
|
||||
|
||||
const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
|
||||
|
||||
// Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM,
|
||||
// there was not enough information to nail it down.
|
||||
// Try to categorize the address.
|
||||
Compile::AliasType* alias_type = C->alias_type(adr_type);
|
||||
assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
|
||||
|
||||
// Only field, array element or unknown locations are supported.
|
||||
if (alias_type->adr_type() != TypeRawPtr::BOTTOM &&
|
||||
alias_type->adr_type() != TypeOopPtr::BOTTOM &&
|
||||
alias_type->basic_type() == T_ILLEGAL) {
|
||||
return false;
|
||||
if (alias_type->adr_type() == TypeInstPtr::KLASS ||
|
||||
alias_type->adr_type() == TypeAryPtr::RANGE) {
|
||||
return false; // not supported
|
||||
}
|
||||
|
||||
bool mismatched = false;
|
||||
BasicType bt = alias_type->basic_type();
|
||||
if (bt != T_ILLEGAL) {
|
||||
assert(alias_type->adr_type()->is_oopptr(), "should be on-heap access");
|
||||
if (bt == T_BYTE && adr_type->isa_aryptr()) {
|
||||
// Alias type doesn't differentiate between byte[] and boolean[]).
|
||||
// Use address type to get the element type.
|
||||
@ -2342,10 +2344,12 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
|
||||
return false;
|
||||
}
|
||||
mismatched = (bt != type);
|
||||
} else if (alias_type->adr_type() == TypeOopPtr::BOTTOM) {
|
||||
} else if (alias_type->adr_type()->isa_oopptr()) {
|
||||
mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched
|
||||
}
|
||||
|
||||
assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched");
|
||||
|
||||
// First guess at the value type.
|
||||
const Type *value_type = Type::get_const_basic_type(type);
|
||||
|
||||
@ -2357,7 +2361,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
|
||||
bool need_mem_bar;
|
||||
switch (kind) {
|
||||
case Relaxed:
|
||||
need_mem_bar = (alias_type->adr_type() == TypeOopPtr::BOTTOM);
|
||||
need_mem_bar = mismatched || can_access_non_heap;
|
||||
break;
|
||||
case Opaque:
|
||||
// Opaque uses CPUOrder membars for protection against code movement.
|
||||
@ -2512,7 +2516,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
|
||||
(void) store_to_memory(control(), adr, val, type, adr_type, mo, requires_atomic_access, unaligned, mismatched);
|
||||
} else {
|
||||
// Possibly an oop being stored to Java heap or native memory
|
||||
if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
|
||||
if (!can_access_non_heap) {
|
||||
// oop to Java heap.
|
||||
(void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
|
||||
} else {
|
||||
|
@ -210,11 +210,11 @@ public:
|
||||
static int cmp( const Type *const t1, const Type *const t2 );
|
||||
// Test for higher or equal in lattice
|
||||
// Variant that drops the speculative part of the types
|
||||
int higher_equal(const Type *t) const {
|
||||
bool higher_equal(const Type *t) const {
|
||||
return !cmp(meet(t),t->remove_speculative());
|
||||
}
|
||||
// Variant that keeps the speculative part of the types
|
||||
int higher_equal_speculative(const Type *t) const {
|
||||
bool higher_equal_speculative(const Type *t) const {
|
||||
return !cmp(meet_speculative(t),t);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,22 @@
|
||||
*
|
||||
* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-TieredCompilation -Xbatch
|
||||
* -XX:+UseCompressedOops -XX:+UseCompressedClassPointers
|
||||
* -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
|
||||
* compiler.unsafe.OpaqueAccesses
|
||||
* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-TieredCompilation -Xbatch
|
||||
* -XX:+UseCompressedOops -XX:-UseCompressedClassPointers
|
||||
* -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
|
||||
* compiler.unsafe.OpaqueAccesses
|
||||
* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-TieredCompilation -Xbatch
|
||||
* -XX:-UseCompressedOops -XX:+UseCompressedClassPointers
|
||||
* -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
|
||||
* compiler.unsafe.OpaqueAccesses
|
||||
* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-TieredCompilation -Xbatch
|
||||
* -XX:-UseCompressedOops -XX:-UseCompressedClassPointers
|
||||
* -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
|
||||
* compiler.unsafe.OpaqueAccesses
|
||||
*/
|
||||
@ -61,6 +77,7 @@ public class OpaqueAccesses {
|
||||
}
|
||||
|
||||
private Object f = new Object();
|
||||
private long l1, l2;
|
||||
|
||||
static Object testFixedOffsetField(Object o) {
|
||||
return UNSAFE.getObject(o, F_OFFSET);
|
||||
@ -74,6 +91,22 @@ public class OpaqueAccesses {
|
||||
return UNSAFE.getInt(o, 4);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeader8(Object o) {
|
||||
return UNSAFE.getInt(o, 8);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeader12(Object o) {
|
||||
return UNSAFE.getInt(o, 12);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeader16(Object o) {
|
||||
return UNSAFE.getInt(o, 16);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeader17(Object o) {
|
||||
return UNSAFE.getIntUnaligned(o, 17);
|
||||
}
|
||||
|
||||
static Object testFixedBase(long off) {
|
||||
return UNSAFE.getObject(INSTANCE, off);
|
||||
}
|
||||
@ -90,6 +123,22 @@ public class OpaqueAccesses {
|
||||
return UNSAFE.getInt(arr, 4);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeaderArray8(Object[] arr) {
|
||||
return UNSAFE.getInt(arr, 8);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeaderArray12(Object[] arr) {
|
||||
return UNSAFE.getInt(arr, 12);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeaderArray16(Object[] arr) {
|
||||
return UNSAFE.getInt(arr, 16);
|
||||
}
|
||||
|
||||
static int testFixedOffsetHeaderArray17(Object[] arr) {
|
||||
return UNSAFE.getIntUnaligned(arr, 17);
|
||||
}
|
||||
|
||||
static Object testFixedOffsetArray(Object[] arr) {
|
||||
return UNSAFE.getObject(arr, E_OFFSET);
|
||||
}
|
||||
@ -118,6 +167,10 @@ public class OpaqueAccesses {
|
||||
testFixedOffsetField(INSTANCE);
|
||||
testFixedOffsetHeader0(INSTANCE);
|
||||
testFixedOffsetHeader4(INSTANCE);
|
||||
testFixedOffsetHeader8(INSTANCE);
|
||||
testFixedOffsetHeader12(INSTANCE);
|
||||
testFixedOffsetHeader16(INSTANCE);
|
||||
testFixedOffsetHeader17(INSTANCE);
|
||||
testFixedBase(F_OFFSET);
|
||||
testOpaque(INSTANCE, F_OFFSET);
|
||||
testMixedAccess();
|
||||
@ -125,6 +178,10 @@ public class OpaqueAccesses {
|
||||
// Array
|
||||
testFixedOffsetHeaderArray0(ARRAY);
|
||||
testFixedOffsetHeaderArray4(ARRAY);
|
||||
testFixedOffsetHeaderArray8(ARRAY);
|
||||
testFixedOffsetHeaderArray12(ARRAY);
|
||||
testFixedOffsetHeaderArray16(ARRAY);
|
||||
testFixedOffsetHeaderArray17(ARRAY);
|
||||
testFixedOffsetArray(ARRAY);
|
||||
testFixedBaseArray(E_OFFSET);
|
||||
testOpaqueArray(ARRAY, E_OFFSET);
|
||||
|
Loading…
x
Reference in New Issue
Block a user