8136893: Improve early java.lang.invoke infrastructure initialization
authorplevart
Wed, 14 Oct 2015 00:08:42 +0200
changeset 32986 ea54ac8672e7
parent 32985 5f78762b773b
child 32987 e5e5ab01398e
8136893: Improve early java.lang.invoke infrastructure initialization Reviewed-by: mhaupt, psandoz, redestad, vlivanov
jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java
jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java
jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java
jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java
--- 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);
             }