Skip to content

Commit

Permalink
[GR-52945] Label some Layered Image Singletons.
Browse files Browse the repository at this point in the history
PullRequest: graal/17566
  • Loading branch information
teshull committed May 12, 2024
2 parents fe20679 + ef82e6d commit 259b37b
Show file tree
Hide file tree
Showing 18 changed files with 259 additions and 47 deletions.
Expand Up @@ -27,12 +27,6 @@
import java.nio.file.Path;
import java.util.Map;

import jdk.graal.compiler.graph.Node;
import jdk.graal.compiler.graph.NodeClass;
import jdk.graal.compiler.nodes.java.LoadExceptionObjectNode;
import jdk.graal.compiler.options.OptionValues;
import jdk.graal.compiler.phases.util.Providers;
import jdk.graal.compiler.replacements.TargetGraphBuilderPlugins;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
Expand All @@ -58,6 +52,7 @@
import com.oracle.svm.core.graal.llvm.util.LLVMOptions;
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
import com.oracle.svm.core.graal.snippets.NodeLoweringProvider;
import com.oracle.svm.core.layeredimagesingleton.UnsupportedLayeredSingleton;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.snippets.ExceptionUnwind;
import com.oracle.svm.core.util.UserError;
Expand All @@ -72,14 +67,21 @@
import com.oracle.svm.hosted.image.ObjectFileFactory;
import com.oracle.svm.util.ModuleSupport;

import jdk.graal.compiler.graph.Node;
import jdk.graal.compiler.graph.NodeClass;
import jdk.graal.compiler.nodes.java.LoadExceptionObjectNode;
import jdk.graal.compiler.options.OptionValues;
import jdk.graal.compiler.phases.util.Providers;
import jdk.graal.compiler.replacements.TargetGraphBuilderPlugins;

