Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ public void duringSetup(DuringSetupAccess access) {
RuntimeClassInitialization.initializeAtBuildTime("com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$IdentityMapping");
RuntimeClassInitialization.initializeAtBuildTime("com.sun.jmx.mbeanserver.DescriptorCache");
RuntimeClassInitialization.initializeAtBuildTime("com.sun.jmx.remote.util.ClassLogger");

RuntimeClassInitialization.initializeAtRunTime("sun.management.MemoryImpl");
RuntimeClassInitialization.initializeAtRunTime("com.sun.management.internal.PlatformMBeanProviderImpl");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
import com.oracle.svm.hosted.config.HybridLayout;
import com.oracle.svm.hosted.image.NativeImageHeap.ObjectInfo;
import com.oracle.svm.hosted.imagelayer.CrossLayerConstantRegistryFeature;
import com.oracle.svm.hosted.imagelayer.LayeredDispatchTableFeature;
import com.oracle.svm.hosted.imagelayer.LayeredImageHooks;
import com.oracle.svm.hosted.meta.HostedClass;
import com.oracle.svm.hosted.meta.HostedField;
import com.oracle.svm.hosted.meta.HostedInstanceClass;
Expand Down Expand Up @@ -431,7 +431,7 @@ private void writeObject(ObjectInfo info, RelocatableBuffer buffer) {
instanceFields = instanceFields.filter(field -> !dynamicHubLayout.isIgnoredField(field));

if (imageLayer) {
LayeredDispatchTableFeature.singleton().registerWrittenDynamicHub((DynamicHub) info.getObject(), heap.aUniverse, heap.hUniverse, vTable);
LayeredImageHooks.processWrittenDynamicHub(new LayeredImageHooks.WrittenDynamicHubInfo((DynamicHub) info.getObject(), heap.aUniverse, heap.hUniverse, vTable));
}

} else if (heap.getHybridLayout(clazz) != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,12 @@
import com.oracle.graal.pointsto.infrastructure.OriginalMethodProvider;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.objectfile.ObjectFile;
import com.oracle.svm.core.InvalidMethodPointerHandler;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.graal.snippets.OpenTypeWorldDispatchTableSnippets;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.layeredimagesingleton.FeatureSingleton;
import com.oracle.svm.core.meta.MethodPointer;
Expand All @@ -67,7 +65,6 @@
import com.oracle.svm.hosted.meta.HostedMetaAccess;
import com.oracle.svm.hosted.meta.HostedMethod;
import com.oracle.svm.hosted.meta.HostedType;
import com.oracle.svm.hosted.meta.HostedUniverse;
import com.oracle.svm.hosted.meta.VTableBuilder;

import jdk.graal.compiler.code.CompilationResult;
Expand Down Expand Up @@ -133,6 +130,7 @@ public void beforeAnalysis(Feature.BeforeAnalysisAccess access) {
config.registerAsRoot(aMethod, false, "in prior layer dispatch table");
});
}
LayeredImageHooks.registerDynamicHubWrittenCallback(this::onDynamicHubWritten);
}

