changeset 1715:b1de131a3fed jdk-9+122

8158736: Adapter class loaders can avoid creating named dynamic modules Reviewed-by: hannesw, mhaupt
author sundar
date Mon, 06 Jun 2016 18:45:47 +0530
parents 8f351da4f151
children f295bf2aeab9 64f922ff84bb
files src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
diffstat 4 files changed, 4 insertions(+), 213 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Fri Jun 03 15:05:17 2016 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Mon Jun 06 18:45:47 2016 +0530
@@ -139,11 +139,6 @@
     public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
 
     /**
-     * Permission to create a new Module
-     */
-    public static final String NASHORN_CREATE_MODULE = "nashorn.createModule";
-
-    /**
      * Permission to enable nashorn debug mode.
      */
     public static final String NASHORN_DEBUG_MODE = "nashorn.debugMode";
@@ -1321,22 +1316,6 @@
      * @param loader the class loader of the module
      * @return the new Module
      */
-    public static Module createModule(final ModuleDescriptor descriptor, final ClassLoader loader) {
-        final SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new RuntimePermission(NASHORN_CREATE_MODULE));
-        }
-        return createModuleTrusted(descriptor, loader);
-    }
-
-    /**
-     * Creates a module layer with one module that is defined to the given class
-     * loader.
-     *
-     * @param descriptor the module descriptor for the newly created module
-     * @param loader the class loader of the module
-     * @return the new Module
-     */
     static Module createModuleTrusted(final ModuleDescriptor descriptor, final ClassLoader loader) {
         return createModuleTrusted(Layer.boot(), descriptor, loader);
     }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Fri Jun 03 15:05:17 2016 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Mon Jun 06 18:45:47 2016 +0530
@@ -63,7 +63,6 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.lang.reflect.Module;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -155,9 +154,6 @@
  * implemented securely.
  */
 final class JavaAdapterBytecodeGenerator {
-    private static final Module NASHORN_MODULE = Context.class.getModule();
-    private static final Module JAVA_BASE_MODULE = Object.class.getModule();
-
     // Field names in adapters
     private static final String GLOBAL_FIELD_NAME = "global";
     private static final String DELEGATE_FIELD_NAME = "delegate";
@@ -233,17 +229,6 @@
     private static final String FINALIZER_DELEGATE_NAME = "$$nashornFinalizerDelegate";
     private static final String FINALIZER_DELEGATE_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE);
 
-    // adapter class may need module read-edges from other modules.
-    // We generate a class to add those required module read-edges.
-    // This is the name of the module read edge adder class.
-    static final String MODULES_READ_ADDER_INTERNAL = ADAPTER_PACKAGE_INTERNAL + "$ModulesReadAdder";
-    static final String MODULES_READ_ADDER = MODULES_READ_ADDER_INTERNAL.replace('/', '.');
-    // module add read method
-    static final String MODULES_ADD_READS = "addReads";
-
-    // .class bytes of module add reader class. Lazily generated and cached.
-    private static byte[] MODULES_READ_ADDER_BYRES;
-
     /**
      * Collection of methods we never override: Object.clone(), Object.finalize().
      */
@@ -269,7 +254,6 @@
     private final Set<MethodInfo> methodInfos = new HashSet<>();
     private final boolean autoConvertibleFromFunction;
     private boolean hasExplicitFinalizer = false;
-    private final Set<Module> accessedModules = new HashSet<>();
 
     private final ClassWriter cw;
 
@@ -333,28 +317,13 @@
     }
 
     JavaAdapterClassLoader createAdapterClassLoader() {
-        return new JavaAdapterClassLoader(generatedClassName, cw.toByteArray(), accessedModules);
+        return new JavaAdapterClassLoader(generatedClassName, cw.toByteArray());
     }
 
     boolean isAutoConvertibleFromFunction() {
         return autoConvertibleFromFunction;
     }
 
