< prev index next >

src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.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

@@ -138,13 +138,13 @@
      *
      * @see java.lang.System#initPhase2(boolean, boolean)
      */
     public static ModuleLayer boot() throws Exception {
 
-        // Step 0: Command line options
+        Counters.start();
 
-        long t0 = System.nanoTime();
+        // Step 0: Command line options
 
         ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
         ModuleFinder appModulePath = finderFor("jdk.module.path");
         boolean isPatched = patcher.hasPatches();
 

@@ -155,19 +155,18 @@
         PrintStream traceOutput = null;
         String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
         if (trace != null && Boolean.parseBoolean(trace))
             traceOutput = System.out;
 
+        Counters.add("jdk.module.boot.0.commandLineTime");
 
         // Step 1: The observable system modules, either all system modules
         // or the system modules pre-generated for the initial module (the
         // initial module may be the unnamed module). If the system modules
         // are pre-generated for the initial module then resolution can be
         // skipped.
 
-        long t1 = System.nanoTime();
-
         SystemModules systemModules = null;
         ModuleFinder systemModuleFinder;
 
         boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
         boolean needResolution = true;

@@ -213,47 +212,40 @@
             hasIncubatorModules = systemModules.hasIncubatorModules();
             // not using the archived module graph - avoid accidental use
             archivedModuleGraph = null;
         }
 
-        Counters.add("jdk.module.boot.1.systemModulesTime", t1);
-
+        Counters.add("jdk.module.boot.1.systemModulesTime");
 
         // Step 2: Define and load java.base. This patches all classes loaded
         // to date so that they are members of java.base. Once java.base is
         // loaded then resources in java.base are available for error messages
         // needed from here on.
 
-        long t2 = System.nanoTime();
-
         ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
         if (base == null)
             throw new InternalError(JAVA_BASE + " not found");
         URI baseUri = base.location().orElse(null);
         if (baseUri == null)
             throw new InternalError(JAVA_BASE + " does not have a location");
         BootLoader.loadModule(base);
         Modules.defineModule(null, base.descriptor(), baseUri);
 
-        Counters.add("jdk.module.boot.2.defineBaseTime", t2);
-
-
         // Step 2a: Scan all modules when --validate-modules specified
 
         if (getAndRemoveProperty("jdk.module.validation") != null) {
             int errors = ModulePathValidator.scanAllModules(System.out);
             if (errors > 0) {
                 fail("Validation of module path failed");
             }
         }
 
+        Counters.add("jdk.module.boot.2.defineBaseTime");
 
         // Step 3: If resolution is needed then create the module finder and
         // the set of root modules to resolve.
 
-        long t3 = System.nanoTime();
-
         ModuleFinder savedModuleFinder = null;
         ModuleFinder finder;
         Set<String> roots;
         if (needResolution) {
 

@@ -339,19 +331,17 @@
             // no resolution case
             finder = systemModuleFinder;
             roots = null;
         }
 
-        Counters.add("jdk.module.boot.3.optionsAndRootsTime", t3);
+        Counters.add("jdk.module.boot.3.optionsAndRootsTime");
 
         // Step 4: Resolve the root modules, with service binding, to create
         // the configuration for the boot layer. If resolution is not needed
         // then create the configuration for the boot layer from the
         // readability graph created at link time.
 
-        long t4 = System.nanoTime();
-
         Configuration cf;
         if (needResolution) {
             cf = Modules.newBootLayerConfiguration(finder, roots, traceOutput);
         } else {
             if (archivedModuleGraph != null) {

@@ -368,22 +358,19 @@
                     .stream()
                     .filter(mn -> !cf.findModule(mn).isPresent())
                     .forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
         }
 
-        Counters.add("jdk.module.boot.4.resolveTime", t4);
-
+        Counters.add("jdk.module.boot.4.resolveTime");
 
         // Step 5: Map the modules in the configuration to class loaders.
         // The static configuration provides the mapping of standard and JDK
         // modules to the boot and platform loaders. All other modules (JDK
         // tool modules, and both explicit and automatic modules on the
         // application module path) are defined to the application class
         // loader.
 
-        long t5 = System.nanoTime();
-
         // mapping of modules to class loaders
         Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
 
         // check that all modules to be mapped to the boot loader will be
         // loaded from the runtime image

@@ -407,30 +394,25 @@
             checkSplitPackages(cf, clf);
         }
 
         // load/register the modules with the built-in class loaders
         loadModules(cf, clf);
