test/hotspot/jtreg/runtime/StackTrace/LargeClassTest.java
changeset 48814 f01f81fa1242
equal deleted inserted replaced
48813:c092a2fbb7c3 48814:f01f81fa1242
       
     1 /*
       
     2  * Copyright (c) 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 8194246
       
    27  * @summary JVM crashes on stack trace for large number of methods.
       
    28  * @library /test/lib
       
    29  * @modules java.base/jdk.internal.org.objectweb.asm
       
    30  *          java.base/jdk.internal.misc
       
    31  * @compile LargeClassTest.java
       
    32  * @run main LargeClassTest
       
    33  */
       
    34 
       
    35 import java.io.File;
       
    36 import java.io.FileOutputStream;
       
    37 import jdk.internal.org.objectweb.asm.ClassWriter;
       
    38 import jdk.internal.org.objectweb.asm.MethodVisitor;
       
    39 import jdk.internal.org.objectweb.asm.FieldVisitor;
       
    40 import jdk.internal.org.objectweb.asm.Label;
       
    41 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
       
    42 import jdk.internal.org.objectweb.asm.Opcodes;
       
    43 import jdk.test.lib.process.ProcessTools;
       
    44 import jdk.test.lib.process.OutputAnalyzer;
       
    45 
       
    46 public class LargeClassTest implements Opcodes {
       
    47     public static void main(String... args) throws Exception {
       
    48         writeClassFile();
       
    49         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".",  "Large");
       
    50         OutputAnalyzer output = new OutputAnalyzer(pb.start());
       
    51         output.shouldHaveExitValue(0);
       
    52     }
       
    53 
       
    54     // Writes a Large class with > signed 16 bit int methods
       
    55     public static void writeClassFile() throws Exception {
       
    56 
       
    57         ClassWriter cw = new ClassWriter(0);
       
    58         FieldVisitor fv;
       
    59         MethodVisitor mv;
       
    60         AnnotationVisitor av0;
       
    61 
       
    62         cw.visit(55, ACC_PUBLIC + ACC_SUPER, "Large", null, "java/lang/Object", null);
       
    63 
       
    64         {
       
    65           mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
       
    66           mv.visitCode();
       
    67           mv.visitVarInsn(ALOAD, 0);
       
    68           mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
       
    69           mv.visitInsn(RETURN);
       
    70           mv.visitMaxs(1, 1);
       
    71           mv.visitEnd();
       
    72         }
       
    73         {
       
    74           // public static void main(String[] args) {
       
    75           //     Large large = new Large();
       
    76           //     large.f_1(55);
       
    77           // }
       
    78           mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
       
    79           mv.visitCode();
       
    80           mv.visitTypeInsn(NEW, "Large");
       
    81           mv.visitInsn(DUP);
       
    82           mv.visitMethodInsn(INVOKESPECIAL, "Large", "<init>", "()V", false);
       
    83           mv.visitVarInsn(ASTORE, 1);
       
    84           mv.visitVarInsn(ALOAD, 1);
       
    85           mv.visitIntInsn(BIPUSH, 55);
       
    86           mv.visitMethodInsn(INVOKEVIRTUAL, "Large", "f_1", "(I)I", false);
       
    87           mv.visitInsn(POP);
       
    88           mv.visitInsn(RETURN);
       
    89           mv.visitMaxs(2, 2);
       
    90           mv.visitEnd();
       
    91         }
       
    92 
       
    93         // Write 33560 methods called f_$i
       
    94         for (int i = 1000; i < 34560; i++)
       
    95         {
       
    96           mv = cw.visitMethod(ACC_PUBLIC, "f_" + i, "()V", null, null);
       
    97           mv.visitCode();
       
    98           mv.visitInsn(RETURN);
       
    99           mv.visitMaxs(0, 1);
       
   100           mv.visitEnd();
       
   101         }
       
   102         {
       
   103           // public int f_1(int prior) {
       
   104           //   int total = prior + new java.util.Random(1).nextInt();
       
   105           //   return total + f_2(total);
       
   106           // }
       
   107           mv = cw.visitMethod(ACC_PUBLIC, "f_1", "(I)I", null, null);
       
   108           mv.visitCode();
       
   109           mv.visitVarInsn(ILOAD, 1);
       
   110           mv.visitTypeInsn(NEW, "java/util/Random");
       
   111           mv.visitInsn(DUP);
       
   112           mv.visitInsn(LCONST_1);
       
   113           mv.visitMethodInsn(INVOKESPECIAL, "java/util/Random", "<init>", "(J)V", false);
       
   114           mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Random", "nextInt", "()I", false);
       
   115           mv.visitInsn(IADD);
       
   116           mv.visitVarInsn(ISTORE, 2);
       
   117           mv.visitVarInsn(ILOAD, 2);
       
   118           mv.visitVarInsn(ALOAD, 0);
       
   119           mv.visitVarInsn(ILOAD, 2);
       
   120           mv.visitMethodInsn(INVOKEVIRTUAL, "Large", "f_2", "(I)I", false);
       
   121           mv.visitInsn(IADD);
       
   122           mv.visitInsn(IRETURN);
       
   123           mv.visitMaxs(5, 3);
       
   124           mv.visitEnd();
       
   125         }
       
   126         {
       
   127           // public int f_2(int total) {
       
   128           //   System.out.println(java.util.Arrays.toString(Thread.currentThread().getStackTrace()));
       
   129           //   return 10;
       
   130           // }
       
   131           mv = cw.visitMethod(ACC_PUBLIC, "f_2", "(I)I", null, null);
       
   132           mv.visitCode();
       
   133           mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
   134           mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", false);
       
   135           mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "getStackTrace", "()[Ljava/lang/StackTraceElement;", false);
       
   136           mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "toString", "([Ljava/lang/Object;)Ljava/lang/String;", false);
       
   137           mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
       
   138           mv.visitIntInsn(BIPUSH, 10);
       
   139           mv.visitInsn(IRETURN);
       
   140           mv.visitMaxs(2, 2);
       
   141           mv.visitEnd();
       
   142         }
       
   143         cw.visitEnd();
       
   144 
       
   145         try (FileOutputStream fos = new FileOutputStream(new File("Large.class"))) {
       
   146           fos.write(cw.toByteArray());
       
   147         }
       
   148     }
       
   149 }