@@ -132,15 +132,15 @@ public static Resources[] layeredSingletons() {
132132 private final EconomicMap <RequestedPattern , RuntimeConditionSet > requestedPatterns = ImageHeapMap .createNonLayeredMap ();
133133
134134 /**
135- * The string representation of {@link ModuleResourceKey } that are already registered in
136- * previous layers. Since the {@link ModuleResourceKey } contains a reference to a
135+ * The string representation of {@link ModuleNameResourceKey } that are already registered in
136+ * previous layers. Since the {@link ModuleInstanceResourceKey } contains a reference to a
137137 * {@link Module}, the {@link Module} name is used instead of the object itself in the string
138- * representation. This works under the assumption that all modules have a different unique name
139- * in Layered Images. More details can be found in
140- * {@link Resources#getModuleResourceKeyString(ModuleResourceKey)} .
138+ * representation. This works under the assumption (enforced by
139+ * LayeredModuleSingleton.setPackages) that all modules have a different unique name in Layered
140+ * Images .
141141 *
142- * The boolean associated to each {@link ModuleResourceKey } is true if the registered value is
143- * complete and false in the case of a negative query.
142+ * The boolean associated to each {@link ModuleNameResourceKey } is true if the registered value
143+ * is complete and false in the case of a negative query.
144144 */
145145 @ Platforms (Platform .HOSTED_ONLY .class ) //
146146 private final Map <String , Boolean > previousLayerResources ;
@@ -155,7 +155,65 @@ public static Resources[] layeredSingletons() {
155155 public record RequestedPattern (String module , String resource ) {
156156 }
157157
158- public record ModuleResourceKey (Module module , String resource ) {
158+ public interface ModuleResourceKey {
159+ Module getModule ();
160+
161+ String getModuleName ();
162+
163+ Object module ();
164+
165+ String resource ();
166+ }
167+
168+ /**
169+ * In standalone images, the module object is the {@link Module} reference itself.
170+ */
171+ public record ModuleInstanceResourceKey (Module module , String resource ) implements ModuleResourceKey {
172+ public ModuleInstanceResourceKey {
173+ assert !ImageLayerBuildingSupport .buildingImageLayer () : "The ModuleInstanceResourceKey should only be used in standalone images." ;
174+ }
175+
176+ @ Override
177+ public Module getModule () {
178+ return module ;
179+ }
180+
181+ @ Override
182+ public String getModuleName () {
183+ if (module == null ) {
184+ return null ;
185+ }
186+ return module .getName ();
187+ }
188+ }
189+
190+ /**
191+ * In Layered Image, only the module name is stored in the record.
192+ */
193+ public record ModuleNameResourceKey (Object module , String resource ) implements ModuleResourceKey {
194+ public ModuleNameResourceKey {
195+ /*
196+ * A null module in the ModuleResourceKey represents any unnamed module, meaning that
197+ * only one marker (null) is needed for all of them and that if the module is not null,
198+ * it is named (see Resources.createStorageKey). This string representation relies on
199+ * the assumption (enforced by LayeredModuleSingleton.setPackages) that a layered image
200+ * build cannot contain two modules with the same name, so Module#getName() is
201+ * guaranteed to be unique for layered images.
202+ */
203+ assert module == null || module instanceof Module : "The ModuleNameResourceKey constructor should only be called with a Module as first argument" ;
204+ assert ImageLayerBuildingSupport .buildingImageLayer () : "The ModuleNameResourceKey should only be used in layered images." ;
205+ module = (module != null ) ? ((Module ) module ).getName () : module ;
206+ }
207+
208+ @ Override
209+ public Module getModule () {
210+ throw VMError .shouldNotReachHere ("Accessing the module instance of the ModuleResourceKey is not supported in layered images." );
211+ }
212+
213+ @ Override
214+ public String getModuleName () {
215+ return (String ) module ;
216+ }
159217 }
160218
161219 /**
@@ -251,7 +309,7 @@ public static ModuleResourceKey createStorageKey(Module module, String resourceN
251309 m = currentLayer ().hostedToRuntimeModuleMapper .apply (m );
252310 }
253311 }
254- return new ModuleResourceKey (m , resourceName );
312+ return ImageLayerBuildingSupport . buildingImageLayer () ? new ModuleNameResourceKey ( m , resourceName ) : new ModuleInstanceResourceKey (m , resourceName );
255313 }
256314
257315 @ Platforms (Platform .HOSTED_ONLY .class ) //
@@ -262,9 +320,8 @@ public void setHostedToRuntimeModuleMapper(Function<Module, Module> hostedToRunt
262320 @ Platforms (Platform .HOSTED_ONLY .class )
263321 public static Set <String > getIncludedResourcesModules () {
264322 return StreamSupport .stream (currentLayer ().resources .getKeys ().spliterator (), false )
265- .map (ModuleResourceKey ::module )
323+ .map (ModuleResourceKey ::getModuleName )
266324 .filter (Objects ::nonNull )
267- .map (Module ::getName )
268325 .collect (Collectors .toSet ());
269326 }
270327
@@ -282,21 +339,8 @@ private void updateTimeStamp() {
282339 }
283340 }
284341
285- private static String getModuleResourceKeyString (ModuleResourceKey m ) {
286- /*
287- * A null module in the ModuleResourceKey represents any unnamed module, meaning that only
288- * one marker is needed for all of them and that if the module is not null, it is named (see
289- * Resources.createStorageKey). This string representation relies on the assumption that a
290- * layered image build cannot contain two modules with the same name, so Module#getName() is
291- * guaranteed to be unique for layered images.
292- */
293- String moduleName = m .module == null ? LayeredModuleSingleton .ALL_UNNAMED_MODULE_NAME : m .module .getName ();
294- return moduleName + m .resource ;
295- }
296-
297342 private void addResource (ModuleResourceKey key , ConditionalRuntimeValue <ResourceStorageEntryBase > entry ) {
298- String moduleResourceKeyString = getModuleResourceKeyString (key );
299- Boolean previousLayerData = previousLayerResources .get (moduleResourceKeyString );
343+ Boolean previousLayerData = ImageLayerBuildingSupport .buildingImageLayer () ? previousLayerResources .get (key .toString ()) : null ;
300344 if (previousLayerData == null || (!previousLayerData && entry .getValueUnconditionally () != NEGATIVE_QUERY_MARKER )) {
301345 resources .put (key , entry );
302346 }
@@ -721,7 +765,7 @@ public PersistFlags preparePersist(ImageSingletonWriter writer) {
721765
722766 var cursor = resources .getEntries ();
723767 while (cursor .advance ()) {
724- resourceKeys .add (getModuleResourceKeyString ( cursor .getKey ()));
768+ resourceKeys .add (cursor .getKey (). toString ( ));
725769 boolean isNegativeQuery = cursor .getValue ().getValueUnconditionally () == NEGATIVE_QUERY_MARKER ;
726770 resourceRegistrationStates .add (!isNegativeQuery );
727771 }
0 commit comments