提交 40d1bc75 编写于 作者: S shshahma

8162101: C2: Handle "wide" aliases for unsafe accesses

Reviewed-by: kvn, thartmann
上级 fe3bf367
...@@ -2630,23 +2630,24 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas ...@@ -2630,23 +2630,24 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas
val = is_store ? argument(3) : NULL; val = is_store ? argument(3) : NULL;
} }
// Can base be NULL? Otherwise, always on-heap access.
bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop));
const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
// Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM, // Try to categorize the address.
// there was not enough information to nail it down.
Compile::AliasType* alias_type = C->alias_type(adr_type); Compile::AliasType* alias_type = C->alias_type(adr_type);
assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here"); assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
// Only field, array element or unknown locations are supported. if (alias_type->adr_type() == TypeInstPtr::KLASS ||
if (alias_type->adr_type() != TypeRawPtr::BOTTOM && alias_type->adr_type() == TypeAryPtr::RANGE) {
alias_type->adr_type() != TypeOopPtr::BOTTOM && return false; // not supported
alias_type->basic_type() == T_ILLEGAL) {
return false;
} }
bool mismatched = false; bool mismatched = false;
BasicType bt = alias_type->basic_type(); BasicType bt = alias_type->basic_type();
if (bt != T_ILLEGAL) { if (bt != T_ILLEGAL) {
assert(alias_type->adr_type()->is_oopptr(), "should be on-heap access");
if (bt == T_BYTE && adr_type->isa_aryptr()) { if (bt == T_BYTE && adr_type->isa_aryptr()) {
// Alias type doesn't differentiate between byte[] and boolean[]). // Alias type doesn't differentiate between byte[] and boolean[]).
// Use address type to get the element type. // Use address type to get the element type.
...@@ -2663,6 +2664,8 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas ...@@ -2663,6 +2664,8 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas
mismatched = (bt != type); mismatched = (bt != type);
} }
assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched");
// First guess at the value type. // First guess at the value type.
const Type *value_type = Type::get_const_basic_type(type); const Type *value_type = Type::get_const_basic_type(type);
...@@ -2777,7 +2780,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas ...@@ -2777,7 +2780,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas
(void) store_to_memory(control(), adr, val, type, adr_type, mo, is_volatile, unaligned, mismatched); (void) store_to_memory(control(), adr, val, type, adr_type, mo, is_volatile, unaligned, mismatched);
} else { } else {
// Possibly an oop being stored to Java heap or native memory // 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. // oop to Java heap.
(void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched); (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
} else { } else {
......
...@@ -209,11 +209,11 @@ public: ...@@ -209,11 +209,11 @@ public:
static int cmp( const Type *const t1, const Type *const t2 ); static int cmp( const Type *const t1, const Type *const t2 );
// Test for higher or equal in lattice // Test for higher or equal in lattice
// Variant that drops the speculative part of the types // 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()); return !cmp(meet(t),t->remove_speculative());
} }
// Variant that keeps the speculative part of the types // 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); return !cmp(meet_speculative(t),t);
} }
......
...@@ -30,6 +30,22 @@ ...@@ -30,6 +30,22 @@
* *
* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
* -XX:-TieredCompilation -Xbatch * -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* * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
* compiler.unsafe.OpaqueAccesses * compiler.unsafe.OpaqueAccesses
*/ */
...@@ -61,6 +77,7 @@ public class OpaqueAccesses { ...@@ -61,6 +77,7 @@ public class OpaqueAccesses {
} }
private Object f = new Object(); private Object f = new Object();
private long l1, l2;
static Object testFixedOffsetField(Object o) { static Object testFixedOffsetField(Object o) {
return UNSAFE.getObject(o, F_OFFSET); return UNSAFE.getObject(o, F_OFFSET);
...@@ -74,6 +91,18 @@ public class OpaqueAccesses { ...@@ -74,6 +91,18 @@ public class OpaqueAccesses {
return UNSAFE.getInt(o, 4); 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 Object testFixedBase(long off) { static Object testFixedBase(long off) {
return UNSAFE.getObject(INSTANCE, off); return UNSAFE.getObject(INSTANCE, off);
} }
...@@ -90,6 +119,18 @@ public class OpaqueAccesses { ...@@ -90,6 +119,18 @@ public class OpaqueAccesses {
return UNSAFE.getInt(arr, 4); 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 Object testFixedOffsetArray(Object[] arr) { static Object testFixedOffsetArray(Object[] arr) {
return UNSAFE.getObject(arr, E_OFFSET); return UNSAFE.getObject(arr, E_OFFSET);
} }
...@@ -118,6 +159,9 @@ public class OpaqueAccesses { ...@@ -118,6 +159,9 @@ public class OpaqueAccesses {
testFixedOffsetField(INSTANCE); testFixedOffsetField(INSTANCE);
testFixedOffsetHeader0(INSTANCE); testFixedOffsetHeader0(INSTANCE);
testFixedOffsetHeader4(INSTANCE); testFixedOffsetHeader4(INSTANCE);
testFixedOffsetHeader8(INSTANCE);
testFixedOffsetHeader12(INSTANCE);
testFixedOffsetHeader16(INSTANCE);
testFixedBase(F_OFFSET); testFixedBase(F_OFFSET);
testOpaque(INSTANCE, F_OFFSET); testOpaque(INSTANCE, F_OFFSET);
testMixedAccess(); testMixedAccess();
...@@ -125,6 +169,9 @@ public class OpaqueAccesses { ...@@ -125,6 +169,9 @@ public class OpaqueAccesses {
// Array // Array
testFixedOffsetHeaderArray0(ARRAY); testFixedOffsetHeaderArray0(ARRAY);
testFixedOffsetHeaderArray4(ARRAY); testFixedOffsetHeaderArray4(ARRAY);
testFixedOffsetHeaderArray8(ARRAY);
testFixedOffsetHeaderArray12(ARRAY);
testFixedOffsetHeaderArray16(ARRAY);
testFixedOffsetArray(ARRAY); testFixedOffsetArray(ARRAY);
testFixedBaseArray(E_OFFSET); testFixedBaseArray(E_OFFSET);
testOpaqueArray(ARRAY, E_OFFSET); testOpaqueArray(ARRAY, E_OFFSET);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册