TestEliminatedArrayCopyDeopt.java revision 11626:552ef60b5f47
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 8130847 8156760
27 * @summary Eliminated instance/array written to by an array copy variant must be correctly initialized when reallocated at a deopt
28 * @ignore 8136818
29 * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestEliminatedArrayCopyDeopt
30 * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+IgnoreUnrecognizedVMOptions -XX:-ReduceInitialCardMarks TestEliminatedArrayCopyDeopt
31 */
32
33// Test that if an ArrayCopy node is eliminated because it doesn't
34// escape, then the correct field/array element values are captured so
35// on a deoptimization, when the object/array is reallocated, it is
36// correctly initialized
37
38public class TestEliminatedArrayCopyDeopt {
39
40    static class A implements Cloneable {
41        int f0;
42        int f1;
43        int f2;
44        int f3;
45        int f4;
46        int f5;
47        int f6;
48        int f7;
49        int f8;
50        int f9;
51        int f10;
52        int f11;
53        int f12;
54        int f13;
55        int f14;
56        int f15;
57
58        public Object clone() throws CloneNotSupportedException {
59            return super.clone();
60        }
61    }
62
63    // Clone
64    static boolean m1(A a, boolean flag) throws CloneNotSupportedException {
65        A c = (A)a.clone();
66        if (flag) {
67            // never taken branch that causes the deoptimization
68            if (c.f0 != 0x42) {
69                return false;
70            }
71        }
72        return true;
73    }
74
75    // Array clone
76    static int[] m2_src = null;
77    static boolean m2(boolean flag) throws CloneNotSupportedException {
78        int[] src  = new int[10];
79        m2_src = src;
80        for (int i = 0; i < src.length; i++) {
81            src[i] = 0x42+i;
82        }
83        int[] c = (int[])src.clone();
84        if (flag) {
85            for (int i = 0; i < c.length; i++) {
86                if (c[i] != src[i]) {
87                    return false;
88                }
89            }
90        }
91        return true;
92    }
93
94    // Array copy
95    static boolean m3(int[] src, boolean flag) {
96        int[] dst = new int[10];
97        System.arraycopy(src, 0, dst, 0, 10);
98        if (flag) {
99            for (int i = 0; i < dst.length; i++) {
100                if (dst[i] != src[i]) {
101                    return false;
102                }
103            }
104        }
105        return true;
106    }
107
108    // Array copy of subrange
109    static boolean m4(int[] src, boolean flag) {
110        int[] dst = new int[10];
111        dst[0] = 0x42;
112        dst[1] = 0x42 - 1;
113        dst[2] = 0x42 - 2;
114        dst[8] = 0x42 - 8;
115        dst[9] = 0x42 - 9;
116        int src_off = 2;
117        int dst_off = 3;
118        int len = 5;
119        System.arraycopy(src, src_off, dst, dst_off, len);
120        if (flag) {
121            for (int i = 0; i < dst.length; i++) {
122                if (i >= dst_off &&  i < dst_off + len) {
123                    if (dst[i] != src[i - dst_off + src_off]) {
124                        return false;
125                    }
126                } else {
127                    if (dst[i] != 0x42-i) {
128                        return false;
129                    }
130                }
131            }
132        }
133        return true;
134    }
135
136    // Array copy with Phi
137    static boolean m5(int[] src, boolean flag1, boolean flag2) {
138        int[] dst = new int[10];
139        if (flag1) {
140            System.arraycopy(src, 0, dst, 0, 10);
141        }
142        if (flag2) {
143            for (int i = 0; i < dst.length; i++) {
144                if (dst[i] != src[i]) {
145                    return false;
146                }
147            }
148        }
149        return true;
150    }
151
152    static public void main(String[] args) throws Exception {
153        boolean success = true;
154        A a = new A();
155        a.f0 = 0x42;
156        for (int i = 0; i < 20000; i++) {
157            m1(a, false);
158        }
159        if (!m1(a, true)) {
160            System.out.println("m1 failed");
161            success = false;
162        }
163
164        for (int i = 0; i < 20000; i++) {
165            m2(false);
166        }
167        if (!m2(true)) {
168            System.out.println("m2 failed");
169            success = false;
170        }
171
172        int[] src = new int[10];
173        for (int i = 0; i < src.length; i++) {
174            src[i] = 0x42+i;
175        }
176
177        for (int i = 0; i < 20000; i++) {
178            m3(src, false);
179        }
180        if (!m3(src, true)) {
181            System.out.println("m3 failed");
182            success = false;
183        }
184
185        for (int i = 0; i < 20000; i++) {
186            m4(src, false);
187        }
188        if (!m4(src, true)) {
189            System.out.println("m4 failed");
190            success = false;
191        }
192
193        for (int i = 0; i < 20000; i++) {
194            m5(src, i%2 == 0, false);
195        }
196        if (!m5(src, true, true)) {
197            System.out.println("m4 failed");
198            success = false;
199        }
200
201        if (!success) {
202            throw new RuntimeException("Test failed");
203        }
204    }
205}
206