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