1 /*
2  * Copyright (c) 2016, Oracle and/or its affiliates. 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 /**
25  * @test
26  * @bug 8148175
27  * @requires vm.gc=="G1" | vm.gc=="null"
28  * @library /test/lib
29  * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions
30  *      -XX:+WhiteBoxAPI -Xmx300m -XX:+UseG1GC
31  *      compiler.gcbarriers.PreserveFPRegistersTest
32  */
33 
34 package compiler.gcbarriers;
35 
36 import sun.hotspot.WhiteBox;
37 
38 public class PreserveFPRegistersTest {
39 
main(String... args)40     public static void main(String... args) throws InterruptedException {
41         new PreserveFPRegistersTest().go();
42     }
43 
44     private static WhiteBox wb = WhiteBox.getWhiteBox();
45 
46     public final Object[][] storage;
47 
48     /**
49      * Number of objects per region.
50      */
51     public final int K = 10;
52 
53     /**
54      * Length of object array: sizeOf(Object[N]) ~= regionSize / K .
55      */
56     public final int N;
57 
58     /**
59      * How many regions involved into testing.
60      */
61     public final int regionCount;
62 
PreserveFPRegistersTest()63     PreserveFPRegistersTest() {
64         long regionSize = wb.g1RegionSize();
65         Runtime rt = Runtime.getRuntime();
66         long used = rt.totalMemory() - rt.freeMemory();
67         long totalFree = rt.maxMemory() - used;
68         regionCount = (int) ( (totalFree / regionSize) * 0.9);
69         int refSize = wb.getHeapOopSize();
70         N = (int) ((regionSize / K ) / refSize) - 5;
71 
72         System.out.println("%% Memory");
73         System.out.println("%%   used          :        " + used / 1024 + "M");
74         System.out.println("%%   available     :        " + totalFree / 1024 + "M");
75         System.out.println("%%   G1 Region Size:        " + regionSize / 1024 + "M");
76         System.out.println("%%   region count  :        " + regionCount);
77 
78         System.out.println("%% Objects storage");
79         System.out.println("%%   N (array length)      : " + N);
80         System.out.println("%%   K (objects in regions): " + K);
81         System.out.println("%%   Reference size        : " + refSize);
82 
83         try {
84             storage = new Object[regionCount * K][];
85             for (int i = 0; i < storage.length; i++) {
86                 storage[i] = new Object[N];
87             }
88         } catch(OutOfMemoryError e) {
89             throw new AssertionError("Test Failed with unexpected OutOfMemoryError exception");
90         }
91     }
92 
go()93     public void go() throws InterruptedException {
94         final float FINAL = getValue();
95 
96         for (int to = 0; to < regionCount; to++) {
97             Object celebrity = storage[to * K];
98             for (int from = 0; from < regionCount; from++) {
99                 for (int rn = 0; rn != 100; rn++) {
100                     storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity;
101                 }
102                 if (FINAL != getValue()) {
103                     throw new AssertionError("Final value has changed: " + FINAL + " != " + getValue());
104                 }
105             }
106         }
107 
108         System.out.println("TEST PASSED");
109     }
110 
getValue()111     public float getValue() {
112         return 6;
113     }
114 
getX(int to, int from, int rn)115     private int getX(int to, int from, int rn) {
116         return (rn*regionCount + to) % N;
117     }
118 
getY(int to, int from, int rn)119     private int getY(int to, int from, int rn) {
120         return ((rn*regionCount + to) / N + from * K) % (regionCount*K) ;
121     }
122 }
123