< prev index next >

src/java.base/share/classes/java/lang/Module.java

Print this page
rev 57859 : 8237484: Improve module system bootstrap
Reviewed-by: alanb

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -130,11 +130,11 @@
 
         boolean isOpen = descriptor.isOpen() || descriptor.isAutomatic();
         Version version = descriptor.version().orElse(null);
         String vs = Objects.toString(version, null);
         String loc = Objects.toString(uri, null);
-        String[] packages = descriptor.packages().toArray(new String[0]);
+        Object[] packages = descriptor.packages().toArray();
         defineModule0(this, isOpen, vs, loc, packages);
     }
 
 
     /**

@@ -1070,58 +1070,71 @@
                                              Function<String, ClassLoader> clf,
                                              ModuleLayer layer)
     {
         boolean isBootLayer = (ModuleLayer.boot() == null);
 
-        int cap = (int)(cf.modules().size() / 0.75f + 1.0f);
+        int numModules = cf.modules().size();
+        int cap = (int)(numModules / 0.75f + 1.0f);
         Map<String, Module> nameToModule = new HashMap<>(cap);
-        Map<String, ClassLoader> nameToLoader = new HashMap<>(cap);
 
-        Set<ClassLoader> loaders = new HashSet<>();
+        // to avoid repeated lookups and reduce iteration overhead, we create
+        // arrays holding correlated information about each module.
+        ResolvedModule[] resolvedModules = new ResolvedModule[numModules];
+        Module[] modules = new Module[numModules];
+        ClassLoader[] classLoaders = new ClassLoader[numModules];
+
+        resolvedModules = cf.modules().toArray(resolvedModules);
+
+        // record that we want to bind the layer to non-boot and non-platform
+        // module loaders as a final step
+        HashSet<ClassLoader> toBindLoaders = new HashSet<>(4);
         boolean hasPlatformModules = false;
 
         // map each module to a class loader
-        for (ResolvedModule resolvedModule : cf.modules()) {
-            String name = resolvedModule.name();
+        ClassLoader pcl = ClassLoaders.platformClassLoader();
+
+        for (int index = 0; index < numModules; index++) {
+            String name = resolvedModules[index].name();
             ClassLoader loader = clf.apply(name);
-            nameToLoader.put(name, loader);
-            if (loader == null || loader == ClassLoaders.platformClassLoader()) {
+
+            if (loader == null || loader == pcl) {
                 if (!(clf instanceof ModuleLoaderMap.Mapper)) {
                     throw new IllegalArgumentException("loader can't be 'null'"
                             + " or the platform class loader");
                 }
                 hasPlatformModules = true;
             } else {
-                loaders.add(loader);
+                toBindLoaders.add(loader);
             }
+
+            classLoaders[index] = loader;
         }
 
         // define each module in the configuration to the VM
-        for (ResolvedModule resolvedModule : cf.modules()) {
-            ModuleReference mref = resolvedModule.reference();
+        for (int index = 0; index < numModules; index++) {
+            ModuleReference mref = resolvedModules[index].reference();
             ModuleDescriptor descriptor = mref.descriptor();
             String name = descriptor.name();
-            ClassLoader loader = nameToLoader.get(name);
+            ClassLoader loader = classLoaders[index];
             Module m;
             if (loader == null && name.equals("java.base")) {
                 // java.base is already defined to the VM
                 m = Object.class.getModule();
             } else {
                 URI uri = mref.location().orElse(null);
                 m = new Module(layer, loader, descriptor, uri);
             }
             nameToModule.put(name, m);
+            modules[index] = m;
         }
 
         // setup readability and exports/opens
-        for (ResolvedModule resolvedModule : cf.modules()) {
+        for (int index = 0; index < numModules; index++) {
+            ResolvedModule resolvedModule = resolvedModules[index];
             ModuleReference mref = resolvedModule.reference();
             ModuleDescriptor descriptor = mref.descriptor();
-
-            String mn = descriptor.name();
-            Module m = nameToModule.get(mn);
-            assert m != null;
+            Module m = modules[index];
 
             // reads
             Set<Module> reads = new HashSet<>();
 
             // name -> source Module when in parent layer

@@ -1169,31 +1182,30 @@
         }
 
         // if there are modules defined to the boot or platform class loaders
         // then register the modules in the class loader's services catalog
         if (hasPlatformModules) {
-            ClassLoader pcl = ClassLoaders.platformClassLoader();
             ServicesCatalog bootCatalog = BootLoader.getServicesCatalog();
             ServicesCatalog pclCatalog = ServicesCatalog.getServicesCatalog(pcl);
-            for (ResolvedModule resolvedModule : cf.modules()) {
+            for (int index = 0; index < numModules; index++) {
+                ResolvedModule resolvedModule = resolvedModules[index];
                 ModuleReference mref = resolvedModule.reference();
                 ModuleDescriptor descriptor = mref.descriptor();
                 if (!descriptor.provides().isEmpty()) {
-                    String name = descriptor.name();
-                    Module m = nameToModule.get(name);
-                    ClassLoader loader = nameToLoader.get(name);
+                    Module m = modules[index];
+                    ClassLoader loader = classLoaders[index];
                     if (loader == null) {
                         bootCatalog.register(m);
                     } else if (loader == pcl) {
                         pclCatalog.register(m);
                     }
                 }
             }
         }
 
         // record that there is a layer with modules defined to the class loader
-        for (ClassLoader loader : loaders) {
+        for (ClassLoader loader : toBindLoaders) {
             layer.bindToLoader(loader);
         }
 
         return nameToModule;
     }

@@ -1618,11 +1630,11 @@
     // JVM_DefineModule
     private static native void defineModule0(Module module,
                                              boolean isOpen,
                                              String version,
                                              String location,
-                                             String[] pns);
+                                             Object[] pns);
 
     // JVM_AddReadsModule
     private static native void addReads0(Module from, Module to);
 
     // JVM_AddModuleExports
< prev index next >