Wed, 23 Nov 2016 23:10:03 -0800
8155781: C2: opaque unsafe access triggers an assert
Reviewed-by: kvn, thartmann
src/share/vm/opto/library_call.cpp | file | annotate | diff | comparison | revisions | |
test/compiler/unsafe/OpaqueAccesses.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/library_call.cpp Wed Nov 23 23:06:39 2016 -0800 1.2 +++ b/src/share/vm/opto/library_call.cpp Wed Nov 23 23:10:03 2016 -0800 1.3 @@ -2637,8 +2637,13 @@ 1.4 Compile::AliasType* alias_type = C->alias_type(adr_type); 1.5 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here"); 1.6 1.7 - assert(alias_type->adr_type() == TypeRawPtr::BOTTOM || alias_type->adr_type() == TypeOopPtr::BOTTOM || 1.8 - alias_type->basic_type() != T_ILLEGAL, "field, array element or unknown"); 1.9 + // Only field, array element or unknown locations are supported. 1.10 + if (alias_type->adr_type() != TypeRawPtr::BOTTOM && 1.11 + alias_type->adr_type() != TypeOopPtr::BOTTOM && 1.12 + alias_type->basic_type() == T_ILLEGAL) { 1.13 + return false; 1.14 + } 1.15 + 1.16 bool mismatched = false; 1.17 BasicType bt = alias_type->basic_type(); 1.18 if (bt != T_ILLEGAL) { 1.19 @@ -2961,12 +2966,6 @@ 1.20 newval = argument(4); // type: oop, int, or long 1.21 } 1.22 1.23 - // Null check receiver. 1.24 - receiver = null_check(receiver); 1.25 - if (stopped()) { 1.26 - return true; 1.27 - } 1.28 - 1.29 // Build field offset expression. 1.30 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset 1.31 // to be plain byte offsets, which are also the same as those accepted 1.32 @@ -2978,8 +2977,6 @@ 1.33 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); 1.34 1.35 Compile::AliasType* alias_type = C->alias_type(adr_type); 1.36 - assert(alias_type->adr_type() == TypeRawPtr::BOTTOM || alias_type->adr_type() == TypeOopPtr::BOTTOM || 1.37 - alias_type->basic_type() != T_ILLEGAL, "field, array element or unknown"); 1.38 BasicType bt = alias_type->basic_type(); 1.39 if (bt != T_ILLEGAL && 1.40 ((bt == T_OBJECT || bt == T_ARRAY) != (type == T_OBJECT))) { 1.41 @@ -2999,6 +2996,12 @@ 1.42 } 1.43 } 1.44 1.45 + // Null check receiver. 1.46 + receiver = null_check(receiver); 1.47 + if (stopped()) { 1.48 + return true; 1.49 + } 1.50 + 1.51 int alias_idx = C->get_alias_index(adr_type); 1.52 1.53 // Memory-model-wise, a LoadStore acts like a little synchronized
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/unsafe/OpaqueAccesses.java Wed Nov 23 23:10:03 2016 -0800 2.3 @@ -0,0 +1,134 @@ 2.4 +/* 2.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. Oracle designates this 2.11 + * particular file as subject to the "Classpath" exception as provided 2.12 + * by Oracle in the LICENSE file that accompanied this code. 2.13 + * 2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.17 + * version 2 for more details (a copy is included in the LICENSE file that 2.18 + * accompanied this code). 2.19 + * 2.20 + * You should have received a copy of the GNU General Public License version 2.21 + * 2 along with this work; if not, write to the Free Software Foundation, 2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.23 + * 2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.25 + * or visit www.oracle.com if you need additional information or have any 2.26 + * questions. 2.27 + */ 2.28 + 2.29 +/* 2.30 + * @test 2.31 + * @bug 8155781 2.32 + * @modules java.base/jdk.internal.misc 2.33 + * 2.34 + * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 2.35 + * -XX:-TieredCompilation -Xbatch 2.36 + * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test* 2.37 + * compiler.unsafe.OpaqueAccesses 2.38 + */ 2.39 +package compiler.unsafe; 2.40 + 2.41 +import sun.misc.Unsafe; 2.42 + 2.43 +import java.lang.reflect.Field; 2.44 + 2.45 +public class OpaqueAccesses { 2.46 + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); 2.47 + 2.48 + private static final Object INSTANCE = new OpaqueAccesses(); 2.49 + 2.50 + private static final Object[] ARRAY = new Object[10]; 2.51 + 2.52 + private static final long F_OFFSET; 2.53 + private static final long E_OFFSET; 2.54 + 2.55 + static { 2.56 + try { 2.57 + Field field = OpaqueAccesses.class.getDeclaredField("f"); 2.58 + F_OFFSET = UNSAFE.objectFieldOffset(field); 2.59 + 2.60 + E_OFFSET = UNSAFE.arrayBaseOffset(ARRAY.getClass()); 2.61 + } catch (NoSuchFieldException e) { 2.62 + throw new Error(e); 2.63 + } 2.64 + } 2.65 + 2.66 + private Object f = new Object(); 2.67 + 2.68 + static Object testFixedOffsetField(Object o) { 2.69 + return UNSAFE.getObject(o, F_OFFSET); 2.70 + } 2.71 + 2.72 + static int testFixedOffsetHeader0(Object o) { 2.73 + return UNSAFE.getInt(o, 0); 2.74 + } 2.75 + 2.76 + static int testFixedOffsetHeader4(Object o) { 2.77 + return UNSAFE.getInt(o, 4); 2.78 + } 2.79 + 2.80 + static Object testFixedBase(long off) { 2.81 + return UNSAFE.getObject(INSTANCE, off); 2.82 + } 2.83 + 2.84 + static Object testOpaque(Object o, long off) { 2.85 + return UNSAFE.getObject(o, off); 2.86 + } 2.87 + 2.88 + static int testFixedOffsetHeaderArray0(Object[] arr) { 2.89 + return UNSAFE.getInt(arr, 0); 2.90 + } 2.91 + 2.92 + static int testFixedOffsetHeaderArray4(Object[] arr) { 2.93 + return UNSAFE.getInt(arr, 4); 2.94 + } 2.95 + 2.96 + static Object testFixedOffsetArray(Object[] arr) { 2.97 + return UNSAFE.getObject(arr, E_OFFSET); 2.98 + } 2.99 + 2.100 + static Object testFixedBaseArray(long off) { 2.101 + return UNSAFE.getObject(ARRAY, off); 2.102 + } 2.103 + 2.104 + static Object testOpaqueArray(Object[] o, long off) { 2.105 + return UNSAFE.getObject(o, off); 2.106 + } 2.107 + 2.108 + static final long ADDR = UNSAFE.allocateMemory(10); 2.109 + static boolean flag; 2.110 + 2.111 + static int testMixedAccess() { 2.112 + flag = !flag; 2.113 + Object o = (flag ? INSTANCE : null); 2.114 + long off = (flag ? F_OFFSET : ADDR); 2.115 + return UNSAFE.getInt(o, off); 2.116 + } 2.117 + 2.118 + public static void main(String[] args) { 2.119 + for (int i = 0; i < 20_000; i++) { 2.120 + // Instance 2.121 + testFixedOffsetField(INSTANCE); 2.122 + testFixedOffsetHeader0(INSTANCE); 2.123 + testFixedOffsetHeader4(INSTANCE); 2.124 + testFixedBase(F_OFFSET); 2.125 + testOpaque(INSTANCE, F_OFFSET); 2.126 + testMixedAccess(); 2.127 + 2.128 + // Array 2.129 + testFixedOffsetHeaderArray0(ARRAY); 2.130 + testFixedOffsetHeaderArray4(ARRAY); 2.131 + testFixedOffsetArray(ARRAY); 2.132 + testFixedBaseArray(E_OFFSET); 2.133 + testOpaqueArray(ARRAY, E_OFFSET); 2.134 + } 2.135 + System.out.println("TEST PASSED"); 2.136 + } 2.137 +}