/*
* This feature enables the LLVM backend of Native Image. It does so by registering the backend,
* lowerings, code cache and exception handling mechanism required to emit LLVM bitcode
* from Graal graphs, and compile this bitcode into machine code.
*/
@AutomaticallyRegisteredFeature
@Platforms({Platform.LINUX.class, Platform.DARWIN.class})
public class LLVMFeature implements Feature, InternalFeature {
public class LLVMFeature implements Feature, InternalFeature, UnsupportedLayeredSingleton {

@Override
public boolean isInConfiguration(IsInConfigurationAccess access) {
Expand Down
Expand Up @@ -51,11 +51,10 @@
import com.oracle.svm.core.util.TimeUtils;
import com.oracle.svm.core.util.VMError;

import jdk.graal.compiler.api.replacements.Fold;

@AutomaticallyRegisteredImageSingleton(VMThreads.class)
public final class PosixVMThreads extends VMThreads {
@Fold

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public static PosixVMThreads singleton() {
return (PosixVMThreads) ImageSingletons.lookup(VMThreads.class);
}
Expand Down
Expand Up @@ -41,6 +41,7 @@
import com.oracle.svm.core.Containers;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyImageSingleton;
import com.oracle.svm.core.stack.StackOverflowCheck;
import com.oracle.svm.core.thread.PlatformThreads;
import com.oracle.svm.core.thread.VMOperation;
Expand All @@ -54,7 +55,7 @@
public class PhysicalMemory {

/** Implemented by operating-system specific code. */
public interface PhysicalMemorySupport {
public interface PhysicalMemorySupport extends RuntimeOnlyImageSingleton {
/** Get the size of physical memory from the OS. */
UnsignedWord size();
}
Expand Down
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, 2024, 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.core.layeredimagesingleton;

import org.graalvm.nativeimage.ImageSingletons;

public interface LayeredImageSingletonSupport {

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

<T> T runtimeLookup(Class<T> key);
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024, 2024, 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.core.layeredimagesingleton;

import java.util.EnumSet;

public interface RuntimeOnlyImageSingleton extends LayeredImageSingleton {

@Override
default EnumSet<ImageBuilderFlags> getImageBuilderFlags() {
return EnumSet.of(ImageBuilderFlags.RUNTIME_ACCESS, ImageBuilderFlags.ALLOW_CONSTANT_FOLDING);
}

@Override
default PersistFlags preparePersist(ImageSingletonWriter writer) {
return PersistFlags.NOTHING;
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2024, 2024, 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.core.layeredimagesingleton;

/**
* This is used to wrap singletons which are only allowed to be accessed at runtime. When a
* singleton wrapped with this is called during image build time an error is thrown.
*/
public record RuntimeOnlyWrapper(LayeredImageSingleton wrappedObject) {
}
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2024, 2024, 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.core.layeredimagesingleton;

import java.util.EnumSet;

import com.oracle.svm.core.util.VMError;

/**
* Marker for singletons which currently cannot be part of layered images.
*/
public interface UnsupportedLayeredSingleton extends LayeredImageSingleton {

@Override
default EnumSet<ImageBuilderFlags> getImageBuilderFlags() {
return EnumSet.of(ImageBuilderFlags.UNSUPPORTED);
}

@Override
default PersistFlags preparePersist(ImageSingletonWriter writer) {
throw VMError.shouldNotReachHere("Unsupported feature singleton cannot be added to image");
}
}
Expand Up @@ -48,6 +48,7 @@
import com.oracle.svm.core.heap.VMOperationInfos;
import com.oracle.svm.core.jdk.UninterruptibleUtils;
import com.oracle.svm.core.jdk.UninterruptibleUtils.AtomicWord;
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyImageSingleton;
import com.oracle.svm.core.locks.VMCondition;
import com.oracle.svm.core.locks.VMLockSupport;
import com.oracle.svm.core.locks.VMMutex;
Expand All @@ -65,17 +66,16 @@
import com.oracle.svm.core.util.VMError;

import jdk.graal.compiler.api.directives.GraalDirectives;
import jdk.graal.compiler.api.replacements.Fold;
import jdk.graal.compiler.core.common.SuppressFBWarnings;
import jdk.graal.compiler.replacements.ReplacementsUtil;
import jdk.graal.compiler.replacements.nodes.AssertionNode;

/**
* Utility methods for the manipulation and iteration of {@link IsolateThread}s.
*/
public abstract class VMThreads {
public abstract class VMThreads implements RuntimeOnlyImageSingleton {

@Fold
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public static VMThreads singleton() {
return ImageSingletons.lookup(VMThreads.class);
}
Expand Down
Expand Up @@ -32,6 +32,13 @@

import java.util.EnumSet;

import org.graalvm.nativeimage.Platform.AMD64;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.layeredimagesingleton.FeatureSingleton;
import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton;

import jdk.graal.compiler.replacements.StringLatin1InflateNode;
import jdk.graal.compiler.replacements.StringUTF16CompressNode;
import jdk.graal.compiler.replacements.nodes.AESNode;
Expand All @@ -57,16 +64,11 @@
import jdk.graal.compiler.replacements.nodes.MessageDigestNode.SHA512Node;
import jdk.graal.compiler.replacements.nodes.VectorizedHashCodeNode;
import jdk.graal.compiler.replacements.nodes.VectorizedMismatchNode;
import org.graalvm.nativeimage.Platform.AMD64;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;

import jdk.vm.ci.amd64.AMD64.CPUFeature;

@AutomaticallyRegisteredFeature
@Platforms(AMD64.class)
public class AMD64StubForeignCallsFeature extends StubForeignCallsFeatureBase {
public class AMD64StubForeignCallsFeature extends StubForeignCallsFeatureBase implements FeatureSingleton, UnsavedSingleton {

private static final EnumSet<CPUFeature> BASELINE = EnumSet.of(SSE2);

Expand Down
Expand Up @@ -35,11 +35,13 @@

import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton.PersistFlags;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonSupport;
import com.oracle.svm.core.layeredimagesingleton.LoadedLayeredImageSingletonInfo;
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyWrapper;
import com.oracle.svm.core.util.UserError;
import com.oracle.svm.hosted.heap.SVMImageLayerLoader;

public final class ImageSingletonsSupportImpl extends ImageSingletonsSupport {
public final class ImageSingletonsSupportImpl extends ImageSingletonsSupport implements LayeredImageSingletonSupport {

@Override
public <T> void add(Class<T> key, T value) {
Expand All @@ -48,7 +50,12 @@ public <T> void add(Class<T> key, T value) {

@Override
public <T> T lookup(Class<T> key) {
return HostedManagement.getAndAssertExists().doLookup(key);
return HostedManagement.getAndAssertExists().doLookup(key, false);
}

@Override
public <T> T runtimeLookup(Class<T> key) {
return HostedManagement.getAndAssertExists().doLookup(key, true);
}

@Override
Expand Down Expand Up @@ -135,9 +142,15 @@ public static void persist() {
}

private final Map<Class<?>, Object> configObjects;
private final boolean checkUnsupported;

public HostedManagement() {
this(false);
}

public HostedManagement(boolean checkUnsupported) {
this.configObjects = new ConcurrentHashMap<>();
this.checkUnsupported = checkUnsupported;
}

<T> void doAdd(Class<T> key, T value) {
Expand All @@ -150,28 +163,40 @@ private void doAddInternal(Class<?> key, Object value) {
throw UserError.abort("ImageSingletons do not allow null value for key %s", key.getTypeName());
}

Object storedValue = value;
if (value instanceof LayeredImageSingleton singleton) {
assert singleton.verifyImageBuilderFlags();

if (singleton.getImageBuilderFlags().contains(LayeredImageSingleton.ImageBuilderFlags.UNSUPPORTED)) {
if (checkUnsupported && singleton.getImageBuilderFlags().contains(LayeredImageSingleton.ImageBuilderFlags.UNSUPPORTED)) {
throw UserError.abort("Unsupported image singleton is being installed %s %s", key.getTypeName(), singleton);
}

if (!singleton.getImageBuilderFlags().contains(LayeredImageSingleton.ImageBuilderFlags.BUILDTIME_ACCESS)) {
storedValue = new RuntimeOnlyWrapper(singleton);
}
}

Object prevValue = configObjects.putIfAbsent(key, value);
Object prevValue = configObjects.putIfAbsent(key, storedValue);

if (prevValue != null) {
throw UserError.abort("ImageSingletons.add must not overwrite existing key %s%nExisting value: %s%nNew value: %s", key.getTypeName(), prevValue, value);
}
}

<T> T doLookup(Class<T> key) {
<T> T doLookup(Class<T> key, boolean stripRuntimeOnly) {
checkKey(key);
Object result = configObjects.get(key);
if (result == null) {
throw UserError.abort("ImageSingletons do not contain key %s", key.getTypeName());
} else if (result == SINGLETON_INSTALLATION_FOBIDDEN) {
throw UserError.abort("A LayeredImageSingleton was installed in a prior layer which forbids creating the singleton in a subsequent layer. Key %s", key.getTypeName());
} else if (result instanceof RuntimeOnlyWrapper wrapper) {
if (!stripRuntimeOnly) {
throw UserError.abort("A LayeredImageSingleton was accessed during image building which does not have %s access. Key: %s, object %s",
LayeredImageSingleton.ImageBuilderFlags.BUILDTIME_ACCESS, key, wrapper.wrappedObject());
}
result = wrapper.wrappedObject();

}
return key.cast(result);
}
Expand Down
Expand Up @@ -173,6 +173,7 @@
import com.oracle.svm.core.hub.LayoutEncoding;
import com.oracle.svm.core.image.ImageHeapLayouter;
import com.oracle.svm.core.jdk.ServiceCatalogSupport;
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonSupport;
import com.oracle.svm.core.option.HostedOptionValues;
import com.oracle.svm.core.option.OptionClassFilter;
import com.oracle.svm.core.option.RuntimeOptionValues;
Expand Down Expand Up @@ -528,8 +529,9 @@ public void run(Map<Method, CEntryPointData> entryPoints,

var hostedOptionValues = new HostedOptionValues(optionProvider.getHostedValues());
SVMImageLayerSupport imageLayerSupport = SVMImageLayerSupport.initialize(hostedOptionValues);
ImageSingletonsSupportImpl.HostedManagement.install(new ImageSingletonsSupportImpl.HostedManagement(), imageLayerSupport);
ImageSingletonsSupportImpl.HostedManagement.install(new ImageSingletonsSupportImpl.HostedManagement(imageLayerSupport.enabled()), imageLayerSupport);

ImageSingletons.add(LayeredImageSingletonSupport.class, (LayeredImageSingletonSupport) ImageSingletonsSupportImpl.get());
ImageSingletons.add(SVMImageLayerSupport.class, imageLayerSupport);
ImageSingletons.add(ProgressReporter.class, reporter);
ImageSingletons.add(DeadlockWatchdog.class, loader.watchdog);
Expand Down

0 comments on commit 259b37b

Please sign in to comment.