-
-        Counters.add("jdk.module.boot.5.loadModulesTime", t5);
-
+        Counters.add("jdk.module.boot.5.loadModulesTime");
 
         // Step 6: Define all modules to the VM
 
-        long t6 = System.nanoTime();
         ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
-        Counters.add("jdk.module.boot.6.layerCreateTime", t6);
-
+        Counters.add("jdk.module.boot.6.layerCreateTime");
 
         // Step 7: Miscellaneous
 
         // check incubating status
         if (hasIncubatorModules || haveModulePath) {
             checkIncubatingStatus(cf);
         }
 
         // --add-reads, --add-exports/--add-opens, and --illegal-access
-        long t7 = System.nanoTime();
         addExtraReads(bootLayer);
         boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
 
         Map<String, Set<String>> concealedPackagesToOpen;
         Map<String, Set<String>> exportedPackagesToOpen;

@@ -444,11 +426,11 @@
         addIllegalAccess(upgradeModulePath,
                          concealedPackagesToOpen,
                          exportedPackagesToOpen,
                          bootLayer,
                          extraExportsOrOpens);
-        Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
+        Counters.add("jdk.module.boot.7.adjustModulesTime");
 
         // save module finders for later use
         if (savedModuleFinder != null) {
             unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
             if (savedModuleFinder != finder)

@@ -466,12 +448,11 @@
                                         concealedPackagesToOpen,
                                         exportedPackagesToOpen);
         }
 
         // total time to initialize
-        Counters.add("jdk.module.boot.totalTime", t0);
-        Counters.publish();
+        Counters.publish("jdk.module.boot.totalTime");
 
         return bootLayer;
     }
 
     /**

@@ -1047,10 +1028,13 @@
      */
     static class Counters {
         private static final boolean PUBLISH_COUNTERS;
         private static final boolean PRINT_COUNTERS;
         private static Map<String, Long> counters;
+        private static long startTime;
+        private static long previousTime;
+
         static {
             String s = System.getProperty("jdk.module.boot.usePerfData");
             if (s == null) {
                 PUBLISH_COUNTERS = false;
                 PRINT_COUNTERS = false;

@@ -1060,30 +1044,47 @@
                 counters = new LinkedHashMap<>();  // preserve insert order
             }
         }
 
         /**
-         * Add a counter
+         * Start counting time.
+         */
+        static void start() {
+            if (PUBLISH_COUNTERS) {
+                startTime = previousTime = System.nanoTime();
+            }
+        }
+
+        /**
+         * Add a counter - storing the time difference between now and the
+         * previous add or the start.
          */
-        static void add(String name, long start) {
-            if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
-                counters.put(name, (System.nanoTime() - start));
+        static void add(String name) {
+            if (PUBLISH_COUNTERS) {
+                long current = System.nanoTime();
+                long elapsed = current - previousTime;
+                previousTime = current;
+                counters.put(name, elapsed);
             }
         }
 
         /**
          * Publish the counters to the instrumentation buffer or stdout.
          */
-        static void publish() {
-            if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
+        static void publish(String totalTimeName) {
+            if (PUBLISH_COUNTERS) {
+                long currentTime = System.nanoTime();
                 for (Map.Entry<String, Long> e : counters.entrySet()) {
                     String name = e.getKey();
                     long value = e.getValue();
-                    if (PUBLISH_COUNTERS)
                         PerfCounter.newPerfCounter(name).set(value);
                     if (PRINT_COUNTERS)
                         System.out.println(name + " = " + value);
                 }
+                long elapsedTotal = currentTime - startTime;
+                PerfCounter.newPerfCounter(totalTimeName).set(elapsedTotal);
+                if (PRINT_COUNTERS)
+                    System.out.println(totalTimeName + " = " + elapsedTotal);
             }
         }
     }
 }
< prev index next >