test/compiler/jsr292/ConcurrentClassLoadingTest.java

Thu, 26 Sep 2013 10:25:02 -0400

author
hseigel
date
Thu, 26 Sep 2013 10:25:02 -0400
changeset 5784
190899198332
parent 5631
74608df95ba3
child 6116
cdf20166ec45
permissions
-rw-r--r--

7195622: CheckUnhandledOops has limited usefulness now
Summary: Enable CHECK_UNHANDLED_OOPS in fastdebug builds across all supported platforms.
Reviewed-by: coleenp, hseigel, dholmes, stefank, twisti, ihse, rdurbin
Contributed-by: lois.foltan@oracle.com

     1 /*
     2  * Copyright (c) 2013, 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  */
    24 /**
    25  * @test
    26  * @bug 8022595
    27  * @summary JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives
    28  *
    29  * @run main/othervm ConcurrentClassLoadingTest
    30  */
    31 import java.util.*;
    32 import java.util.concurrent.BrokenBarrierException;
    33 import java.util.concurrent.CyclicBarrier;
    35 public class ConcurrentClassLoadingTest {
    36     int numThreads = 0;
    37     long seed = 0;
    38     CyclicBarrier l;
    39     Random rand;
    41     public static void main(String[] args) throws Throwable {
    42         ConcurrentClassLoadingTest test = new ConcurrentClassLoadingTest();
    43         test.parseArgs(args);
    44         test.run();
    45     }
    47     void parseArgs(String[] args) {
    48         int i = 0;
    49         while (i < args.length) {
    50             String flag = args[i];
    51             switch(flag) {
    52                 case "-seed":
    53                     seed = Long.parseLong(args[++i]);
    54                     break;
    55                 case "-numThreads":
    56                     numThreads = Integer.parseInt(args[++i]);
    57                     break;
    58                 default:
    59                     throw new Error("Unknown flag: " + flag);
    60             }
    61             ++i;
    62         }
    63     }
    65     void init() {
    66         if (numThreads == 0) {
    67             numThreads = Runtime.getRuntime().availableProcessors();
    68         }
    70         if (seed == 0) {
    71             seed = (new Random()).nextLong();
    72         }
    73         rand = new Random(seed);
    75         l = new CyclicBarrier(numThreads + 1);
    77         System.out.printf("Threads: %d\n", numThreads);
    78         System.out.printf("Seed: %d\n", seed);
    79     }
    81     final List<Loader> loaders = new ArrayList<>();
    83     void prepare() {
    84         List<String> c = new ArrayList<>(Arrays.asList(classNames));
    86         // Split classes between loading threads
    87         int count = (classNames.length / numThreads) + 1;
    88         for (int t = 0; t < numThreads; t++) {
    89             List<String> sel = new ArrayList<>();
    91             System.out.printf("Thread #%d:\n", t);
    92             for (int i = 0; i < count; i++) {
    93                 if (c.size() == 0) break;
    95                 int k = rand.nextInt(c.size());
    96                 String elem = c.remove(k);
    97                 sel.add(elem);
    98                 System.out.printf("\t%s\n", elem);
    99             }
   100             loaders.add(new Loader(sel));
   101         }
   103         // Print diagnostic info when the test hangs
   104         Runtime.getRuntime().addShutdownHook(new Thread() {
   105             public void run() {
   106                 boolean alive = false;
   107                 for (Loader l : loaders) {
   108                     if (!l.isAlive())  continue;
   110                     if (!alive) {
   111                         System.out.println("Some threads are still alive:");
   112                         alive = true;
   113                     }
   115                     System.out.println(l.getName());
   116                     for (StackTraceElement elem : l.getStackTrace()) {
   117                         System.out.println("\t"+elem.toString());
   118                     }
   119                 }
   120             }
   121         });
   122     }
   124     public void run() throws Throwable {
   125         init();
   126         prepare();
   128         for (Loader loader : loaders) {
   129             loader.start();
   130         }
   132         l.await();
   134         for (Loader loader : loaders) {
   135             loader.join();
   136         }
   137     }
   139     class Loader extends Thread {
   140         List<String> classes;
   142         public Loader(List<String> classes) {
   143             this.classes = classes;
   144             setDaemon(true);
   145         }
   147         @Override
   148         public void run() {
   149             try {
   150                 l.await();
   152                 for (String name : classes) {
   153                     Class.forName(name).getName();
   154                 }
   155             } catch (ClassNotFoundException | BrokenBarrierException | InterruptedException e) {
   156                 throw new Error(e);
   157             }
   158         }
   159     }
   161     final static String[] classNames = {
   162             "java.lang.invoke.AbstractValidatingLambdaMetafactory",
   163             "java.lang.invoke.BoundMethodHandle",
   164             "java.lang.invoke.CallSite",
   165             "java.lang.invoke.ConstantCallSite",
   166             "java.lang.invoke.DirectMethodHandle",
   167             "java.lang.invoke.InnerClassLambdaMetafactory",
   168             "java.lang.invoke.InvokeDynamic",
   169             "java.lang.invoke.InvokeGeneric",
   170             "java.lang.invoke.InvokerBytecodeGenerator",
   171             "java.lang.invoke.Invokers",
   172             "java.lang.invoke.LambdaConversionException",
   173             "java.lang.invoke.LambdaForm",
   174             "java.lang.invoke.LambdaMetafactory",
   175             "java.lang.invoke.MagicLambdaImpl",
   176             "java.lang.invoke.MemberName",
   177             "java.lang.invoke.MethodHandle",
   178             "java.lang.invoke.MethodHandleImpl",
   179             "java.lang.invoke.MethodHandleInfo",
   180             "java.lang.invoke.MethodHandleNatives",
   181             "java.lang.invoke.MethodHandleProxies",
   182             "java.lang.invoke.MethodHandles",
   183             "java.lang.invoke.MethodHandleStatics",
   184             "java.lang.invoke.MethodType",
   185             "java.lang.invoke.MethodTypeForm",
   186             "java.lang.invoke.MutableCallSite",
   187             "java.lang.invoke.SerializedLambda",
   188             "java.lang.invoke.SimpleMethodHandle",
   189             "java.lang.invoke.SwitchPoint",
   190             "java.lang.invoke.TypeConvertingMethodAdapter",
   191             "java.lang.invoke.VolatileCallSite",
   192             "java.lang.invoke.WrongMethodTypeException"
   193     };
   194 }

mercurial