1 /* 2 * Copyright (c) 2024 Alibaba Group Holding Limited. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 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.c2.irTests.scalarReplacement; 25 26 import compiler.lib.ir_framework.*; 27 28 /* 29 * @test 30 * @bug 8333334 31 * @summary Tests that dead barrier control flows do not affect the scalar replacement. 32 * @library /test/lib / 33 * @requires vm.compiler2.enabled 34 * @requires vm.gc.G1 35 * @run driver compiler.c2.irTests.scalarReplacement.ScalarReplacementWithGCBarrierTests 36 */ 37 public class ScalarReplacementWithGCBarrierTests { 38 static class List { 39 public Node head; 40 41 public void push(int value) { 42 Node n = new Node(); 43 n.value = value; 44 n.next = head; 45 head = n; 46 } 47 48 @ForceInline 49 public Iter iter() { 50 Iter iter = new Iter(); 51 iter.list = this; 52 iter.n = head; 53 iter.sum = 0; 54 return iter; 55 } 56 } 57 58 static class Node { 59 public int value; 60 public Node next; 61 } 62 63 static class Iter { 64 public List list; 65 public Node n; 66 public Integer sum; 67 68 @ForceInline 69 public boolean next() { 70 int lastSum = sum; 71 while (sum - lastSum < 1000) { 72 while (n != null && n.value < 30) n = n.next; 73 if (n == null) return false; 74 sum += n.value; 75 n = n.next; 76 } 77 return true; 78 } 79 } 80 81 private static final int SIZE = 1000; 82 83 public static void main(String[] args) { 84 // Must use G1 GC to ensure there is a pre-barrier 85 // before the first field write. 86 TestFramework.runWithFlags("-XX:+UseG1GC"); 87 } 88 89 @Run(test = "testScalarReplacementWithGCBarrier") 90 private void runner() { 91 List list = new List(); 92 for (int i = 0; i < SIZE; i++) { 93 list.push(i); 94 } 95 testScalarReplacementWithGCBarrier(list); 96 } 97 98 // Allocation of `Iter iter` should be eliminated by scalar replacement, and 99 // the allocation of `Integer sum` can not be eliminated, so there should be 100 // 1 allocation after allocations and locks elimination. 101 // 102 // Before the patch of JDK-8333334, both allocations of `Iter` and `Integer` 103 // could not be eliminated. 104 @Test 105 @IR(phase = { CompilePhase.PHASEIDEAL_BEFORE_EA }, counts = { IRNode.ALLOC, "2" }) 106 @IR(phase = { CompilePhase.ITER_GVN_AFTER_ELIMINATION }, counts = { IRNode.ALLOC, "1" }) 107 private int testScalarReplacementWithGCBarrier(List list) { 108 Iter iter = list.iter(); 109 while (true) { 110 while (iter.next()) {} 111 if (list.head == null) break; 112 list.head = list.head.next; 113 iter.n = list.head; 114 } 115 return iter.sum; 116 } 117 }