Wed, 23 Nov 2016 23:15:05 -0800
8162101: C2: Handle "wide" aliases for unsafe accesses
Reviewed-by: kvn, thartmann
1.1 --- a/src/share/vm/opto/library_call.cpp Wed Nov 23 23:10:03 2016 -0800 1.2 +++ b/src/share/vm/opto/library_call.cpp Wed Nov 23 23:15:05 2016 -0800 1.3 @@ -2630,23 +2630,24 @@ 1.4 val = is_store ? argument(3) : NULL; 1.5 } 1.6 1.7 + // Can base be NULL? Otherwise, always on-heap access. 1.8 + bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop)); 1.9 + 1.10 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); 1.11 1.12 - // Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM, 1.13 - // there was not enough information to nail it down. 1.14 + // Try to categorize the address. 1.15 Compile::AliasType* alias_type = C->alias_type(adr_type); 1.16 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here"); 1.17 1.18 - // Only field, array element or unknown locations are supported. 1.19 - if (alias_type->adr_type() != TypeRawPtr::BOTTOM && 1.20 - alias_type->adr_type() != TypeOopPtr::BOTTOM && 1.21 - alias_type->basic_type() == T_ILLEGAL) { 1.22 - return false; 1.23 + if (alias_type->adr_type() == TypeInstPtr::KLASS || 1.24 + alias_type->adr_type() == TypeAryPtr::RANGE) { 1.25 + return false; // not supported 1.26 } 1.27 1.28 bool mismatched = false; 1.29 BasicType bt = alias_type->basic_type(); 1.30 if (bt != T_ILLEGAL) { 1.31 + assert(alias_type->adr_type()->is_oopptr(), "should be on-heap access"); 1.32 if (bt == T_BYTE && adr_type->isa_aryptr()) { 1.33 // Alias type doesn't differentiate between byte[] and boolean[]). 1.34 // Use address type to get the element type. 1.35 @@ -2663,6 +2664,8 @@ 1.36 mismatched = (bt != type); 1.37 } 1.38 1.39 + assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched"); 1.40 + 1.41 // First guess at the value type. 1.42 const Type *value_type = Type::get_const_basic_type(type); 1.43 1.44 @@ -2777,7 +2780,7 @@ 1.45 (void) store_to_memory(control(), adr, val, type, adr_type, mo, is_volatile, unaligned, mismatched); 1.46 } else { 1.47 // Possibly an oop being stored to Java heap or native memory 1.48 - if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) { 1.49 + if (!can_access_non_heap) { 1.50 // oop to Java heap. 1.51 (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched); 1.52 } else {
2.1 --- a/src/share/vm/opto/type.hpp Wed Nov 23 23:10:03 2016 -0800 2.2 +++ b/src/share/vm/opto/type.hpp Wed Nov 23 23:15:05 2016 -0800 2.3 @@ -209,11 +209,11 @@ 2.4 static int cmp( const Type *const t1, const Type *const t2 ); 2.5 // Test for higher or equal in lattice 2.6 // Variant that drops the speculative part of the types 2.7 - int higher_equal(const Type *t) const { 2.8 + bool higher_equal(const Type *t) const { 2.9 return !cmp(meet(t),t->remove_speculative()); 2.10 } 2.11 // Variant that keeps the speculative part of the types 2.12 - int higher_equal_speculative(const Type *t) const { 2.13 + bool higher_equal_speculative(const Type *t) const { 2.14 return !cmp(meet_speculative(t),t); 2.15 } 2.16
3.1 --- a/test/compiler/unsafe/OpaqueAccesses.java Wed Nov 23 23:10:03 2016 -0800 3.2 +++ b/test/compiler/unsafe/OpaqueAccesses.java Wed Nov 23 23:15:05 2016 -0800 3.3 @@ -30,6 +30,22 @@ 3.4 * 3.5 * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 3.6 * -XX:-TieredCompilation -Xbatch 3.7 + * -XX:+UseCompressedOops -XX:+UseCompressedClassPointers 3.8 + * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test* 3.9 + * compiler.unsafe.OpaqueAccesses 3.10 + * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 3.11 + * -XX:-TieredCompilation -Xbatch 3.12 + * -XX:+UseCompressedOops -XX:-UseCompressedClassPointers 3.13 + * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test* 3.14 + * compiler.unsafe.OpaqueAccesses 3.15 + * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 3.16 + * -XX:-TieredCompilation -Xbatch 3.17 + * -XX:-UseCompressedOops -XX:+UseCompressedClassPointers 3.18 + * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test* 3.19 + * compiler.unsafe.OpaqueAccesses 3.20 + * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 3.21 + * -XX:-TieredCompilation -Xbatch 3.22 + * -XX:-UseCompressedOops -XX:-UseCompressedClassPointers 3.23 * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test* 3.24 * compiler.unsafe.OpaqueAccesses 3.25 */ 3.26 @@ -61,6 +77,7 @@ 3.27 } 3.28 3.29 private Object f = new Object(); 3.30 + private long l1, l2; 3.31 3.32 static Object testFixedOffsetField(Object o) { 3.33 return UNSAFE.getObject(o, F_OFFSET); 3.34 @@ -74,6 +91,18 @@ 3.35 return UNSAFE.getInt(o, 4); 3.36 } 3.37 3.38 + static int testFixedOffsetHeader8(Object o) { 3.39 + return UNSAFE.getInt(o, 8); 3.40 + } 3.41 + 3.42 + static int testFixedOffsetHeader12(Object o) { 3.43 + return UNSAFE.getInt(o, 12); 3.44 + } 3.45 + 3.46 + static int testFixedOffsetHeader16(Object o) { 3.47 + return UNSAFE.getInt(o, 16); 3.48 + } 3.49 + 3.50 static Object testFixedBase(long off) { 3.51 return UNSAFE.getObject(INSTANCE, off); 3.52 } 3.53 @@ -90,6 +119,18 @@ 3.54 return UNSAFE.getInt(arr, 4); 3.55 } 3.56 3.57 + static int testFixedOffsetHeaderArray8(Object[] arr) { 3.58 + return UNSAFE.getInt(arr, 8); 3.59 + } 3.60 + 3.61 + static int testFixedOffsetHeaderArray12(Object[] arr) { 3.62 + return UNSAFE.getInt(arr, 12); 3.63 + } 3.64 + 3.65 + static int testFixedOffsetHeaderArray16(Object[] arr) { 3.66 + return UNSAFE.getInt(arr, 16); 3.67 + } 3.68 + 3.69 static Object testFixedOffsetArray(Object[] arr) { 3.70 return UNSAFE.getObject(arr, E_OFFSET); 3.71 } 3.72 @@ -118,6 +159,9 @@ 3.73 testFixedOffsetField(INSTANCE); 3.74 testFixedOffsetHeader0(INSTANCE); 3.75 testFixedOffsetHeader4(INSTANCE); 3.76 + testFixedOffsetHeader8(INSTANCE); 3.77 + testFixedOffsetHeader12(INSTANCE); 3.78 + testFixedOffsetHeader16(INSTANCE); 3.79 testFixedBase(F_OFFSET); 3.80 testOpaque(INSTANCE, F_OFFSET); 3.81 testMixedAccess(); 3.82 @@ -125,6 +169,9 @@ 3.83 // Array 3.84 testFixedOffsetHeaderArray0(ARRAY); 3.85 testFixedOffsetHeaderArray4(ARRAY); 3.86 + testFixedOffsetHeaderArray8(ARRAY); 3.87 + testFixedOffsetHeaderArray12(ARRAY); 3.88 + testFixedOffsetHeaderArray16(ARRAY); 3.89 testFixedOffsetArray(ARRAY); 3.90 testFixedBaseArray(E_OFFSET); 3.91 testOpaqueArray(ARRAY, E_OFFSET);