8136893: Improve early java.lang.invoke infrastructure initialization
Reviewed-by: mhaupt, psandoz, redestad, vlivanov
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Mon Oct 12 19:14:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Oct 14 00:08:42 2015 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -834,7 +834,7 @@
static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
try {
- return LOOKUP.findStatic(cbmh, "make", MethodType.fromMethodDescriptorString(makeSignature(types, false), null));
+ return LOOKUP.findStatic(cbmh, "make", MethodType.fromDescriptor(makeSignature(types, false), null));
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
throw newInternalError(e);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Mon Oct 12 19:14:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Wed Oct 14 00:08:42 2015 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -141,7 +141,7 @@
synchronized (this) {
if (type instanceof String) {
String sig = (String) type;
- MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
+ MethodType res = MethodType.fromDescriptor(sig, getClassLoader());
type = res;
} else if (type instanceof Object[]) {
Object[] typeInfo = (Object[]) type;
@@ -206,7 +206,7 @@
synchronized (this) {
if (type instanceof String) {
String sig = (String) type;
- MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
+ MethodType mtype = MethodType.fromDescriptor("()"+sig, getClassLoader());
Class<?> res = mtype.returnType();
type = res;
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Mon Oct 12 19:14:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Oct 14 00:08:42 2015 +0200
@@ -383,7 +383,7 @@
if (type instanceof MethodType)
return (MethodType) type;
else
- return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
+ return MethodType.fromDescriptor((String)type, callerClass.getClassLoader());
}
// Tracing logic:
static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Mon Oct 12 19:14:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Oct 14 00:08:42 2015 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1058,6 +1058,23 @@
public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
throws IllegalArgumentException, TypeNotPresentException
{
+ return fromDescriptor(descriptor,
+ (loader == null) ? ClassLoader.getSystemClassLoader() : loader);
+ }
+
+ /**
+ * Same as {@link #fromMethodDescriptorString(String, ClassLoader)}, but
+ * {@code null} ClassLoader means the bootstrap loader is used here.
+ * <p>
+ * IMPORTANT: This method is preferable for JDK internal use as it more
+ * correctly interprets {@code null} ClassLoader than
+ * {@link #fromMethodDescriptorString(String, ClassLoader)}.
+ * Use of this method also avoids early initialization issues when system
+ * ClassLoader is not initialized yet.
+ */
+ static MethodType fromDescriptor(String descriptor, ClassLoader loader)
+ throws IllegalArgumentException, TypeNotPresentException
+ {
if (!descriptor.startsWith("(") || // also generates NPE if needed
descriptor.indexOf(')') < 0 ||
descriptor.indexOf('.') >= 0)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Mon Oct 12 19:14:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Wed Oct 14 00:08:42 2015 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -131,7 +131,7 @@
}
private static String boxingDescriptor(Wrapper w) {
- return String.format("(%s)L%s;", w.basicTypeChar(), wrapperName(w));
+ return "(" + w.basicTypeChar() + ")L" + wrapperName(w) + ";";
}
private static String unboxingDescriptor(Wrapper w) {
--- a/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Mon Oct 12 19:14:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Wed Oct 14 00:08:42 2015 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,14 +37,20 @@
private BytecodeDescriptor() { } // cannot instantiate
+ /**
+ * @param loader the class loader in which to look up the types (null means
+ * bootstrap class loader)
+ */
public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {
return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);
}
+ /**
+ * @param loader the class loader in which to look up the types (null means
+ * bootstrap class loader)
+ */
static List<Class<?>> parseMethod(String bytecodeSignature,
int start, int end, ClassLoader loader) {
- if (loader == null)
- loader = ClassLoader.getSystemClassLoader();
String str = bytecodeSignature;
int[] i = {start};
ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>();
@@ -71,6 +77,10 @@
throw new IllegalArgumentException("bad signature: "+str+": "+msg);
}
+ /**
+ * @param loader the class loader in which to look up the types (null means
+ * bootstrap class loader)
+ */
private static Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {
if (i[0] == end) return null;
char c = str.charAt(i[0]++);
@@ -80,7 +90,9 @@
i[0] = endc+1;
String name = str.substring(begc, endc).replace('/', '.');
try {
- return loader.loadClass(name);
+ return (loader == null)
+ ? Class.forName(name, false, null)
+ : loader.loadClass(name);
} catch (ClassNotFoundException ex) {
throw new TypeNotPresentException(name, ex);
}