From 133a63b4a1a2ef2e4a51fdf9edac073078692f39 Mon Sep 17 00:00:00 2001 From: Aleksei Voitylov Date: Wed, 24 Mar 2021 16:32:36 +0000 Subject: [PATCH] 8263968: CDS: java/lang/ModuleLayer.EMPTY_LAYER should be singleton Reviewed-by: iklam, dholmes, alanb, redestad --- src/hotspot/share/memory/heapShared.cpp | 1 + .../share/classes/java/lang/ModuleLayer.java | 14 +++++++++++--- .../appcds/cacheObject/CheckArchivedModuleApp.java | 10 ++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/memory/heapShared.cpp b/src/hotspot/share/memory/heapShared.cpp index a701c314dd0..d24ec5cbf3c 100644 --- a/src/hotspot/share/memory/heapShared.cpp +++ b/src/hotspot/share/memory/heapShared.cpp @@ -93,6 +93,7 @@ static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = { static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = { {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"}, {"java/util/ImmutableCollections", "archivedObjects"}, + {"java/lang/ModuleLayer", "EMPTY_LAYER"}, {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"}, {"jdk/internal/math/FDBigInteger", "archivedCaches"}, }; diff --git a/src/java.base/share/classes/java/lang/ModuleLayer.java b/src/java.base/share/classes/java/lang/ModuleLayer.java index f74146d74d1..86fde6c7f13 100644 --- a/src/java.base/share/classes/java/lang/ModuleLayer.java +++ b/src/java.base/share/classes/java/lang/ModuleLayer.java @@ -48,6 +48,8 @@ import jdk.internal.loader.ClassLoaderValue; import jdk.internal.loader.Loader; import jdk.internal.loader.LoaderPool; import jdk.internal.module.ServicesCatalog; +import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.Stable; import sun.security.util.SecurityConstants; @@ -147,9 +149,15 @@ import sun.security.util.SecurityConstants; public final class ModuleLayer { - // the empty layer - private static final ModuleLayer EMPTY_LAYER - = new ModuleLayer(Configuration.empty(), List.of(), null); + // the empty layer (may be initialized from the CDS archive) + private static @Stable ModuleLayer EMPTY_LAYER; + static { + CDS.initializeFromArchive(ModuleLayer.class); + if (EMPTY_LAYER == null) { + // create a new empty layer if there is no archived version. + EMPTY_LAYER = new ModuleLayer(Configuration.empty(), List.of(), null); + } + } // the configuration from which this layer was created private final Configuration cf; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java index 63b656666f5..8f17298056e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java @@ -61,6 +61,7 @@ public class CheckArchivedModuleApp { checkModuleDescriptors(expectArchivedDescriptors); checkConfiguration(expectArchivedConfiguration); checkEmptyConfiguration(expectArchivedConfiguration); + checkEmptyLayer(); } private static void checkModuleDescriptors(boolean expectArchivedDescriptors) { @@ -139,4 +140,13 @@ public class CheckArchivedModuleApp { } } } + + private static void checkEmptyLayer() { + // ModuleLayer.EMPTY_FIELD returned by empty() method is singleton. + // Check that with CDS there is still a single instance of EMPTY_LAYER + // and boot() layer parent is THE empty layer. + if (ModuleLayer.empty() != ModuleLayer.boot().parents().get(0)) { + throw new RuntimeException("FAILED. Empty module layer is not singleton"); + } + } }