8207263: Store the Configuration for system modules into CDS archive
Archive boot layer Configuration. Reviewed-by: redestad, iklam, ccheung
This commit is contained in:
parent
5858a507f4
commit
a5d14313f5
@ -4250,6 +4250,11 @@ int reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
|
||||
int jdk_internal_module_ArchivedModuleGraph::_archivedSystemModules_offset;
|
||||
int jdk_internal_module_ArchivedModuleGraph::_archivedModuleFinder_offset;
|
||||
int jdk_internal_module_ArchivedModuleGraph::_archivedMainModule_offset;
|
||||
int jdk_internal_module_ArchivedModuleGraph::_archivedConfiguration_offset;
|
||||
int java_lang_module_Configuration::_EMPTY_CONFIGURATION_offset;
|
||||
int java_util_ImmutableCollections_ListN::_EMPTY_LIST_offset;
|
||||
int java_util_ImmutableCollections_SetN::_EMPTY_SET_offset;
|
||||
int java_util_ImmutableCollections_MapN::_EMPTY_MAP_offset;
|
||||
|
||||
#define STACKTRACEELEMENT_FIELDS_DO(macro) \
|
||||
macro(declaringClassObject_offset, k, "declaringClassObject", class_signature, false); \
|
||||
@ -4412,20 +4417,81 @@ static int member_offset(int hardcoded_offset) {
|
||||
return (hardcoded_offset * heapOopSize) + instanceOopDesc::base_offset_in_bytes();
|
||||
}
|
||||
|
||||
#define MODULEBOOTSTRAP_FIELDS_DO(macro) \
|
||||
#define ARCHIVEDMODULEGRAPH_FIELDS_DO(macro) \
|
||||
macro(_archivedSystemModules_offset, k, "archivedSystemModules", systemModules_signature, true); \
|
||||
macro(_archivedModuleFinder_offset, k, "archivedModuleFinder", moduleFinder_signature, true); \
|
||||
macro(_archivedMainModule_offset, k, "archivedMainModule", string_signature, true)
|
||||
macro(_archivedMainModule_offset, k, "archivedMainModule", string_signature, true); \
|
||||
macro(_archivedConfiguration_offset, k, "archivedConfiguration", configuration_signature, true)
|
||||
|
||||
void jdk_internal_module_ArchivedModuleGraph::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::ArchivedModuleGraph_klass();
|
||||
assert(k != NULL, "must be loaded");
|
||||
MODULEBOOTSTRAP_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
ARCHIVEDMODULEGRAPH_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void jdk_internal_module_ArchivedModuleGraph::serialize(SerializeClosure* f) {
|
||||
MODULEBOOTSTRAP_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
|
||||
ARCHIVEDMODULEGRAPH_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CONFIGURATION_FIELDS_DO(macro) \
|
||||
macro(_EMPTY_CONFIGURATION_offset, k, "EMPTY_CONFIGURATION", configuration_signature, true)
|
||||
|
||||
void java_lang_module_Configuration::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::Configuration_klass();
|
||||
assert(k != NULL, "must be loaded");
|
||||
CONFIGURATION_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void java_lang_module_Configuration::serialize(SerializeClosure* f) {
|
||||
CONFIGURATION_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define LISTN_FIELDS_DO(macro) \
|
||||
macro(_EMPTY_LIST_offset, k, "EMPTY_LIST", list_signature, true)
|
||||
|
||||
void java_util_ImmutableCollections_ListN::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::ImmutableCollections_ListN_klass();
|
||||
assert(k != NULL, "must be loaded");
|
||||
LISTN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void java_util_ImmutableCollections_ListN::serialize(SerializeClosure* f) {
|
||||
LISTN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SETN_FIELDS_DO(macro) \
|
||||
macro(_EMPTY_SET_offset, k, "EMPTY_SET", set_signature, true)
|
||||
|
||||
void java_util_ImmutableCollections_SetN::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::ImmutableCollections_SetN_klass();
|
||||
assert(k != NULL, "must be loaded");
|
||||
SETN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void java_util_ImmutableCollections_SetN::serialize(SerializeClosure* f) {
|
||||
SETN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAPN_FIELDS_DO(macro) \
|
||||
macro(_EMPTY_MAP_offset, k, "EMPTY_MAP", map_signature, true)
|
||||
|
||||
void java_util_ImmutableCollections_MapN::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::ImmutableCollections_MapN_klass();
|
||||
assert(k != NULL, "must be loaded");
|
||||
MAPN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void java_util_ImmutableCollections_MapN::serialize(SerializeClosure* f) {
|
||||
MAPN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4487,6 +4553,10 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_LiveStackFrameInfo::compute_offsets();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets();
|
||||
|
||||
java_lang_module_Configuration::compute_offsets();
|
||||
java_util_ImmutableCollections_ListN::compute_offsets();
|
||||
java_util_ImmutableCollections_MapN::compute_offsets();
|
||||
java_util_ImmutableCollections_SetN::compute_offsets();
|
||||
jdk_internal_module_ArchivedModuleGraph::compute_offsets();
|
||||
|
||||
// generated interpreter code wants to know about the offsets we just computed:
|
||||
|
@ -1490,10 +1490,48 @@ class jdk_internal_module_ArchivedModuleGraph: AllStatic {
|
||||
static int _archivedSystemModules_offset;
|
||||
static int _archivedModuleFinder_offset;
|
||||
static int _archivedMainModule_offset;
|
||||
static int _archivedConfiguration_offset;
|
||||
public:
|
||||
static int archivedSystemModules_offset() { return _archivedSystemModules_offset; }
|
||||
static int archivedModuleFinder_offset() { return _archivedModuleFinder_offset; }
|
||||
static int archivedMainModule_offset() { return _archivedMainModule_offset; }
|
||||
static int archivedConfiguration_offset() { return _archivedConfiguration_offset; }
|
||||
static void compute_offsets();
|
||||
static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
|
||||
};
|
||||
|
||||
class java_lang_module_Configuration: AllStatic {
|
||||
private:
|
||||
static int _EMPTY_CONFIGURATION_offset;
|
||||
public:
|
||||
static int EMPTY_CONFIGURATION_offset() { return _EMPTY_CONFIGURATION_offset; }
|
||||
static void compute_offsets();
|
||||
static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
|
||||
};
|
||||
|
||||
class java_util_ImmutableCollections_ListN : AllStatic {
|
||||
private:
|
||||
static int _EMPTY_LIST_offset;
|
||||
public:
|
||||
static int EMPTY_LIST_offset() { return _EMPTY_LIST_offset; }
|
||||
static void compute_offsets();
|
||||
static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
|
||||
};
|
||||
|
||||
class java_util_ImmutableCollections_SetN : AllStatic {
|
||||
private:
|
||||
static int _EMPTY_SET_offset;
|
||||
public:
|
||||
static int EMPTY_SET_offset() { return _EMPTY_SET_offset; }
|
||||
static void compute_offsets();
|
||||
static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
|
||||
};
|
||||
|
||||
class java_util_ImmutableCollections_MapN : AllStatic {
|
||||
private:
|
||||
static int _EMPTY_MAP_offset;
|
||||
public:
|
||||
static int EMPTY_MAP_offset() { return _EMPTY_MAP_offset; }
|
||||
static void compute_offsets();
|
||||
static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
|
||||
};
|
||||
|
@ -187,6 +187,10 @@ class OopStorage;
|
||||
do_klass(jdk_internal_loader_ClassLoaders_AppClassLoader_klass, jdk_internal_loader_ClassLoaders_AppClassLoader, Pre ) \
|
||||
do_klass(jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass, jdk_internal_loader_ClassLoaders_PlatformClassLoader, Pre ) \
|
||||
do_klass(CodeSource_klass, java_security_CodeSource, Pre ) \
|
||||
do_klass(Configuration_klass, java_lang_module_Configuration, Pre ) \
|
||||
do_klass(ImmutableCollections_ListN_klass, java_util_ImmutableCollections_ListN, Pre ) \
|
||||
do_klass(ImmutableCollections_MapN_klass, java_util_ImmutableCollections_MapN, Pre ) \
|
||||
do_klass(ImmutableCollections_SetN_klass, java_util_ImmutableCollections_SetN, Pre ) \
|
||||
do_klass(ArchivedModuleGraph_klass, jdk_internal_module_ArchivedModuleGraph, Pre ) \
|
||||
\
|
||||
do_klass(StackTraceElement_klass, java_lang_StackTraceElement, Opt ) \
|
||||
|
@ -648,13 +648,20 @@
|
||||
JFR_TEMPLATES(template) \
|
||||
\
|
||||
/* cds */ \
|
||||
template(configuration_signature, "Ljava/lang/module/Configuration;") \
|
||||
template(java_lang_module_Configuration, "java/lang/module/Configuration") \
|
||||
template(java_util_ImmutableCollections_ListN, "java/util/ImmutableCollections$ListN") \
|
||||
template(java_util_ImmutableCollections_MapN, "java/util/ImmutableCollections$MapN") \
|
||||
template(java_util_ImmutableCollections_SetN, "java/util/ImmutableCollections$SetN") \
|
||||
template(jdk_internal_loader_ClassLoaders, "jdk/internal/loader/ClassLoaders") \
|
||||
template(jdk_vm_cds_SharedClassInfo, "jdk/vm/cds/SharedClassInfo") \
|
||||
template(url_void_signature, "(Ljava/net/URL;)V") \
|
||||
template(list_signature, "Ljava/util/List;") \
|
||||
template(map_signature, "Ljava/util/Map;") \
|
||||
template(moduleFinder_signature, "Ljava/lang/module/ModuleFinder;") \
|
||||
template(set_signature, "Ljava/util/Set;") \
|
||||
template(systemModules_signature, "Ljdk/internal/module/SystemModules;") \
|
||||
template(toFileURL_name, "toFileURL") \
|
||||
template(toFileURL_signature, "(Ljava/lang/String;)Ljava/net/URL;") \
|
||||
template(moduleFinder_signature, "Ljava/lang/module/ModuleFinder;") \
|
||||
template(systemModules_signature, "Ljdk/internal/module/SystemModules;") \
|
||||
template(url_void_signature, "(Ljava/net/URL;)V") \
|
||||
\
|
||||
/*end*/
|
||||
|
||||
|
@ -104,6 +104,13 @@ void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k, Klass *relocate
|
||||
}
|
||||
|
||||
assert(relocated_k->is_shared(), "must be a shared class");
|
||||
|
||||
if (_k == relocated_k) {
|
||||
// Don't add the Klass containing the sub-graph to it's own klass
|
||||
// initialization list.
|
||||
return;
|
||||
}
|
||||
|
||||
if (relocated_k->is_instance_klass()) {
|
||||
assert(InstanceKlass::cast(relocated_k)->is_shared_boot_class(),
|
||||
"must be boot class");
|
||||
@ -498,7 +505,12 @@ void HeapShared::archive_reachable_objects_from_static_field(Klass *k,
|
||||
#define do_module_object_graph(archive_object_graph_do) \
|
||||
archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedSystemModules_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedModuleFinder_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK)
|
||||
archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedConfiguration_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::ImmutableCollections_ListN_klass(), java_util_ImmutableCollections_ListN::EMPTY_LIST_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::ImmutableCollections_MapN_klass(), java_util_ImmutableCollections_MapN::EMPTY_MAP_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::ImmutableCollections_SetN_klass(), java_util_ImmutableCollections_SetN::EMPTY_SET_offset(), T_OBJECT, CHECK); \
|
||||
archive_object_graph_do(SystemDictionary::Configuration_klass(), java_lang_module_Configuration::EMPTY_CONFIGURATION_offset(), T_OBJECT, CHECK)
|
||||
|
||||
void HeapShared::archive_module_graph_objects(Thread* THREAD) {
|
||||
do_module_object_graph(archive_reachable_objects_from_static_field);
|
||||
|
@ -438,6 +438,7 @@ void MetaspaceShared::serialize_well_known_classes(SerializeClosure* soc) {
|
||||
java_lang_Thread::serialize(soc);
|
||||
java_lang_ThreadGroup::serialize(soc);
|
||||
java_lang_AssertionStatusDirectives::serialize(soc);
|
||||
java_lang_module_Configuration::serialize(soc);
|
||||
java_lang_ref_SoftReference::serialize(soc);
|
||||
java_lang_invoke_MethodHandle::serialize(soc);
|
||||
java_lang_invoke_DirectMethodHandle::serialize(soc);
|
||||
@ -461,6 +462,9 @@ void MetaspaceShared::serialize_well_known_classes(SerializeClosure* soc) {
|
||||
java_lang_StackFrameInfo::serialize(soc);
|
||||
java_lang_LiveStackFrameInfo::serialize(soc);
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::serialize(soc);
|
||||
java_util_ImmutableCollections_ListN::serialize(soc);
|
||||
java_util_ImmutableCollections_MapN::serialize(soc);
|
||||
java_util_ImmutableCollections_SetN::serialize(soc);
|
||||
jdk_internal_module_ArchivedModuleGraph::serialize(soc);
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,10 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.module.ModuleReferenceImpl;
|
||||
import jdk.internal.module.ModuleTarget;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
/**
|
||||
* A configuration that is the result of <a href="package-summary.html#resolution">
|
||||
@ -103,7 +105,17 @@ import jdk.internal.module.ModuleTarget;
|
||||
public final class Configuration {
|
||||
|
||||
// @see Configuration#empty()
|
||||
private static final Configuration EMPTY_CONFIGURATION = new Configuration();
|
||||
// EMPTY_CONFIGURATION may be initialized from the CDS archive.
|
||||
private static @Stable Configuration EMPTY_CONFIGURATION;
|
||||
|
||||
static {
|
||||
// Initialize EMPTY_CONFIGURATION from the archive.
|
||||
VM.initializeFromArchive(Configuration.class);
|
||||
// Create a new empty Configuration if there is no archived version.
|
||||
if (EMPTY_CONFIGURATION == null) {
|
||||
EMPTY_CONFIGURATION = new Configuration();
|
||||
}
|
||||
}
|
||||
|
||||
// parent configurations, in search order
|
||||
private final List<Configuration> parents;
|
||||
|
@ -36,6 +36,7 @@ import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
/**
|
||||
@ -409,7 +410,15 @@ class ImmutableCollections {
|
||||
static final class ListN<E> extends AbstractImmutableList<E>
|
||||
implements Serializable {
|
||||
|
||||
static final List<?> EMPTY_LIST = new ListN<>();
|
||||
// EMPTY_LIST may be initialized from the CDS archive.
|
||||
static @Stable List<?> EMPTY_LIST;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(ListN.class);
|
||||
if (EMPTY_LIST == null) {
|
||||
EMPTY_LIST = new ListN<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
private final E[] elements;
|
||||
@ -567,7 +576,15 @@ class ImmutableCollections {
|
||||
static final class SetN<E> extends AbstractImmutableSet<E>
|
||||
implements Serializable {
|
||||
|
||||
static final Set<?> EMPTY_SET = new SetN<>();
|
||||
// EMPTY_SET may be initialized from the CDS archive.
|
||||
static @Stable Set<?> EMPTY_SET;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(SetN.class);
|
||||
if (EMPTY_SET == null) {
|
||||
EMPTY_SET = new SetN<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
final E[] elements;
|
||||
@ -772,7 +789,15 @@ class ImmutableCollections {
|
||||
*/
|
||||
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
|
||||
|
||||
static final Map<?,?> EMPTY_MAP = new MapN<>();
|
||||
// EMPTY_MAP may be initialized from the CDS archive.
|
||||
static @Stable Map<?,?> EMPTY_MAP;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(MapN.class);
|
||||
if (EMPTY_MAP == null) {
|
||||
EMPTY_MAP = new MapN<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
final Object[] table; // pairs of key, value
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.misc.VM;
|
||||
@ -36,13 +37,18 @@ final class ArchivedModuleGraph {
|
||||
private static String archivedMainModule;
|
||||
private static SystemModules archivedSystemModules;
|
||||
private static ModuleFinder archivedModuleFinder;
|
||||
private static Configuration archivedConfiguration;
|
||||
|
||||
private final SystemModules systemModules;
|
||||
private final ModuleFinder finder;
|
||||
private final Configuration configuration;
|
||||
|
||||
private ArchivedModuleGraph(SystemModules modules, ModuleFinder finder) {
|
||||
private ArchivedModuleGraph(SystemModules modules,
|
||||
ModuleFinder finder,
|
||||
Configuration configuration) {
|
||||
this.systemModules = modules;
|
||||
this.finder = finder;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
SystemModules systemModules() {
|
||||
@ -53,27 +59,36 @@ final class ArchivedModuleGraph {
|
||||
return finder;
|
||||
}
|
||||
|
||||
Configuration configuration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
// A factory method that ModuleBootstrap can use to obtain the
|
||||
// ArchivedModuleGraph.
|
||||
static ArchivedModuleGraph get(String mainModule) {
|
||||
if (Objects.equals(mainModule, archivedMainModule)
|
||||
&& archivedSystemModules != null
|
||||
&& archivedModuleFinder != null) {
|
||||
&& archivedModuleFinder != null
|
||||
&& archivedConfiguration != null) {
|
||||
return new ArchivedModuleGraph(archivedSystemModules,
|
||||
archivedModuleFinder);
|
||||
archivedModuleFinder,
|
||||
archivedConfiguration);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Used at CDS dump time
|
||||
static void archive(String mainModule, SystemModules systemModules,
|
||||
ModuleFinder finder) {
|
||||
static void archive(String mainModule,
|
||||
SystemModules systemModules,
|
||||
ModuleFinder finder,
|
||||
Configuration configuration) {
|
||||
if (archivedMainModule != null)
|
||||
throw new UnsupportedOperationException();
|
||||
archivedMainModule = mainModule;
|
||||
archivedSystemModules = systemModules;
|
||||
archivedModuleFinder = finder;
|
||||
archivedConfiguration = configuration;
|
||||
}
|
||||
|
||||
static {
|
||||
|
@ -172,6 +172,7 @@ public final class ModuleBootstrap {
|
||||
|
||||
boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
|
||||
boolean needResolution = true;
|
||||
boolean canArchive = false;
|
||||
|
||||
// If the java heap was archived at CDS dump time and the environment
|
||||
// at dump time matches the current environment then use the archived
|
||||
@ -186,7 +187,6 @@ public final class ModuleBootstrap {
|
||||
systemModuleFinder = archivedModuleGraph.finder();
|
||||
needResolution = (traceOutput != null);
|
||||
} else {
|
||||
boolean canArchive = false;
|
||||
if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
|
||||
systemModules = SystemModuleFinders.systemModules(mainModule);
|
||||
if (systemModules != null && !isPatched) {
|
||||
@ -206,12 +206,6 @@ public final class ModuleBootstrap {
|
||||
systemModules = new ExplodedSystemModules();
|
||||
systemModuleFinder = SystemModuleFinders.ofSystem();
|
||||
}
|
||||
|
||||
// Module graph can be archived at CDS dump time. Only allow the
|
||||
// unnamed module case for now.
|
||||
if (canArchive && (mainModule == null)) {
|
||||
ArchivedModuleGraph.archive(mainModule, systemModules, systemModuleFinder);
|
||||
}
|
||||
}
|
||||
|
||||
Counters.add("jdk.module.boot.1.systemModulesTime", t1);
|
||||
@ -353,8 +347,12 @@ public final class ModuleBootstrap {
|
||||
if (needResolution) {
|
||||
cf = JLMA.resolveAndBind(finder, roots, traceOutput);
|
||||
} else {
|
||||
Map<String, Set<String>> map = systemModules.moduleReads();
|
||||
cf = JLMA.newConfiguration(systemModuleFinder, map);
|
||||
if (archivedModuleGraph != null) {
|
||||
cf = archivedModuleGraph.configuration();
|
||||
} else {
|
||||
Map<String, Set<String>> map = systemModules.moduleReads();
|
||||
cf = JLMA.newConfiguration(systemModuleFinder, map);
|
||||
}
|
||||
}
|
||||
|
||||
// check that modules specified to --patch-module are resolved
|
||||
@ -436,6 +434,13 @@ public final class ModuleBootstrap {
|
||||
limitedFinder = new SafeModuleFinder(finder);
|
||||
}
|
||||
|
||||
// Module graph can be archived at CDS dump time. Only allow the
|
||||
// unnamed module case for now.
|
||||
if (canArchive && (mainModule == null)) {
|
||||
ArchivedModuleGraph.archive(mainModule, systemModules,
|
||||
systemModuleFinder, cf);
|
||||
}
|
||||
|
||||
// total time to initialize
|
||||
Counters.add("jdk.module.boot.totalTime", t0);
|
||||
Counters.publish();
|
||||
|
@ -54,41 +54,49 @@ public class ArchivedModuleComboTest {
|
||||
Path userDir = Paths.get(System.getProperty("user.dir"));
|
||||
Path moduleDir = Files.createTempDirectory(userDir, "mods");
|
||||
|
||||
// Dump without --module-path
|
||||
//
|
||||
// Dump without --module-path, without --show-module-resolution
|
||||
//
|
||||
OutputAnalyzer output = TestCommon.dump(appJar,
|
||||
TestCommon.list("CheckArchivedModuleApp"),
|
||||
use_whitebox_jar);
|
||||
TestCommon.checkDump(output);
|
||||
|
||||
// Test case 1)
|
||||
// - Dump without --module-path
|
||||
// - Run from -cp only, archived boot layer module ModuleDescriptors
|
||||
// should be used.
|
||||
// - Dump without --module-path, without --show-module-resolution
|
||||
// - Run from -cp only and without --show-module-resolution
|
||||
// + archived boot layer module ModuleDescriptors should be used
|
||||
// + archived boot layer configuration should be used
|
||||
System.out.println("----------------------- Test case 1 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"yes",
|
||||
"yes");
|
||||
TestCommon.checkExec(output);
|
||||
|
||||
// Test case 2)
|
||||
// - Dump without --module-path
|
||||
// - Run from -cp only, archived boot layer module ModuleDescriptors
|
||||
// should be used with --show-module-resolution (requires resolution).
|
||||
// - Dump without --module-path, without --show-module-resolution
|
||||
// - Run from -cp only and with --show-module-resolution
|
||||
// + archived boot layer module ModuleDescriptors should be used with
|
||||
// --show-module-resolution (requires resolution)
|
||||
// + archived boot layer Configuration should not be disabled
|
||||
System.out.println("----------------------- Test case 2 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"--show-module-resolution",
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"yes");
|
||||
TestCommon.checkExec(output);
|
||||
"yes",
|
||||
"no");
|
||||
TestCommon.checkExec(output, "root java.base jrt:/java.base");
|
||||
|
||||
// Test case 3)
|
||||
// - Dump without --module-path
|
||||
// - Run with --module-path, archived boot layer module ModuleDescriptors
|
||||
// should be disabled.
|
||||
// - Dump without --module-path, without --show-module-resolution
|
||||
// - Run with --module-path
|
||||
// + archived boot layer module ModuleDescriptors should be disabled
|
||||
// + archived boot layer Configuration should be disabled
|
||||
System.out.println("----------------------- Test case 3 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"--module-path",
|
||||
@ -96,12 +104,15 @@ public class ArchivedModuleComboTest {
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"no",
|
||||
"no");
|
||||
TestCommon.checkExec(output);
|
||||
|
||||
//
|
||||
// Dump with --module-path specified (test case 4, 5). Use an
|
||||
// empty directory as it's simple and still triggers the case
|
||||
// where system module objects are not archived.
|
||||
//
|
||||
output = TestCommon.dump(appJar,
|
||||
TestCommon.list("CheckArchivedModuleApp"),
|
||||
"--module-path",
|
||||
@ -112,19 +123,20 @@ public class ArchivedModuleComboTest {
|
||||
// Test case 4)
|
||||
// - Dump with --module-path
|
||||
// - Run from -cp only, no archived boot layer module ModuleDescriptors
|
||||
// should be found.
|
||||
// and Configuration should be found.
|
||||
System.out.println("----------------------- Test case 4 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"no",
|
||||
"no");
|
||||
TestCommon.checkExec(output);
|
||||
|
||||
// Test case 5)
|
||||
// - Dump with --module-path
|
||||
// - Run with --module-path, no archived boot layer module ModuleDescriptors
|
||||
// should be found.
|
||||
// and Configuration should be found.
|
||||
System.out.println("----------------------- Test case 5 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"--module-path",
|
||||
@ -132,7 +144,47 @@ public class ArchivedModuleComboTest {
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"no",
|
||||
"no");
|
||||
TestCommon.checkExec(output);
|
||||
|
||||
//
|
||||
// Dump without --module-path, with --show-module-resolution
|
||||
//
|
||||
output = TestCommon.dump(appJar,
|
||||
TestCommon.list("CheckArchivedModuleApp"),
|
||||
"--show-module-resolution",
|
||||
use_whitebox_jar);
|
||||
TestCommon.checkDump(output, "root java.base jrt:/java.base");
|
||||
|
||||
// Test case 6)
|
||||
// - Dump without --module-path, with --show-module-resolution
|
||||
// - Run from -cp only and without --show-module-resolution
|
||||
// + archived boot layer module ModuleDescriptors should be used
|
||||
// + archived boot layer Configuration should be used
|
||||
System.out.println("----------------------- Test case 6 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"yes",
|
||||
"yes");
|
||||
TestCommon.checkExec(output);
|
||||
|
||||
// Test case 7)
|
||||
// - Dump without --module-path, with --show-module-resolution
|
||||
// - Run from -cp only and with --show-module-resolution
|
||||
// + archived boot layer module ModuleDescriptors should be used with
|
||||
// --show-module-resolution (requires resolution)
|
||||
// + archived boot layer Configuration should be disabled
|
||||
System.out.println("----------------------- Test case 7 ----------------------");
|
||||
output = TestCommon.exec(appJar, use_whitebox_jar,
|
||||
"--show-module-resolution",
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"yes",
|
||||
"no");
|
||||
TestCommon.checkExec(output, "root java.base jrt:/java.base");
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +130,7 @@ public class ArchivedModuleWithCustomImageTest {
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+WhiteBoxAPI",
|
||||
"CheckArchivedModuleApp",
|
||||
"yes",
|
||||
"yes"};
|
||||
printCommand(runCmd);
|
||||
ProcessBuilder pbRun = new ProcessBuilder();
|
||||
|
@ -23,7 +23,9 @@
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
@ -41,16 +43,23 @@ public class CheckArchivedModuleApp {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean expectArchived = "yes".equals(args[0]);
|
||||
checkModuleDescriptors(expectArchived);
|
||||
if (args.length != 2) {
|
||||
throw new RuntimeException(
|
||||
"FAILED. Incorrect argument length: " + args.length);
|
||||
}
|
||||
boolean expectArchivedDescriptors = "yes".equals(args[0]);
|
||||
boolean expectArchivedConfiguration = "yes".equals(args[1]);
|
||||
checkModuleDescriptors(expectArchivedDescriptors);
|
||||
checkConfiguration(expectArchivedConfiguration);
|
||||
checkEmptyConfiguration(expectArchivedConfiguration);
|
||||
}
|
||||
|
||||
private static void checkModuleDescriptors(boolean expectArchived) {
|
||||
private static void checkModuleDescriptors(boolean expectArchivedDescriptors) {
|
||||
Set<Module> modules = ModuleLayer.boot().modules();
|
||||
for (Module m : modules) {
|
||||
ModuleDescriptor md = m.getDescriptor();
|
||||
String name = md.name();
|
||||
if (expectArchived) {
|
||||
if (expectArchivedDescriptors) {
|
||||
if (wb.isShared(md)) {
|
||||
System.out.println(name + " is archived. Expected.");
|
||||
} else {
|
||||
@ -67,4 +76,58 @@ public class CheckArchivedModuleApp {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkEmptyConfiguration(boolean expectArchivedConfiguration) {
|
||||
// Configuration.EMPTY_CONFIGURATION uses the singletons,
|
||||
// ListN.EMPTY_LIST, SetN.EMPTY_SET and MapN.EMPTY_MAP in
|
||||
// ImmutableCollections for the 'parents', 'modules' and
|
||||
// 'graph' fields. The ImmutableCollections singletons
|
||||
// can be accessed via List.of(), Set.of() and Map.of() APIs.
|
||||
// Configuration public APIs also allow access to the
|
||||
// EMPTY_CONFIGURATION's 'parents' and 'modules'. When the
|
||||
// archived java heap data is enabled at runtime, make sure
|
||||
// the EMPTY_CONFIGURATION.parents and EMPTY_CONFIGURATION.modules
|
||||
// are the archived ImmutableCollections singletons.
|
||||
Configuration emptyCf = Configuration.empty();
|
||||
List emptyCfParents = emptyCf.parents();
|
||||
Set emptyCfModules = emptyCf.modules();
|
||||
if (expectArchivedConfiguration) {
|
||||
if (emptyCfParents == List.of() &&
|
||||
wb.isShared(emptyCfParents)) {
|
||||
System.out.println("Empty Configuration has expected parents.");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"FAILED. Unexpected parents for empty Configuration.");
|
||||
}
|
||||
if (emptyCfModules == Set.of() &&
|
||||
wb.isShared(emptyCfModules)) {
|
||||
System.out.println("Empty Configuration has expected module set.");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"FAILED. Unexpected module set for empty Configuration.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void checkConfiguration(boolean expectArchivedConfiguration) {
|
||||
Configuration cf = ModuleLayer.boot().configuration();
|
||||
|
||||
if (expectArchivedConfiguration) {
|
||||
if (wb.isShared(cf)) {
|
||||
System.out.println("Boot layer configuration is archived. Expected.");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"FAILED. Boot layer configuration is not archived.");
|
||||
}
|
||||
} else {
|
||||
if (!wb.isShared(cf)) {
|
||||
System.out.println("Boot layer configuration is not archived. Expected.");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"FAILED. Boot layer configuration is archived.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user