< prev index next >
src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java
Print this page
rev 57943 : 8237878: Improve ModuleLoaderMap datastructures
Reviewed-by: alanb
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -26,18 +26,16 @@
package jdk.internal.module;
import java.lang.module.Configuration;
import java.lang.module.ResolvedModule;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import jdk.internal.loader.ClassLoaders;
-
/**
* Supports the mapping of modules to class loaders. The set of modules mapped
* to the boot and platform class loaders is generated at build time from
* this source file.
*/
@@ -45,68 +43,80 @@
/**
* Maps the system modules to the built-in class loaders.
*/
public static final class Mapper implements Function<String, ClassLoader> {
- private final Map<String, ClassLoader> map;
- Mapper(Map<String, ClassLoader> map) {
- this.map = map; // defensive copy not needed
+ private static final ClassLoader PLATFORM_CLASSLOADER =
+ ClassLoaders.platformClassLoader();
+ private static final ClassLoader APP_CLASSLOADER =
+ ClassLoaders.appClassLoader();
+
+ // Using boxed values allows us to use these as an adhoc enum, while keeping
+ // comparisons in Mapper.apply cheap during bootstrap since we can do
+ // identity comparisons rather than unbox the value. Not storing a reference
+ // to the ClassLoader directly ensures we can archive Mapper instances
+ private static final Integer PLATFORM_LOADER_INDEX = 1;
+ private static final Integer APP_LOADER_INDEX = 2;
+
+ private final HashMap<String, Integer> map;
+
+ Mapper(Configuration cf) {
+ var map = new HashMap<String, Integer>();
+ for (ResolvedModule resolvedModule : cf.modules()) {
+ String mn = resolvedModule.name();
+ if (!Modules.bootModules.contains(mn)) {
+ if (Modules.platformModules.contains(mn)) {
+ map.put(mn, PLATFORM_LOADER_INDEX);
+ } else {
+ map.put(mn, APP_LOADER_INDEX);
+ }
+ }
+ }
+ this.map = map;
}
@Override
public ClassLoader apply(String name) {
- return map.get(name);
+ Integer loader = map.get(name);
+ if (loader == APP_LOADER_INDEX) {
+ return APP_CLASSLOADER;
+ } else if (loader == PLATFORM_LOADER_INDEX) {
+ return PLATFORM_CLASSLOADER;
+ } else { // BOOT_LOADER_INDEX
+ return null;
+ }
}
}
/**
* Returns the names of the modules defined to the boot loader.
*/
public static Set<String> bootModules() {
- // The list of boot modules generated at build time.
- String[] BOOT_MODULES = new String[] { "@@BOOT_MODULE_NAMES@@" };
- Set<String> bootModules = new HashSet<>(BOOT_MODULES.length);
- for (String mn : BOOT_MODULES) {
- bootModules.add(mn);
- }
- return bootModules;
+ return Modules.bootModules;
}
/**
* Returns the names of the modules defined to the platform loader.
*/
public static Set<String> platformModules() {
- // The list of platform modules generated at build time.
- String[] PLATFORM_MODULES = new String[] { "@@PLATFORM_MODULE_NAMES@@" };
- Set<String> platformModules = new HashSet<>(PLATFORM_MODULES.length);
- for (String mn : PLATFORM_MODULES) {
- platformModules.add(mn);
+ return Modules.platformModules;
}
- return platformModules;
+
+ private static class Modules {
+ // list of boot modules is generated at build time.
+ private static final Set<String> bootModules =
+ Set.of(new String[] { "@@BOOT_MODULE_NAMES@@" });
+
+ // list of platform modules is generated at build time.
+ private static final Set<String> platformModules =
+ Set.of(new String[] { "@@PLATFORM_MODULE_NAMES@@" });
}
/**
- * Returns the function to map modules in the given configuration to the
+ * Returns a function to map modules in the given configuration to the
* built-in class loaders.
*/
- static Function<String, ClassLoader> mappingFunction(Configuration cf) {
- Set<String> bootModules = bootModules();
- Set<String> platformModules = platformModules();
-
- ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
- ClassLoader appClassLoader = ClassLoaders.appClassLoader();
-
- Map<String, ClassLoader> map = new HashMap<>();
- for (ResolvedModule resolvedModule : cf.modules()) {
- String mn = resolvedModule.name();
- if (!bootModules.contains(mn)) {
- if (platformModules.contains(mn)) {
- map.put(mn, platformClassLoader);
- } else {
- map.put(mn, appClassLoader);
- }
- }
- }
- return new Mapper(map);
+ static Mapper mappingFunction(Configuration cf) {
+ return new Mapper(cf);
}
}
< prev index next >