< prev index next >

test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java

Print this page

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package compiler.gcbarriers;
 25 
 26 import compiler.lib.ir_framework.*;
 27 import java.lang.invoke.VarHandle;
 28 import java.lang.invoke.MethodHandles;
 29 import java.lang.ref.Reference;
 30 import java.lang.ref.ReferenceQueue;
 31 import java.lang.ref.SoftReference;
 32 import java.lang.ref.WeakReference;
 33 import jdk.test.lib.Asserts;

 34 
 35 /**
 36  * @test
 37  * @summary Test that implicit null checks are generated as expected for
 38             different GC memory accesses.
 39  * @library /test/lib /

 40  * @run driver compiler.gcbarriers.TestImplicitNullChecks
 41  */
 42 
 43 
 44 public class TestImplicitNullChecks {
 45 
 46     static class Outer {
 47         Object f;
 48     }
 49 
 50     static class OuterWithVolatileField {
 51         volatile Object f;
 52     }
 53 
 54     static final VarHandle fVarHandle;

 55     static {
 56         MethodHandles.Lookup l = MethodHandles.lookup();
 57         try {
 58             fVarHandle = l.findVarHandle(Outer.class, "f", Object.class);
 59         } catch (Exception e) {
 60             throw new Error(e);
 61         }
 62     }
 63 
 64     public static void main(String[] args) {
 65         TestFramework.runWithFlags("-XX:CompileCommand=inline,java.lang.ref.*::*",

 66                                    "-XX:-TieredCompilation");
 67         TestFramework.runWithFlags("-XX:CompileCommand=inline,java.lang.ref.*::*",

 68                                    "-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1");
 69     }
 70 
 71     @Test
 72     // On AIX, implicit null checks are limited because the zero page is
 73     // readable (but not writable). See os::zero_page_read_protected().
 74     @IR(applyIfPlatform = {"aix", "false"},
 75         applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
 76         counts = {IRNode.NULL_CHECK, "1"},
 77         phase = CompilePhase.FINAL_CODE)
 78     static Object testLoad(Outer o) {
 79         return o.f;
 80     }
 81 
 82     @Test
 83     // On aarch64, volatile loads always use indirect memory operands, which
 84     // leads to a pattern that cannot be exploited by the current C2 analysis.
 85     // On PPC64, volatile loads are preceded by membar_volatile instructions,
 86     // which also inhibits the current C2 analysis.
 87     @IR(applyIfPlatformAnd = {"aarch64", "false", "ppc", "false"},

139 
140     @Run(test = {"testStore"})
141     static void runStoreTests() {
142         {
143             Outer o = new Outer();
144             Object o1 = new Object();
145             testStore(o, o1);
146         }
147     }
148 
149     @Test
150     // G1 and ZGC compare-and-exchange operations cannot be currently used to
151     // implement implicit null checks, because they expand into multiple memory
152     // access instructions that are not necessarily located at the initial
153     // instruction start address. The same holds for testCompareAndSwap and
154     // testGetAndSet below.
155     @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
156         failOn = IRNode.NULL_CHECK,
157         phase = CompilePhase.FINAL_CODE)
158     static Object testCompareAndExchange(Outer o, Object oldVal, Object newVal) {
159         return fVarHandle.compareAndExchange(o, oldVal, newVal);
160     }
161 
162     @Test
163     @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
164         failOn = IRNode.NULL_CHECK,
165         phase = CompilePhase.FINAL_CODE)
166     static boolean testCompareAndSwap(Outer o, Object oldVal, Object newVal) {
167         return fVarHandle.compareAndSet(o, oldVal, newVal);
168     }
169 
170     @Test
171     @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
172         failOn = IRNode.NULL_CHECK,
173         phase = CompilePhase.FINAL_CODE)
174     static Object testGetAndSet(Outer o, Object newVal) {
175         return fVarHandle.getAndSet(o, newVal);
176     }
177 
178     @Run(test = {"testCompareAndExchange",
179                  "testCompareAndSwap",
180                  "testGetAndSet"})
181     static void runAtomicTests() {
182         {
183             Outer o = new Outer();
184             Object oldVal = new Object();
185             Object newVal = new Object();
186             testCompareAndExchange(o, oldVal, newVal);
187         }
188         {
189             Outer o = new Outer();
190             Object oldVal = new Object();
191             Object newVal = new Object();
192             testCompareAndSwap(o, oldVal, newVal);
193         }
194         {
195             Outer o = new Outer();

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package compiler.gcbarriers;
 25 
 26 import compiler.lib.ir_framework.*;




 27 import java.lang.ref.SoftReference;
 28 import java.lang.ref.WeakReference;
 29 import jdk.test.lib.Asserts;
 30 import jdk.internal.misc.Unsafe;
 31 
 32 /**
 33  * @test
 34  * @summary Test that implicit null checks are generated as expected for
 35             different GC memory accesses.
 36  * @library /test/lib /
 37  * @modules java.base/jdk.internal.misc
 38  * @run driver compiler.gcbarriers.TestImplicitNullChecks
 39  */
 40 
 41 
 42 public class TestImplicitNullChecks {
 43 
 44     static class Outer {
 45         Object f;
 46     }
 47 
 48     static class OuterWithVolatileField {
 49         volatile Object f;
 50     }
 51 
 52     static final Unsafe UNSAFE = Unsafe.getUnsafe();
 53     static final long F_OFFSET;
 54     static {

 55         try {
 56             F_OFFSET = UNSAFE.objectFieldOffset(Outer.class.getDeclaredField("f"));
 57         } catch (Exception e) {
 58             throw new Error(e);
 59         }
 60     }
 61 
 62     public static void main(String[] args) {
 63         TestFramework.runWithFlags("--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED",
 64                                    "-XX:CompileCommand=inline,java.lang.ref.*::*",
 65                                    "-XX:-TieredCompilation");
 66         TestFramework.runWithFlags("--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED",
 67                                    "-XX:CompileCommand=inline,java.lang.ref.*::*",
 68                                    "-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1");
 69     }
 70 
 71     @Test
 72     // On AIX, implicit null checks are limited because the zero page is
 73     // readable (but not writable). See os::zero_page_read_protected().
 74     @IR(applyIfPlatform = {"aix", "false"},
 75         applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
 76         counts = {IRNode.NULL_CHECK, "1"},
 77         phase = CompilePhase.FINAL_CODE)
 78     static Object testLoad(Outer o) {
 79         return o.f;
 80     }
 81 
 82     @Test
 83     // On aarch64, volatile loads always use indirect memory operands, which
 84     // leads to a pattern that cannot be exploited by the current C2 analysis.
 85     // On PPC64, volatile loads are preceded by membar_volatile instructions,
 86     // which also inhibits the current C2 analysis.
 87     @IR(applyIfPlatformAnd = {"aarch64", "false", "ppc", "false"},

139 
140     @Run(test = {"testStore"})
141     static void runStoreTests() {
142         {
143             Outer o = new Outer();
144             Object o1 = new Object();
145             testStore(o, o1);
146         }
147     }
148 
149     @Test
150     // G1 and ZGC compare-and-exchange operations cannot be currently used to
151     // implement implicit null checks, because they expand into multiple memory
152     // access instructions that are not necessarily located at the initial
153     // instruction start address. The same holds for testCompareAndSwap and
154     // testGetAndSet below.
155     @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
156         failOn = IRNode.NULL_CHECK,
157         phase = CompilePhase.FINAL_CODE)
158     static Object testCompareAndExchange(Outer o, Object oldVal, Object newVal) {
159         return UNSAFE.compareAndExchangeReference(o, F_OFFSET, oldVal, newVal);
160     }
161 
162     @Test
163     @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
164         failOn = IRNode.NULL_CHECK,
165         phase = CompilePhase.FINAL_CODE)
166     static boolean testCompareAndSwap(Outer o, Object oldVal, Object newVal) {
167         return UNSAFE.compareAndSetReference(o, F_OFFSET, oldVal, newVal);
168     }
169 
170     @Test
171     @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"},
172         failOn = IRNode.NULL_CHECK,
173         phase = CompilePhase.FINAL_CODE)
174     static Object testGetAndSet(Outer o, Object newVal) {
175         return UNSAFE.getAndSetReference(o, F_OFFSET, newVal);
176     }
177 
178     @Run(test = {"testCompareAndExchange",
179                  "testCompareAndSwap",
180                  "testGetAndSet"})
181     static void runAtomicTests() {
182         {
183             Outer o = new Outer();
184             Object oldVal = new Object();
185             Object newVal = new Object();
186             testCompareAndExchange(o, oldVal, newVal);
187         }
188         {
189             Outer o = new Outer();
190             Object oldVal = new Object();
191             Object newVal = new Object();
192             testCompareAndSwap(o, oldVal, newVal);
193         }
194         {
195             Outer o = new Outer();
< prev index next >