--- a/hotspot/src/share/vm/opto/library_call.cpp Tue Aug 23 22:31:48 2016 +0000
+++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Aug 25 12:51:10 2016 +0300
@@ -2309,25 +2309,27 @@
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 @@
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 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 @@
(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 {
--- a/hotspot/src/share/vm/opto/type.hpp Tue Aug 23 22:31:48 2016 +0000
+++ b/hotspot/src/share/vm/opto/type.hpp Thu Aug 25 12:51:10 2016 +0300
@@ -210,11 +210,11 @@
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);
}
--- a/hotspot/test/compiler/unsafe/OpaqueAccesses.java Tue Aug 23 22:31:48 2016 +0000
+++ b/hotspot/test/compiler/unsafe/OpaqueAccesses.java Thu Aug 25 12:51:10 2016 +0300
@@ -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 @@
}
private Object f = new Object();
+ private long l1, l2;
static Object testFixedOffsetField(Object o) {
return UNSAFE.getObject(o, F_OFFSET);
@@ -74,6 +91,22 @@
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 @@
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 @@
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 @@
// Array
testFixedOffsetHeaderArray0(ARRAY);
testFixedOffsetHeaderArray4(ARRAY);
+ testFixedOffsetHeaderArray8(ARRAY);
+ testFixedOffsetHeaderArray12(ARRAY);
+ testFixedOffsetHeaderArray16(ARRAY);
+ testFixedOffsetHeaderArray17(ARRAY);
testFixedOffsetArray(ARRAY);
testFixedBaseArray(E_OFFSET);
testOpaqueArray(ARRAY, E_OFFSET);