1 /*
2  * Copyright (c) 2014, 2018, 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 6898462 8198826
27  * @summary failed reallocations of scalar replaced objects during deoptimization causes crash
28  *
29  * @requires !vm.graal.enabled
30  * @run main/othervm -XX:-BackgroundCompilation -Xmx128M -XX:+IgnoreUnrecognizedVMOptions -XX:+VerifyStack
31  *      -XX:CompileCommand=exclude,compiler.uncommontrap.TestDeoptOOM::main
32  *      -XX:CompileCommand=exclude,compiler.uncommontrap.TestDeoptOOM::m9_1
33  *      compiler.uncommontrap.TestDeoptOOM
34  */
35 
36 package compiler.uncommontrap;
37 
38 public class TestDeoptOOM {
39 
40     long f1;
41     long f2;
42     long f3;
43     long f4;
44     long f5;
45 
46     static class LinkedList {
47         LinkedList l;
48         long[] array;
LinkedList(LinkedList l, int size)49         LinkedList(LinkedList l, int size) {
50             array = new long[size];
51             this.l = l;
52         }
53     }
54 
55     static LinkedList ll;
56 
consume_all_memory()57     static void consume_all_memory() {
58         int size = 128 * 1024 * 1024;
59         while(size > 0) {
60             try {
61                 while(true) {
62                     ll = new LinkedList(ll, size);
63                 }
64             } catch(OutOfMemoryError oom) {
65             }
66             size = size / 2;
67         }
68     }
69 
free_memory()70     static void free_memory() {
71         ll = null;
72     }
73 
m1(boolean deopt)74     static TestDeoptOOM m1(boolean deopt) {
75         try {
76             TestDeoptOOM tdoom = new TestDeoptOOM();
77             if (deopt) {
78                 return tdoom;
79             }
80         } catch(OutOfMemoryError oom) {
81             free_memory();
82             System.out.println("OOM caught in m1");
83         }
84         return null;
85     }
86 
m2_1(boolean deopt)87     static TestDeoptOOM m2_1(boolean deopt) {
88         try {
89             TestDeoptOOM tdoom = new TestDeoptOOM();
90             if (deopt) {
91                 return tdoom;
92             }
93         } catch(OutOfMemoryError oom) {
94             free_memory();
95             System.out.println("OOM caught in m2_1");
96         }
97         return null;
98     }
99 
m2(boolean deopt)100     static TestDeoptOOM m2(boolean deopt) {
101         try {
102             return m2_1(deopt);
103         } catch(OutOfMemoryError oom) {
104             free_memory();
105             System.out.println("OOM caught in m2");
106         }
107         return null;
108     }
109 
m3_3(boolean deopt)110     static TestDeoptOOM m3_3(boolean deopt) {
111         try {
112             TestDeoptOOM tdoom = new TestDeoptOOM();
113             if (deopt) {
114                 return tdoom;
115             }
116         } catch(OutOfMemoryError oom) {
117             free_memory();
118             System.out.println("OOM caught in m3_3");
119         }
120         return null;
121     }
122 
m3_2(boolean deopt)123     static boolean m3_2(boolean deopt) {
124         try {
125             return m3_3(deopt) != null;
126         } catch(OutOfMemoryError oom) {
127             free_memory();
128             System.out.println("OOM caught in m3_2");
129         }
130         return false;
131     }
132 
m3_1(boolean deopt)133     static TestDeoptOOM m3_1(boolean deopt) {
134         try {
135             TestDeoptOOM tdoom = new TestDeoptOOM();
136             if (m3_2(deopt)) {
137                 return tdoom;
138             }
139         } catch(OutOfMemoryError oom) {
140             free_memory();
141             System.out.println("OOM caught in m3_1");
142         }
143         return null;
144     }
145 
m3(boolean deopt)146     static TestDeoptOOM m3(boolean deopt) {
147         try {
148             return m3_1(deopt);
149         } catch(OutOfMemoryError oom) {
150             free_memory();
151             System.out.println("OOM caught in m3");
152         }
153         return null;
154     }
155 
m4(boolean deopt)156     static TestDeoptOOM m4(boolean deopt) {
157         try {
158             TestDeoptOOM tdoom = new TestDeoptOOM();
159             if (deopt) {
160                 tdoom.f1 = 1l;
161                 tdoom.f2 = 2l;
162                 tdoom.f3 = 3l;
163                 return tdoom;
164             }
165         } catch(OutOfMemoryError oom) {
166             free_memory();
167             System.out.println("OOM caught in m4");
168         }
169         return null;
170     }
171 
m5(boolean deopt)172     static TestDeoptOOM m5(boolean deopt) {
173         try {
174             TestDeoptOOM tdoom = new TestDeoptOOM();
175             synchronized(tdoom) {
176                 if (deopt) {
177                     return tdoom;
178                 }
179             }
180         } catch(OutOfMemoryError oom) {
181             free_memory();
182             System.out.println("OOM caught in m5");
183         }
184         return null;
185     }
186 
m6_1(boolean deopt)187     synchronized TestDeoptOOM m6_1(boolean deopt) {
188         if (deopt) {
189             return this;
190         }
191         return null;
192     }
193 
m6(boolean deopt)194     static TestDeoptOOM m6(boolean deopt) {
195         try {
196             TestDeoptOOM tdoom = new TestDeoptOOM();
197             return tdoom.m6_1(deopt);
198         } catch(OutOfMemoryError oom) {
199             free_memory();
200             System.out.println("OOM caught in m6");
201         }
202         return null;
203     }
204 
m7_1(boolean deopt, Object lock)205     static TestDeoptOOM m7_1(boolean deopt, Object lock) {
206         try {
207             synchronized(lock) {
208                 TestDeoptOOM tdoom = new TestDeoptOOM();
209                 if (deopt) {
210                     return tdoom;
211                 }
212             }
213         } catch(OutOfMemoryError oom) {
214             free_memory();
215             System.out.println("OOM caught in m7_1");
216         }
217         return null;
218     }
219 
m7(boolean deopt, Object lock)220     static TestDeoptOOM m7(boolean deopt, Object lock) {
221         try {
222             return m7_1(deopt, lock);
223         } catch(OutOfMemoryError oom) {
224             free_memory();
225             System.out.println("OOM caught in m7");
226         }
227         return null;
228     }
229 
230     static class A {
231         long f1;
232         long f2;
233         long f3;
234         long f4;
235         long f5;
236     }
237 
238     static class B {
239         long f1;
240         long f2;
241         long f3;
242         long f4;
243         long f5;
244 
245         A a;
246     }
247 
m8(boolean deopt)248     static B m8(boolean deopt) {
249         try {
250             A a = new A();
251             B b = new B();
252             b.a = a;
253             if (deopt) {
254                 return b;
255             }
256         } catch(OutOfMemoryError oom) {
257             free_memory();
258             System.out.println("OOM caught in m8");
259         }
260         return null;
261     }
262 
m9_1(int i)263     static void m9_1(int i) {
264         if (i > 90000) {
265             consume_all_memory();
266         }
267     }
268 
m9()269     static TestDeoptOOM m9() {
270         try {
271             for (int i = 0; i < 100000; i++) {
272                 TestDeoptOOM tdoom = new TestDeoptOOM();
273                 m9_1(i);
274                 if (i > 90000) {
275                     return tdoom;
276                 }
277             }
278         } catch(OutOfMemoryError oom) {
279             free_memory();
280             System.out.println("OOM caught in m1");
281         }
282         return null;
283     }
284 
main(String[] args)285     public static void main(String[] args) {
286         for (int i = 0; i < 20000; i++) {
287             m1(false);
288         }
289 
290         consume_all_memory();
291 
292         try {
293             m1(true);
294         } catch(OutOfMemoryError oom) {
295             free_memory();
296             System.out.println("OOM caught in main " + oom.getMessage());
297         }
298 
299         free_memory();
300 
301         for (int i = 0; i < 20000; i++) {
302             m2(false);
303         }
304 
305         consume_all_memory();
306 
307         try {
308             m2(true);
309         } catch(OutOfMemoryError oom) {
310             free_memory();
311             System.out.println("OOM caught in main");
312         }
313 
314         free_memory();
315 
316         for (int i = 0; i < 20000; i++) {
317             m3(false);
318         }
319 
320         consume_all_memory();
321 
322         try {
323             m3(true);
324         } catch(OutOfMemoryError oom) {
325             free_memory();
326             System.out.println("OOM caught in main");
327         }
328 
329         free_memory();
330 
331         for (int i = 0; i < 20000; i++) {
332             m4(false);
333         }
334 
335         consume_all_memory();
336 
337         try {
338             m4(true);
339         } catch(OutOfMemoryError oom) {
340             free_memory();
341             System.out.println("OOM caught in main");
342         }
343 
344         free_memory();
345 
346         for (int i = 0; i < 20000; i++) {
347             m5(false);
348         }
349 
350         consume_all_memory();
351 
352         try {
353             m5(true);
354         } catch(OutOfMemoryError oom) {
355             free_memory();
356             System.out.println("OOM caught in main");
357         }
358 
359         free_memory();
360 
361         for (int i = 0; i < 20000; i++) {
362             m6(false);
363         }
364 
365         consume_all_memory();
366 
367         try {
368             m6(true);
369         } catch(OutOfMemoryError oom) {
370             free_memory();
371             System.out.println("OOM caught in main");
372         }
373 
374         free_memory();
375 
376         final Object lock = new Object();
377 
378         for (int i = 0; i < 20000; i++) {
379             m7(false, lock);
380         }
381 
382         consume_all_memory();
383 
384         try {
385             m7(true, lock);
386         } catch(OutOfMemoryError oom) {
387             free_memory();
388             System.out.println("OOM caught in main");
389         }
390 
391         free_memory();
392 
393         Thread thread = new Thread() {
394                 public void run() {
395                     System.out.println("Acquiring lock");
396                     synchronized(lock) {
397                         System.out.println("Lock acquired");
398                     }
399                     System.out.println("Lock released");
400                 }
401             };
402         thread.start();
403         try {
404             thread.join();
405         } catch(InterruptedException ie) {
406         }
407 
408         for (int i = 0; i < 20000; i++) {
409             m8(false);
410         }
411 
412         consume_all_memory();
413 
414         try {
415             m8(true);
416         } catch(OutOfMemoryError oom) {
417             free_memory();
418             System.out.println("OOM caught in main");
419         }
420 
421         free_memory();
422 
423         try {
424             m9();
425         } catch(OutOfMemoryError oom) {
426             free_memory();
427             System.out.println("OOM caught in main");
428         }
429 
430         free_memory();
431     }
432 }
433