test/compiler/jsr292/ConcurrentClassLoadingTest.java

Wed, 22 Jan 2014 12:37:28 -0800

author
katleman
date
Wed, 22 Jan 2014 12:37:28 -0800
changeset 6575
2bac854670c0
parent 6185
68ec0a75ee22
child 6876
710a3c8b516e
permissions
-rw-r--r--

Added tag jdk8u5-b05 for changeset b90de55aca30

vlivanov@5631 1 /*
vlivanov@5631 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
vlivanov@5631 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
vlivanov@5631 4 *
vlivanov@5631 5 * This code is free software; you can redistribute it and/or modify it
vlivanov@5631 6 * under the terms of the GNU General Public License version 2 only, as
vlivanov@5631 7 * published by the Free Software Foundation.
vlivanov@5631 8 *
vlivanov@5631 9 * This code is distributed in the hope that it will be useful, but WITHOUT
vlivanov@5631 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
vlivanov@5631 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
vlivanov@5631 12 * version 2 for more details (a copy is included in the LICENSE file that
vlivanov@5631 13 * accompanied this code).
vlivanov@5631 14 *
vlivanov@5631 15 * You should have received a copy of the GNU General Public License version
vlivanov@5631 16 * 2 along with this work; if not, write to the Free Software Foundation,
vlivanov@5631 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
vlivanov@5631 18 *
vlivanov@5631 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
vlivanov@5631 20 * or visit www.oracle.com if you need additional information or have any
vlivanov@5631 21 * questions.
vlivanov@5631 22 */
vlivanov@5631 23
vlivanov@5631 24 /**
vlivanov@5631 25 * @test
vlivanov@5631 26 * @bug 8022595
vlivanov@5631 27 * @summary JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives
vlivanov@5631 28 *
vlivanov@5631 29 * @run main/othervm ConcurrentClassLoadingTest
vlivanov@5631 30 */
vlivanov@5631 31 import java.util.*;
vlivanov@5631 32 import java.util.concurrent.BrokenBarrierException;
vlivanov@5631 33 import java.util.concurrent.CyclicBarrier;
vlivanov@5631 34
vlivanov@5631 35 public class ConcurrentClassLoadingTest {
vlivanov@5631 36 int numThreads = 0;
vlivanov@5631 37 long seed = 0;
vlivanov@5631 38 CyclicBarrier l;
vlivanov@5631 39 Random rand;
vlivanov@5631 40
vlivanov@5631 41 public static void main(String[] args) throws Throwable {
vlivanov@5631 42 ConcurrentClassLoadingTest test = new ConcurrentClassLoadingTest();
vlivanov@5631 43 test.parseArgs(args);
vlivanov@5631 44 test.run();
vlivanov@5631 45 }
vlivanov@5631 46
vlivanov@5631 47 void parseArgs(String[] args) {
vlivanov@5631 48 int i = 0;
vlivanov@5631 49 while (i < args.length) {
vlivanov@5631 50 String flag = args[i];
vlivanov@5631 51 switch(flag) {
vlivanov@5631 52 case "-seed":
vlivanov@5631 53 seed = Long.parseLong(args[++i]);
vlivanov@5631 54 break;
vlivanov@5631 55 case "-numThreads":
vlivanov@5631 56 numThreads = Integer.parseInt(args[++i]);
vlivanov@5631 57 break;
vlivanov@5631 58 default:
vlivanov@5631 59 throw new Error("Unknown flag: " + flag);
vlivanov@5631 60 }
vlivanov@5631 61 ++i;
vlivanov@5631 62 }
vlivanov@5631 63 }
vlivanov@5631 64
vlivanov@5631 65 void init() {
vlivanov@5631 66 if (numThreads == 0) {
vlivanov@5631 67 numThreads = Runtime.getRuntime().availableProcessors();
vlivanov@5631 68 }
vlivanov@5631 69
vlivanov@5631 70 if (seed == 0) {
vlivanov@5631 71 seed = (new Random()).nextLong();
vlivanov@5631 72 }
vlivanov@5631 73 rand = new Random(seed);
vlivanov@5631 74
vlivanov@5631 75 l = new CyclicBarrier(numThreads + 1);
vlivanov@5631 76
vlivanov@5631 77 System.out.printf("Threads: %d\n", numThreads);
vlivanov@5631 78 System.out.printf("Seed: %d\n", seed);
vlivanov@5631 79 }
vlivanov@5631 80
vlivanov@5631 81 final List<Loader> loaders = new ArrayList<>();
vlivanov@5631 82
vlivanov@5631 83 void prepare() {
vlivanov@5631 84 List<String> c = new ArrayList<>(Arrays.asList(classNames));
vlivanov@5631 85
vlivanov@5631 86 // Split classes between loading threads
vlivanov@5631 87 int count = (classNames.length / numThreads) + 1;
vlivanov@5631 88 for (int t = 0; t < numThreads; t++) {
vlivanov@5631 89 List<String> sel = new ArrayList<>();
vlivanov@5631 90
vlivanov@5631 91 System.out.printf("Thread #%d:\n", t);
vlivanov@5631 92 for (int i = 0; i < count; i++) {
vlivanov@5631 93 if (c.size() == 0) break;
vlivanov@5631 94
vlivanov@5631 95 int k = rand.nextInt(c.size());
vlivanov@5631 96 String elem = c.remove(k);
vlivanov@5631 97 sel.add(elem);
vlivanov@5631 98 System.out.printf("\t%s\n", elem);
vlivanov@5631 99 }
vlivanov@5631 100 loaders.add(new Loader(sel));
vlivanov@5631 101 }
vlivanov@5631 102
vlivanov@5631 103 // Print diagnostic info when the test hangs
vlivanov@5631 104 Runtime.getRuntime().addShutdownHook(new Thread() {
vlivanov@5631 105 public void run() {
vlivanov@5631 106 boolean alive = false;
vlivanov@5631 107 for (Loader l : loaders) {
vlivanov@5631 108 if (!l.isAlive()) continue;
vlivanov@5631 109
vlivanov@5631 110 if (!alive) {
vlivanov@5631 111 System.out.println("Some threads are still alive:");
vlivanov@5631 112 alive = true;
vlivanov@5631 113 }
vlivanov@5631 114
vlivanov@5631 115 System.out.println(l.getName());
vlivanov@5631 116 for (StackTraceElement elem : l.getStackTrace()) {
vlivanov@5631 117 System.out.println("\t"+elem.toString());
vlivanov@5631 118 }
vlivanov@5631 119 }
vlivanov@5631 120 }
vlivanov@5631 121 });
vlivanov@5631 122 }
vlivanov@5631 123
vlivanov@5631 124 public void run() throws Throwable {
vlivanov@5631 125 init();
vlivanov@5631 126 prepare();
vlivanov@5631 127
vlivanov@5631 128 for (Loader loader : loaders) {
vlivanov@5631 129 loader.start();
vlivanov@5631 130 }
vlivanov@5631 131
vlivanov@5631 132 l.await();
vlivanov@5631 133
vlivanov@5631 134 for (Loader loader : loaders) {
vlivanov@5631 135 loader.join();
vlivanov@5631 136 }
vlivanov@5631 137 }
vlivanov@5631 138
vlivanov@5631 139 class Loader extends Thread {
vlivanov@5631 140 List<String> classes;
vlivanov@5631 141
vlivanov@5631 142 public Loader(List<String> classes) {
vlivanov@5631 143 this.classes = classes;
vlivanov@5631 144 setDaemon(true);
vlivanov@5631 145 }
vlivanov@5631 146
vlivanov@5631 147 @Override
vlivanov@5631 148 public void run() {
vlivanov@5631 149 try {
vlivanov@5631 150 l.await();
vlivanov@5631 151
vlivanov@5631 152 for (String name : classes) {
vlivanov@5631 153 Class.forName(name).getName();
vlivanov@5631 154 }
vlivanov@5631 155 } catch (ClassNotFoundException | BrokenBarrierException | InterruptedException e) {
vlivanov@5631 156 throw new Error(e);
vlivanov@5631 157 }
vlivanov@5631 158 }
vlivanov@5631 159 }
vlivanov@5631 160
vlivanov@5631 161 final static String[] classNames = {
vlivanov@5631 162 "java.lang.invoke.CallSite",
vlivanov@5631 163 "java.lang.invoke.ConstantCallSite",
vlivanov@5631 164 "java.lang.invoke.LambdaConversionException",
vlivanov@5631 165 "java.lang.invoke.LambdaMetafactory",
vlivanov@5631 166 "java.lang.invoke.MethodHandle",
vlivanov@5631 167 "java.lang.invoke.MethodHandleInfo",
vlivanov@5631 168 "java.lang.invoke.MethodHandleProxies",
vlivanov@5631 169 "java.lang.invoke.MethodHandles",
vlivanov@5631 170 "java.lang.invoke.MethodType",
vlivanov@5631 171 "java.lang.invoke.MutableCallSite",
vlivanov@5631 172 "java.lang.invoke.SerializedLambda",
vlivanov@5631 173 "java.lang.invoke.SwitchPoint",
vlivanov@5631 174 "java.lang.invoke.VolatileCallSite",
vlivanov@5631 175 "java.lang.invoke.WrongMethodTypeException"
vlivanov@5631 176 };
vlivanov@5631 177 }

mercurial