@Override
Expand Down Expand Up @@ -395,12 +393,13 @@ private static void compareTypeInfo(HostedDispatchTable curInfo, PriorDispatchTa
/*
* Recording a hub was written to the heap
*/
public void registerWrittenDynamicHub(DynamicHub hub, AnalysisUniverse aUniverse, HostedUniverse hUniverse, Object vTable) {
AnalysisType aType = ((SVMHost) aUniverse.hostVM()).lookupType(hub);
HostedType hType = hUniverse.lookup(aType);
public void onDynamicHubWritten(LayeredImageHooks.WrittenDynamicHubInfo hubInfo) {
AnalysisType aType = ((SVMHost) hubInfo.aUniverse().hostVM()).lookupType(hubInfo.hub());
HostedType hType = hubInfo.hUniverse().lookup(aType);

assert hType.getWrapped().isReachable() : "All installed hubs should be reachable " + hType;

Object vTable = hubInfo.vTable();
int vtableLength = Array.getLength(vTable);
if (VTableBuilder.hasEmptyDispatchTable(hType)) {
assert vtableLength == 0 : hType;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2025, 2025, 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
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.hosted.imagelayer;

import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.Feature;

import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.imagelayer.BuildingInitialLayerPredicate;
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.layeredimagesingleton.FeatureSingleton;
import com.oracle.svm.core.layeredimagesingleton.ImageSingletonLoader;
import com.oracle.svm.core.layeredimagesingleton.ImageSingletonWriter;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
import com.oracle.svm.hosted.FeatureImpl;
import com.oracle.svm.hosted.meta.HostedType;
import com.oracle.svm.util.LogUtils;

import jdk.graal.compiler.debug.Assertions;

/**
* Tracks information about {@link DynamicHub} which should be consistent across builds.
*/
@AutomaticallyRegisteredFeature
public class LayeredDynamicHubFeature implements InternalFeature, FeatureSingleton {

@Override
public boolean isInConfiguration(Feature.IsInConfigurationAccess access) {
return ImageLayerBuildingSupport.buildingImageLayer();
}

@Override
public void duringSetup(DuringSetupAccess access) {
if (ImageLayerBuildingSupport.buildingSharedLayer()) {
LayeredImageHooks.registerDynamicHubWrittenCallback(this::onDynamicHubWritten);
}
}

void onDynamicHubWritten(LayeredImageHooks.WrittenDynamicHubInfo info) {
DynamicHub hub = info.hub();
if (hub.getArrayHub() == null) {
DynamicHubMetadataTracking.singleton().recordMissingArrayHub(hub);
}
}

@Override
public void beforeCompilation(BeforeCompilationAccess access) {
if (ImageLayerBuildingSupport.buildingApplicationLayer()) {
/*
* Scan all DynamicHubs to see if new missing array hubs have been installed. Currently
* we must wait to do this until after typeIDs have been assigned.
*/
DynamicHubMetadataTracking tracking = DynamicHubMetadataTracking.singleton();
FeatureImpl.BeforeCompilationAccessImpl config = (FeatureImpl.BeforeCompilationAccessImpl) access;
config.getUniverse().getTypes().stream().filter(tracking::missingArrayHub).forEach(hType -> {
if (hType.getHub().getArrayHub() != null) {
var missingArrayName = hType.getHub().getArrayHub().getName();
String message = String.format("New array type seen in application layer which was not installed within the dynamic hub.%nHub: %s%nArrayType: %s", hType.getHub().getName(),
missingArrayName);
LogUtils.warning(message);
}
});
}
}
}

@AutomaticallyRegisteredImageSingleton(onlyWith = BuildingInitialLayerPredicate.class)
class DynamicHubMetadataTracking implements LayeredImageSingleton {
private final Set<Integer> typeIDsWithMissingHubs;

DynamicHubMetadataTracking() {
this.typeIDsWithMissingHubs = ConcurrentHashMap.newKeySet();
}

DynamicHubMetadataTracking(Set<Integer> missingHubSet) {
this.typeIDsWithMissingHubs = missingHubSet;
}

static DynamicHubMetadataTracking singleton() {
return ImageSingletons.lookup(DynamicHubMetadataTracking.class);
}

boolean missingArrayHub(HostedType hType) {
return typeIDsWithMissingHubs.contains(hType.getTypeID());
}

void recordMissingArrayHub(DynamicHub hub) {
var added = typeIDsWithMissingHubs.add(hub.getTypeID());
assert added : Assertions.errorMessage("type recorded twice:", hub);
}

@Override
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
return LayeredImageSingletonBuilderFlags.BUILDTIME_ACCESS_ONLY;
}

@Override
public PersistFlags preparePersist(ImageSingletonWriter writer) {
writer.writeIntList("typeIDsWithMissingArrayHubs", typeIDsWithMissingHubs.stream().toList());
return PersistFlags.CREATE;
}

@SuppressWarnings("unused")
public static Object createFromLoader(ImageSingletonLoader loader) {
Set<Integer> missingHubs = Set.copyOf(loader.readIntList("typeIDsWithMissingArrayHubs"));

return new DynamicHubMetadataTracking(missingHubs);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2025, 2025, 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
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.hosted.imagelayer;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.Feature;

import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.layeredimagesingleton.FeatureSingleton;
import com.oracle.svm.hosted.meta.HostedUniverse;

/**
* Class containing hooks which can only be registered and executed during layered image builds.
*/
@AutomaticallyRegisteredFeature
public class LayeredImageHooks implements InternalFeature, FeatureSingleton {
private final Set<Consumer<WrittenDynamicHubInfo>> hubWrittenCallbacks = ConcurrentHashMap.newKeySet();

@Override
public boolean isInConfiguration(Feature.IsInConfigurationAccess access) {
return ImageLayerBuildingSupport.buildingImageLayer();
}

private static LayeredImageHooks singleton() {
return ImageSingletons.lookup(LayeredImageHooks.class);
}

public record WrittenDynamicHubInfo(DynamicHub hub, AnalysisUniverse aUniverse, HostedUniverse hUniverse, Object vTable) {

}

/**
* Register a callback which will execute each time a new {@link DynamicHub} is installed in the
* image heap.
*/
public static void registerDynamicHubWrittenCallback(Consumer<WrittenDynamicHubInfo> consumer) {
singleton().hubWrittenCallbacks.add(consumer);
}

public static void processWrittenDynamicHub(WrittenDynamicHubInfo info) {
singleton().hubWrittenCallbacks.forEach(callback -> callback.accept(info));
}
}