Wed, 22 Jan 2014 12:37:28 -0800
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 | } |