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