-    static synchronized byte[] getModulesAddReadsBytes() {
-        if (MODULES_READ_ADDER_BYRES == null) {
-            // lazily generate module read edge adder class
-            MODULES_READ_ADDER_BYRES = generateModulesReadAdderClass();
-        }
-
-        return MODULES_READ_ADDER_BYRES;
-    }
-
-    private void addAccessedModule(Module m) {
-        if (m != null && m != JAVA_BASE_MODULE && m != NASHORN_MODULE) {
-            accessedModules.add(m);
-        }
-    }
-
     private static String getGeneratedClassName(final Class<?> superType, final List<Class<?>> interfaces) {
         // The class we use to primarily name our adapter is either the superclass, or if it is Object (meaning we're
         // just implementing interfaces or extending Object), then the first implemented interface or Object.
@@ -447,14 +416,6 @@
     }
 
     private boolean generateConstructors(final Constructor<?> ctor) {
-        for (final Class<?> pt : ctor.getParameterTypes()) {
-            if (pt.isPrimitive()) continue;
-            final Module ptMod = pt.getModule();
-            if (ptMod != null) {
-                accessedModules.add(ptMod);
-            }
-        }
-
         if(classOverride) {
             // Generate a constructor that just delegates to ctor. This is used with class-level overrides, when we want
             // to create instances without further per-instance overrides.
@@ -1134,8 +1095,6 @@
      */
     private void gatherMethods(final Class<?> type) throws AdaptationException {
         if (Modifier.isPublic(type.getModifiers())) {
-            addAccessedModule(type.getModule());
-
             final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods();
 
             for (final Method typeMethod: typeMethods) {
@@ -1160,16 +1119,6 @@
                         continue;
                     }
 
-                    for (final Class<?> pt : typeMethod.getParameterTypes()) {
-                        if (pt.isPrimitive()) continue;
-                        addAccessedModule(pt.getModule());
-                    }
-
-                    final Class<?> rt = typeMethod.getReturnType();
-                    if (!rt.isPrimitive()) {
-                        addAccessedModule(rt.getModule());
-                    }
-
                     final MethodInfo mi = new MethodInfo(typeMethod);
                     if (Modifier.isFinal(m) || isCallerSensitive(typeMethod)) {
                         finalMethods.add(mi);
@@ -1255,92 +1204,4 @@
     private static Call lookupServiceMethod(final String name, final Class<?> rtype, final Class<?>... ptypes) {
         return staticCallNoLookup(JavaAdapterServices.class, name, rtype, ptypes);
     }
-
-    /*
-     * Generate a class that adds module read edges from adapter module to the
-     * modules of the reference types used by the generated adapter class.
-     */
-    private static byte[] generateModulesReadAdderClass() {
-        final ClassWriter cw = new ClassWriter(0);
-        MethodVisitor mv;
-
-        // make the class package private
-        cw.visit(Opcodes.V1_7, ACC_SUPER | ACC_FINAL, MODULES_READ_ADDER_INTERNAL,
-            null, "java/lang/Object", null);
-
-        // private static final Module MY_MODULE;
-        {
-            FieldVisitor fv = cw.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC,
-                "MY_MODULE", "Ljava/lang/reflect/Module;", null, null);
-            fv.visitEnd();
-        }
-
-        /*
-         * private static void addReads(Module[] modules) {
-         *     for (Module m : mods) {
-         *         MY_MODULE.addRead(m);
-         *     }
-         * }
-         */
-        {
-            mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC,
-                MODULES_ADD_READS,
-                "([Ljava/lang/reflect/Module;)V", null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0);
-            mv.visitVarInsn(ASTORE, 1);
-            mv.visitVarInsn(ALOAD, 1);
-            mv.visitInsn(ARRAYLENGTH);
-            mv.visitVarInsn(ISTORE, 2);
-            mv.visitInsn(ICONST_0);
-            mv.visitVarInsn(ISTORE, 3);
-            Label l0 = new Label();
-            mv.visitLabel(l0);
-            mv.visitFrame(Opcodes.F_APPEND, 3,
-                new Object[]{"[Ljava/lang/reflect/Module;",
-                Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
-            mv.visitVarInsn(ILOAD, 3);
-            mv.visitVarInsn(ILOAD, 2);
-            Label l1 = new Label();
-            mv.visitJumpInsn(IF_ICMPGE, l1);
-            mv.visitVarInsn(ALOAD, 1);
-            mv.visitVarInsn(ILOAD, 3);
-            mv.visitInsn(AALOAD);
-            mv.visitVarInsn(ASTORE, 4);
-            mv.visitFieldInsn(GETSTATIC, MODULES_READ_ADDER_INTERNAL,
-                "MY_MODULE", "Ljava/lang/reflect/Module;");
-            mv.visitVarInsn(ALOAD, 4);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Module",
-                "addReads", "(Ljava/lang/reflect/Module;)Ljava/lang/reflect/Module;", false);
-            mv.visitInsn(POP);
-            mv.visitIincInsn(3, 1);
-            mv.visitJumpInsn(GOTO, l0);
-            mv.visitLabel(l1);
-            mv.visitFrame(Opcodes.F_CHOP, 3, null, 0, null);
-            mv.visitInsn(RETURN);
-            mv.visitMaxs(2, 5);
-            mv.visitEnd();
-        }
-
-        /*
-         * static {
-         *      MY_MODULE = ThisClass.class.getModule();
-         * }
-         */
-        {
-            mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
-            mv.visitCode();
-            mv.visitLdcInsn(Type.getType("L" + MODULES_READ_ADDER_INTERNAL + ";"));
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class",
-                "getModule", "()Ljava/lang/reflect/Module;", false);
-            mv.visitFieldInsn(PUTSTATIC, MODULES_READ_ADDER_INTERNAL,
-                "MY_MODULE", "Ljava/lang/reflect/Module;");
-            mv.visitInsn(RETURN);
-            mv.visitMaxs(1, 0);
-            mv.visitEnd();
-        }
-        cw.visitEnd();
-
-        return cw.toByteArray();
-    }
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Fri Jun 03 15:05:17 2016 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Mon Jun 06 18:45:47 2016 +0530
@@ -25,7 +25,6 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import java.lang.module.ModuleDescriptor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Module;
@@ -58,19 +57,16 @@
 
     private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
     private static final AccessControlContext GET_CONTEXT_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_GET_CONTEXT);
-    private static final AccessControlContext CREATE_MODULE_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_CREATE_MODULE);
 
     private static final Collection<String> VISIBLE_INTERNAL_CLASS_NAMES = Collections.unmodifiableCollection(new HashSet<>(
             Arrays.asList(JavaAdapterServices.class.getName(), ScriptObject.class.getName(), ScriptFunction.class.getName(), JSType.class.getName())));
 
     private final String className;
     private final byte[] classBytes;
-    private final Set<Module> accessedModules;
 
-    JavaAdapterClassLoader(final String className, final byte[] classBytes, final Set<Module> accessedModules) {
+    JavaAdapterClassLoader(final String className, final byte[] classBytes) {
         this.className = className.replace('/', '.');
         this.classBytes = classBytes;
-        this.accessedModules = accessedModules;
     }
 
     /**
@@ -93,21 +89,6 @@
         }, CREATE_LOADER_ACC_CTXT);
     }
 
-    private static Module createAdapterModule(final ClassLoader loader) {
-        final ModuleDescriptor descriptor =
-            new ModuleDescriptor.Builder("jdk.scripting.nashorn.javaadapters")
-                .requires(NASHORN_MODULE.getName())
-                .exports(JavaAdapterBytecodeGenerator.ADAPTER_PACKAGE)
-                .build();
-
-        return AccessController.doPrivileged(new PrivilegedAction<Module>() {
-            @Override
-            public Module run() {
-                return Context.createModule(descriptor, loader);
-            }
-        }, CREATE_MODULE_ACC_CTXT);
-    }
-
     // Note that the adapter class is created in the protection domain of the class/interface being
     // extended/implemented, and only the privileged global setter action class is generated in the protection domain
     // of Nashorn itself. Also note that the creation and loading of the global setter is deferred until it is
@@ -119,39 +100,10 @@
         return new SecureClassLoader(parentLoader) {
             private final ClassLoader myLoader = getClass().getClassLoader();
 
-            // new adapter module
-            private final Module adapterModule = createAdapterModule(this);
+            // the unnamed module into which adapter is loaded!
+            private final Module adapterModule = getUnnamedModule();
 
             {
-                // new adapter module read-edges
-                if (!accessedModules.isEmpty()) {
-
-                    // There are modules accessed from this adapter. We need to add module-read
-                    // edges to those from the adapter module. We do this by generating a
-                    // package-private class, loading it with this adapter class loader and
-                    // then calling a private static method on it.
-                    final byte[] buf = JavaAdapterBytecodeGenerator.getModulesAddReadsBytes();
-                    final Class<?> addReader = defineClass(
-                        JavaAdapterBytecodeGenerator.MODULES_READ_ADDER, buf, 0, buf.length);
-                    final PrivilegedAction<Method> pa = () -> {
-                        try {
-                            final Method m = addReader.getDeclaredMethod(
-                                JavaAdapterBytecodeGenerator.MODULES_ADD_READS, Module[].class);
-                            m.setAccessible(true);
-                            return m;
-                        } catch (final NoSuchMethodException | SecurityException ex) {
-                            throw new RuntimeException(ex);
-                        }
-                    };
-                    final Method addReads = AccessController.doPrivileged(pa);
-                    try {
-                        addReads.invoke(null, (Object)accessedModules.toArray(new Module[0]));
-                    } catch (final IllegalAccessException | IllegalArgumentException |
-                            InvocationTargetException ex) {
-                        throw new RuntimeException(ex);
-                    }
-                }
-
                 // specific exports from nashorn to the new adapter module
                 NASHORN_MODULE.addExports("jdk.nashorn.internal.runtime", adapterModule);
                 NASHORN_MODULE.addExports("jdk.nashorn.internal.runtime.linker", adapterModule);
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Fri Jun 03 15:05:17 2016 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Mon Jun 06 18:45:47 2016 +0530
@@ -380,7 +380,6 @@
     private static ProtectionDomain createMinimalPermissionDomain() {
         // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
         final Permissions permissions = new Permissions();
-        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
         permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
         permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
         return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);