package com.oracle.svm.hosted;
import static org.graalvm.compiler.hotspot.JVMCIVersionCheck.JVMCI11_RELEASES_URL;
import static org.graalvm.compiler.hotspot.JVMCIVersionCheck.JVMCI8_RELEASES_URL;
import static org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.registerInvocationPlugins;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import com.oracle.svm.core.OS;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Pair;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.Indent;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.lir.phases.LIRSuites;
import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.gc.BarrierSet;
import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GeneratedPluginFactory;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.Phase;
import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeoptimizationGroupingPhase;
import org.graalvm.compiler.phases.common.ExpandLogicPhase;
import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.UseTrappingNullChecksPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.phases.tiers.LowTierContext;
import org.graalvm.compiler.phases.tiers.MidTierContext;
import org.graalvm.compiler.phases.tiers.Suites;
import org.graalvm.compiler.phases.util.Providers;
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
import org.graalvm.compiler.replacements.NodeIntrinsificationProvider;
import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.WordOperationPlugin;
import org.graalvm.compiler.word.WordTypes;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.CContext;
import org.graalvm.nativeimage.c.constant.CConstant;
import org.graalvm.nativeimage.c.constant.CEnum;
import org.graalvm.nativeimage.c.function.CEntryPoint;
import org.graalvm.nativeimage.c.function.CFunction;
import org.graalvm.nativeimage.c.function.CFunctionPointer;
import org.graalvm.nativeimage.c.struct.CPointerTo;
import org.graalvm.nativeimage.c.struct.CStruct;
import org.graalvm.nativeimage.c.struct.RawStructure;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.Feature.OnAnalysisExitAccess;
import org.graalvm.nativeimage.impl.CConstantValueSupport;
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
import org.graalvm.nativeimage.impl.SizeOfSupport;
import org.graalvm.nativeimage.impl.clinit.ClassInitializationTracking;
import org.graalvm.word.PointerBase;
import com.oracle.graal.pointsto.AnalysisPolicy;
import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.BytecodeSensitiveAnalysisPolicy;
import com.oracle.graal.pointsto.DefaultAnalysisPolicy;
import com.oracle.graal.pointsto.api.PointstoOptions;
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor;
import com.oracle.graal.pointsto.infrastructure.WrappedJavaMethod;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisMetaAccessExtensionProvider;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.graal.pointsto.meta.HostedProviders;
import com.oracle.graal.pointsto.reports.AnalysisHeapHistogramPrinter;
import com.oracle.graal.pointsto.reports.AnalysisReportsOptions;
import com.oracle.graal.pointsto.reports.CallTreePrinter;
import com.oracle.graal.pointsto.reports.ObjectTreePrinter;
import com.oracle.graal.pointsto.reports.ReportUtils;
import com.oracle.graal.pointsto.reports.StatisticsPrinter;
import com.oracle.graal.pointsto.typestate.PointsToStats;
import com.oracle.graal.pointsto.typestate.TypeState;
import com.oracle.graal.pointsto.util.Timer;
import com.oracle.graal.pointsto.util.Timer.StopTimer;
import com.oracle.svm.core.ClassLoaderQuery;
import com.oracle.svm.core.FrameAccess;
import com.oracle.svm.core.JavaMainWrapper.JavaMainSupport;
import com.oracle.svm.core.LinkerInvocation;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.SubstrateTargetDescription;
import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.c.function.CEntryPointOptions;
import com.oracle.svm.core.c.libc.LibCBase;
import com.oracle.svm.core.c.libc.NoLibC;
import com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider;
import com.oracle.svm.core.c.struct.OffsetOf;
import com.oracle.svm.core.config.ConfigurationValues;
import com.oracle.svm.core.graal.GraalConfiguration;
import com.oracle.svm.core.graal.code.SubstrateBackend;
import com.oracle.svm.core.graal.code.SubstratePlatformConfigurationProvider;
import com.oracle.svm.core.graal.jdk.ArraycopySnippets;
import com.oracle.svm.core.graal.lir.VerifyCFunctionReferenceMapsLIRPhase;
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
import com.oracle.svm.core.graal.meta.SubstrateForeignCallsProvider;
import com.oracle.svm.core.graal.meta.SubstrateLoweringProvider;
import com.oracle.svm.core.graal.meta.SubstrateReplacements;
import com.oracle.svm.core.graal.meta.SubstrateSnippetReflectionProvider;
import com.oracle.svm.core.graal.meta.SubstrateStampProvider;
import com.oracle.svm.core.graal.phases.CollectDeoptimizationSourcePositionsPhase;
import com.oracle.svm.core.graal.phases.DeadStoreRemovalPhase;
import com.oracle.svm.core.graal.phases.MethodSafepointInsertionPhase;
import com.oracle.svm.core.graal.phases.OptimizeExceptionCallsPhase;
import com.oracle.svm.core.graal.phases.RemoveUnwindPhase;
import com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin;
import com.oracle.svm.core.graal.snippets.DeoptHostedSnippets;
import com.oracle.svm.core.graal.snippets.DeoptRuntimeSnippets;
import com.oracle.svm.core.graal.snippets.DeoptTester;
import com.oracle.svm.core.graal.snippets.ExceptionSnippets;
import com.oracle.svm.core.graal.snippets.NodeLoweringProvider;
import com.oracle.svm.core.graal.snippets.TypeSnippets;
import com.oracle.svm.core.graal.stackvalue.StackValuePhase;
import com.oracle.svm.core.graal.word.SubstrateWordTypes;
import com.oracle.svm.core.heap.Heap;
import com.oracle.svm.core.heap.RestrictHeapAccessCallees;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.LayoutEncoding;
import com.oracle.svm.core.image.ImageHeapLayouter;
import com.oracle.svm.core.jdk.LocalizationFeature;
import com.oracle.svm.core.option.HostedOptionValues;
import com.oracle.svm.core.option.OptionUtils;
import com.oracle.svm.core.option.RuntimeOptionValues;
import com.oracle.svm.core.option.SubstrateOptionsParser;
import com.oracle.svm.core.snippets.SnippetRuntime;
import com.oracle.svm.core.util.InterruptImageBuilding;
import com.oracle.svm.core.util.UserError;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.FeatureImpl.AfterAnalysisAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.AfterCompilationAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.AfterHeapLayoutAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.AfterImageWriteAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.AfterRegistrationAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.BeforeCompilationAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.BeforeImageWriteAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl;
import com.oracle.svm.hosted.FeatureImpl.OnAnalysisExitAccessImpl;
import com.oracle.svm.hosted.ameta.AnalysisConstantFieldProvider;
import com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider;
import com.oracle.svm.hosted.analysis.Inflation;
import com.oracle.svm.hosted.analysis.SVMAnalysisMetaAccess;
import com.oracle.svm.hosted.analysis.flow.SVMMethodTypeFlowBuilder;
import com.oracle.svm.hosted.annotation.AnnotationSupport;
import com.oracle.svm.hosted.c.CAnnotationProcessorCache;
import com.oracle.svm.hosted.c.CConstantValueSupportImpl;
import com.oracle.svm.hosted.c.GraalAccess;
import com.oracle.svm.hosted.c.NativeLibraries;
import com.oracle.svm.hosted.c.OffsetOfSupportImpl;
import com.oracle.svm.hosted.c.SizeOfSupportImpl;
import com.oracle.svm.hosted.c.codegen.CCompilerInvoker;
import com.oracle.svm.hosted.cenum.CEnumCallWrapperSubstitutionProcessor;
import com.oracle.svm.hosted.classinitialization.ClassInitializationFeature;
import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport;
import com.oracle.svm.hosted.classinitialization.ConfigurableClassInitialization;
import com.oracle.svm.hosted.code.CEntryPointCallStubSupport;
import com.oracle.svm.hosted.code.CEntryPointData;
import com.oracle.svm.hosted.code.CFunctionSubstitutionProcessor;
import com.oracle.svm.hosted.code.CompileQueue;
import com.oracle.svm.hosted.code.HostedRuntimeConfigurationBuilder;
import com.oracle.svm.hosted.code.NativeMethodSubstitutionProcessor;
import com.oracle.svm.hosted.code.RestrictHeapAccessCalleesImpl;
import com.oracle.svm.hosted.code.SharedRuntimeConfigurationBuilder;
import com.oracle.svm.hosted.code.SubstrateGraphMakerFactory;
import com.oracle.svm.hosted.image.AbstractBootImage;
import com.oracle.svm.hosted.image.AbstractBootImage.NativeImageKind;
import com.oracle.svm.hosted.image.NativeImageCodeCache;
import com.oracle.svm.hosted.image.NativeImageCodeCacheFactory;
import com.oracle.svm.hosted.image.NativeImageHeap;
import com.oracle.svm.hosted.meta.HostedField;
import com.oracle.svm.hosted.meta.HostedInterface;
import com.oracle.svm.hosted.meta.HostedMetaAccess;
import com.oracle.svm.hosted.meta.HostedMethod;
import com.oracle.svm.hosted.meta.HostedSnippetReflectionProvider;
import com.oracle.svm.hosted.meta.HostedType;
import com.oracle.svm.hosted.meta.HostedUniverse;
import com.oracle.svm.hosted.meta.UniverseBuilder;
import com.oracle.svm.hosted.option.HostedOptionProvider;
import com.oracle.svm.hosted.phases.CInterfaceInvocationPlugin;
import com.oracle.svm.hosted.phases.ConstantFoldLoadFieldPlugin;
import com.oracle.svm.hosted.phases.EarlyConstantFoldLoadFieldPlugin;
import com.oracle.svm.hosted.phases.ExperimentalNativeImageInlineDuringParsingPlugin;
import com.oracle.svm.hosted.phases.ExperimentalNativeImageInlineDuringParsingSupport;
import com.oracle.svm.hosted.phases.InjectedAccessorsPlugin;
import com.oracle.svm.hosted.phases.IntrinsifyMethodHandlesInvocationPlugin;
import com.oracle.svm.hosted.phases.SubstrateClassInitializationPlugin;
import com.oracle.svm.hosted.phases.VerifyDeoptFrameStatesLIRPhase;
import com.oracle.svm.hosted.phases.VerifyNoGuardsPhase;
import com.oracle.svm.hosted.snippets.SubstrateGraphBuilderPlugins;
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
import com.oracle.svm.hosted.substitute.DeclarativeSubstitutionProcessor;
import com.oracle.svm.hosted.substitute.DeletedFieldsPlugin;
import com.oracle.svm.hosted.substitute.UnsafeAutomaticSubstitutionProcessor;
import com.oracle.svm.util.ReflectionUtil;
import com.oracle.svm.util.ReflectionUtil.ReflectionUtilError;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
public class NativeImageGenerator {
private final FeatureHandler featureHandler;
private final ImageClassLoader loader;
private final HostedOptionProvider optionProvider;
private ForkJoinPool buildExecutor;
private DeadlockWatchdog watchdog;
private AnalysisUniverse aUniverse;
private HostedUniverse hUniverse;
private Inflation bigbang;
private NativeLibraries nativeLibraries;
private AbstractBootImage image;
private AtomicBoolean buildStarted = new AtomicBoolean();
private Pair<Method, CEntryPointData> mainEntryPoint;
private TemporaryBuildDirectoryProviderImpl buildDirectoryProvider;
public NativeImageGenerator(ImageClassLoader loader, HostedOptionProvider optionProvider, Pair<Method, CEntryPointData> mainEntryPoint) {
this.loader = loader;
this.mainEntryPoint = mainEntryPoint;
this.featureHandler = new FeatureHandler();
this.optionProvider = optionProvider;
optionProvider.getHostedValues().put(GraalOptions.EagerSnippets, true);
optionProvider.getRuntimeValues().put(GraalOptions.EagerSnippets, true);
}
public static Platform loadPlatform(ClassLoader classLoader, String platformClassName) throws ClassNotFoundException {
Class<?> platformClass;
platformClass = classLoader.loadClass(platformClassName);
Object result;
try {
result = ReflectionUtil.newInstance(platformClass);
} catch (ReflectionUtilError ex) {
throw UserError.abort(ex.getCause(), "Could not instantiate platform class %s. Ensure the class is not abstract and has a no-argument constructor.", platformClassName);
}
if (!(result instanceof Platform)) {
throw UserError.abort("Platform class %s does not implement %s", platformClassName, Platform.class.getTypeName());
}
return (Platform) result;
}
public static Platform loadPlatform(String os, String arch) {
ServiceLoader<Platform> loader = ServiceLoader.load(Platform.class);
for (Platform platform : loader) {
if (platform.getOS().equals(os) && platform.getArchitecture().equals(arch)) {
return platform;
}
}
throw UserError.abort("Platform specified as " + os + "-" + arch + " isn't supported.");
}
public static Platform getTargetPlatform(ClassLoader classLoader) {
String platformClassName = System.getProperty(Platform.PLATFORM_PROPERTY_NAME);
if (platformClassName != null) {
try {
return loadPlatform(classLoader, platformClassName);
} catch (ClassNotFoundException ex) {
throw UserError.abort("Could not find platform class %s that was specified explicitly on the command line using the system property %s",
platformClassName, Platform.PLATFORM_PROPERTY_NAME);
}
}
String os = System.getProperty("svm.targetPlatformOS");
if (os == null) {
os = OS.getCurrent().className.toLowerCase();
}
String arch = System.getProperty("svm.targetPlatformArch");
if (arch == null) {
arch = SubstrateUtil.getArchitectureName();
}
return loadPlatform(os, arch);
}
public static boolean includedIn(Platform platform, Class<? extends Platform> platformGroup) {
return platformGroup.isInstance(platform);
}
public static boolean includedIn(Platform platform, Platforms platformsAnnotation) {
if (platformsAnnotation == null) {
return true;
}
for (Class<? extends Platform> platformGroup : platformsAnnotation.value()) {
if (includedIn(platform, platformGroup)) {
return true;
}
}
return false;
}
public static SubstrateTargetDescription createTarget(Platform platform) {
if (includedIn(platform, Platform.AMD64.class)) {
Architecture architecture;
if (NativeImageOptions.NativeArchitecture.getValue()) {
architecture = GraalAccess.getOriginalTarget().arch;
} else {
EnumSet<AMD64.CPUFeature> features = EnumSet.noneOf(AMD64.CPUFeature.class);
features.add(AMD64.CPUFeature.SSE);
features.add(AMD64.CPUFeature.SSE2);
features.addAll(parseCSVtoEnum(AMD64.CPUFeature.class, NativeImageOptions.CPUFeatures.getValue(), AMD64.CPUFeature.values()));
architecture = new AMD64(features, SubstrateTargetDescription.allAMD64Flags());
}
assert architecture instanceof AMD64 : "using AMD64 platform with a different architecture";
int deoptScratchSpace = 2 * 8;
return new SubstrateTargetDescription(architecture, true, 16, 0, deoptScratchSpace);
} else if (includedIn(platform, Platform.AARCH64.class)) {
Architecture architecture;
if (NativeImageOptions.NativeArchitecture.getValue()) {
architecture = GraalAccess.getOriginalTarget().arch;
} else {
EnumSet<AArch64.CPUFeature> features = EnumSet.noneOf(AArch64.CPUFeature.class);
features.addAll(parseCSVtoEnum(AArch64.CPUFeature.class, NativeImageOptions.CPUFeatures.getValue(), AArch64.CPUFeature.values()));
architecture = new AArch64(features, EnumSet.noneOf(AArch64.Flag.class));
}
assert architecture instanceof AArch64 : "using AArch64 platform with a different architecture";
int deoptScratchSpace = 2 * 8;
return new SubstrateTargetDescription(architecture, true, 16, 0, deoptScratchSpace);
} else {
throw UserError.abort("Architecture specified by platform is not supported: %s", platform.getClass().getTypeName());
}
}
public void run(Map<Method, CEntryPointData> entryPoints,
JavaMainSupport javaMainSupport, String imageName,
NativeImageKind k,
SubstitutionProcessor harnessSubstitutions,
ForkJoinPool compilationExecutor, ForkJoinPool analysisExecutor,
EconomicSet<String> allOptionNames) {
try {
if (!buildStarted.compareAndSet(false, true)) {
throw UserError.abort("An image build has already been performed with this generator.");
}
try {
ResolvedJavaType.class.getDeclaredMethod("link");
} catch (ReflectiveOperationException ex) {
throw UserError.abort("JVMCI version provided %s is missing the 'ResolvedJavaType.link()' method added in jvmci-20.2-b01. " +
"Please use the latest JVMCI JDK from %s or %s.", System.getProperty("java.home"), JVMCI8_RELEASES_URL, JVMCI11_RELEASES_URL);
}
setSystemPropertiesForImageLate(k);
int maxConcurrentThreads = NativeImageOptions.getMaximumNumberOfConcurrentThreads(new OptionValues(optionProvider.getHostedValues()));
this.buildExecutor = createForkJoinPool(maxConcurrentThreads);
buildExecutor.submit(() -> {
ImageSingletons.add(ClassLoaderQuery.class, new ClassLoaderQueryImpl(loader.getClassLoader()));
ImageSingletons.add(HostedOptionValues.class, new HostedOptionValues(optionProvider.getHostedValues()));
ImageSingletons.add(RuntimeOptionValues.class, new RuntimeOptionValues(optionProvider.getRuntimeValues(), allOptionNames));
watchdog = new DeadlockWatchdog();
try {
buildDirectoryProvider = new TemporaryBuildDirectoryProviderImpl();
ImageSingletons.add(TemporaryBuildDirectoryProvider.class, buildDirectoryProvider);
doRun(entryPoints, javaMainSupport, imageName, k, harnessSubstitutions, compilationExecutor, analysisExecutor);
} catch (Throwable t) {
try {
cleanup();
} catch (Throwable ecleanup) {
t.addSuppressed(ecleanup);
}
throw t;
} finally {
watchdog.close();
}
cleanup();
}).get();
} catch (InterruptedException | CancellationException e) {
System.out.println("Interrupted!");
throw new InterruptImageBuilding(e);
} catch (ExecutionException e) {
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
} else if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
} finally {
shutdownBuildExecutor();
}
}
private void cleanup() {
if (buildDirectoryProvider != null) {
buildDirectoryProvider.clean();
}
featureHandler.forEachFeature(Feature::cleanup);
}
protected static void setSystemPropertiesForImageEarly() {
System.setProperty(ImageInfo.PROPERTY_IMAGE_CODE_KEY, ImageInfo.PROPERTY_IMAGE_CODE_VALUE_BUILDTIME);
}
private static void setSystemPropertiesForImageLate(NativeImageKind imageKind) {
VMError.guarantee(ImageInfo.inImageBuildtimeCode(), "System property to indicate image build time is set earlier, before listing classes");
if (imageKind.isExecutable) {
System.setProperty(ImageInfo.PROPERTY_IMAGE_KIND_KEY, ImageInfo.PROPERTY_IMAGE_KIND_VALUE_EXECUTABLE);
} else {
System.setProperty(ImageInfo.PROPERTY_IMAGE_KIND_KEY, ImageInfo.PROPERTY_IMAGE_KIND_VALUE_SHARED_LIBRARY);
}
}
protected static void clearSystemPropertiesForImage() {
System.clearProperty(ImageInfo.PROPERTY_IMAGE_CODE_KEY);
System.clearProperty(ImageInfo.PROPERTY_IMAGE_KIND_KEY);
}
private ForkJoinPool createForkJoinPool(int maxConcurrentThreads) {
ImageSingletonsSupportImpl.HostedManagement vmConfig = new ImageSingletonsSupportImpl.HostedManagement();
ImageSingletonsSupportImpl.HostedManagement.installInThread(vmConfig);
return new ForkJoinPool(
maxConcurrentThreads,
pool -> new ForkJoinWorkerThread(pool) {
@Override
protected void onStart() {
super.onStart();
ImageSingletonsSupportImpl.HostedManagement.installInThread(vmConfig);
assert loader.getClassLoader().equals(getContextClassLoader());
}
@Override
protected void onTermination(Throwable exception) {
ImageSingletonsSupportImpl.HostedManagement.clearInThread();
super.onTermination(exception);
}
},
Thread.getDefaultUncaughtExceptionHandler(),
false);
}
@SuppressWarnings("try")
private void doRun(Map<Method, CEntryPointData> entryPoints,
JavaMainSupport javaMainSupport, String imageName, NativeImageKind k,
SubstitutionProcessor harnessSubstitutions,
ForkJoinPool compilationExecutor, ForkJoinPool analysisExecutor) {
List<HostedMethod> hostedEntryPoints = new ArrayList<>();
OptionValues options = HostedOptionValues.singleton();
SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
try (DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(originalSnippetReflection)).build()) {
setupNativeImage(imageName, options, entryPoints, javaMainSupport, harnessSubstitutions, analysisExecutor, originalSnippetReflection, debug);
boolean returnAfterAnalysis = runPointsToAnalysis(imageName, options, debug);
if (returnAfterAnalysis) {
return;
}
NativeImageHeap heap;
HostedMetaAccess hMetaAccess;
SharedRuntimeConfigurationBuilder runtime;
try (StopTimer t = new Timer(imageName, "universe").start()) {
hUniverse = new HostedUniverse(bigbang);
hMetaAccess = new HostedMetaAccess(hUniverse, bigbang.getMetaAccess());
new UniverseBuilder(aUniverse, bigbang.getMetaAccess(), hUniverse, hMetaAccess, HostedConfiguration.instance().createStaticAnalysisResultsBuilder(bigbang, hUniverse),
bigbang.getUnsupportedFeatures()).build(debug);
runtime = new HostedRuntimeConfigurationBuilder(options, bigbang.getHostVM(), hUniverse, hMetaAccess, bigbang.getProviders(), nativeLibraries).build();
registerGraphBuilderPlugins(featureHandler, runtime.getRuntimeConfig(), (HostedProviders) runtime.getRuntimeConfig().getProviders(), bigbang.getMetaAccess(), aUniverse,
hMetaAccess, hUniverse,
nativeLibraries, loader, false, true, bigbang.getAnnotationSubstitutionProcessor(), new SubstrateClassInitializationPlugin((SVMHost) aUniverse.hostVM()),
bigbang.getHostVM().getClassInitializationSupport(), ConfigurationValues.getTarget());
if (NativeImageOptions.PrintUniverse.getValue()) {
printTypes();
}
for (AnalysisMethod m : aUniverse.getMethods()) {
if (m.isEntryPoint()) {
HostedMethod found = hUniverse.lookup(m);
assert found != null;
hostedEntryPoints.add(found);
}
}
if (hostedEntryPoints.size() == 0) {
throw UserError.abort("Warning: no entry points found, i.e., no method annotated with @%s", CEntryPoint.class.getSimpleName());
}
bigbang.getUnsupportedFeatures().report(bigbang);
recordRestrictHeapAccessCallees(aUniverse.getMethods());
bigbang.cleanupAfterAnalysis();
} catch (UnsupportedFeatureException ufe) {
throw FallbackFeature.reportAsFallback(ufe);
}
heap = new NativeImageHeap(aUniverse, hUniverse, hMetaAccess, ImageSingletons.lookup(ImageHeapLayouter.class));
BeforeCompilationAccessImpl beforeCompilationConfig = new BeforeCompilationAccessImpl(featureHandler, loader, aUniverse, hUniverse, hMetaAccess, heap, debug, runtime);
featureHandler.forEachFeature(feature -> feature.beforeCompilation(beforeCompilationConfig));
runtime.updateLazyState(hMetaAccess);
NativeImageCodeCache codeCache;
CompileQueue compileQueue;
try (StopTimer t = new Timer(imageName, "compile").start()) {
compileQueue = HostedConfiguration.instance().createCompileQueue(debug, featureHandler, hUniverse, runtime, DeoptTester.enabled(), bigbang.getProviders().getSnippetReflection(),
compilationExecutor);
compileQueue.finish(debug);
hUniverse.getMethods().forEach(HostedMethod::clear);
codeCache = NativeImageCodeCacheFactory.get().newCodeCache(compileQueue, heap, loader.platform,
ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory());
codeCache.layoutConstants();
codeCache.layoutMethods(debug, imageName, bigbang, compilationExecutor);
AfterCompilationAccessImpl config = new AfterCompilationAccessImpl(featureHandler, loader, aUniverse, hUniverse, hMetaAccess, compileQueue.getCompilationTasks(), heap, debug);
featureHandler.forEachFeature(feature -> feature.afterCompilation(config));
}
CodeCacheProvider codeCacheProvider = runtime.getRuntimeConfig().getBackendForNormalMethod().getProviders().getCodeCache();
try (Indent indent = debug.logAndIndent("create native image")) {
try (DebugContext.Scope buildScope = debug.scope("CreateBootImage", codeCacheProvider)) {
try (StopTimer t = new Timer(imageName, "image").start()) {
heap.addInitialObjects();
codeCache.addConstantsToHeap();
heap.addTrailingObjects();
AfterHeapLayoutAccessImpl config = new AfterHeapLayoutAccessImpl(featureHandler, loader, heap, hMetaAccess, debug);
featureHandler.forEachFeature(feature -> feature.afterHeapLayout(config));
this.image = AbstractBootImage.create(k, hUniverse, hMetaAccess, nativeLibraries, heap, codeCache, hostedEntryPoints, loader.getClassLoader());
image.build(debug);
if (NativeImageOptions.PrintUniverse.getValue()) {
codeCache.printCompilationResults();
}
}
} catch (Throwable e) {
throw VMError.shouldNotReachHere(e);
}
}
BeforeImageWriteAccessImpl beforeConfig = new BeforeImageWriteAccessImpl(featureHandler, loader, imageName, image,
runtime.getRuntimeConfig(), aUniverse, hUniverse, optionProvider, hMetaAccess, debug);
featureHandler.forEachFeature(feature -> feature.beforeImageWrite(beforeConfig));
try (StopTimer t = new Timer(imageName, "write").start()) {
Path tmpDir = ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory();
LinkerInvocation inv = image.write(debug, generatedFiles(HostedOptionValues.singleton()), tmpDir, imageName, beforeConfig);
if (NativeImageOptions.ExitAfterRelocatableImageWrite.getValue()) {
return;
}
AfterImageWriteAccessImpl afterConfig = new AfterImageWriteAccessImpl(featureHandler, loader, hUniverse, inv, tmpDir, image.getBootImageKind(), debug);
featureHandler.forEachFeature(feature -> feature.afterImageWrite(afterConfig));
}
}
}
@SuppressWarnings("try")
private boolean runPointsToAnalysis(String imageName, OptionValues options, DebugContext debug) {
try (Indent ignored = debug.logAndIndent("run analysis")) {
try (Indent ignored1 = debug.logAndIndent("process analysis initializers")) {
BeforeAnalysisAccessImpl config = new BeforeAnalysisAccessImpl(featureHandler, loader, bigbang, nativeLibraries, debug);
featureHandler.forEachFeature(feature -> feature.beforeAnalysis(config));
bigbang.getHostVM().getClassInitializationSupport().setConfigurationSealed(true);
}
try (StopTimer t = bigbang.analysisTimer.start()) {
DuringAnalysisAccessImpl config = new DuringAnalysisAccessImpl(featureHandler, loader, bigbang, nativeLibraries, debug);
int numIterations = 0;
while (true) {
try (Indent indent2 = debug.logAndIndent("new analysis iteration")) {
boolean analysisChanged = bigbang.finish();
numIterations++;
if (numIterations > 1000) {
throw UserError.abort("Static analysis did not reach a fix point after %d iterations because a Feature keeps requesting new analysis iterations. " +
"The analysis itself %s find a change in type states in the last iteration.",
numIterations, analysisChanged ? "DID" : "DID NOT");
}
try (StopTimer t2 = bigbang.processFeaturesTimer.start()) {
int numTypes = aUniverse.getTypes().size();
int numMethods = aUniverse.getMethods().size();
int numFields = aUniverse.getFields().size();
bigbang.getHostVM().notifyClassReachabilityListener(aUniverse, config);
featureHandler.forEachFeature(feature -> feature.duringAnalysis(config));
if (!config.getAndResetRequireAnalysisIteration()) {
if (numTypes != aUniverse.getTypes().size() || numMethods != aUniverse.getMethods().size() || numFields != aUniverse.getFields().size()) {
throw UserError.abort(
"When a feature makes more types, methods, or fields reachable, it must require another analysis iteration via DuringAnalysisAccess.requireAnalysisIteration()");
}
break;
}
}
}
}
nativeLibraries.processAnnotated();
AfterAnalysisAccessImpl postConfig = new AfterAnalysisAccessImpl(featureHandler, loader, bigbang, debug);
featureHandler.forEachFeature(feature -> feature.afterAnalysis(postConfig));
checkUniverse();
bigbang.typeFlowTimer.print();
bigbang.checkObjectsTimer.print();
bigbang.processFeaturesTimer.print();
bigbang.getUnsupportedFeatures().report(bigbang);
bigbang.checkUserLimitations();
} catch (UnsupportedFeatureException ufe) {
throw FallbackFeature.reportAsFallback(ufe);
}
} catch (InterruptedException ie) {
throw new InterruptImageBuilding();
} finally {
OnAnalysisExitAccess onExitConfig = new OnAnalysisExitAccessImpl(featureHandler, loader, bigbang, debug);
featureHandler.forEachFeature(feature -> feature.onAnalysisExit(onExitConfig));
if (bigbang != null) {
if (AnalysisReportsOptions.PrintAnalysisStatistics.getValue(options)) {
StatisticsPrinter.print(bigbang, SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
}
if (AnalysisReportsOptions.PrintAnalysisCallTree.getValue(options)) {
CallTreePrinter.print(bigbang, SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
}
if (AnalysisReportsOptions.PrintImageObjectTree.getValue(options)) {
ObjectTreePrinter.print(bigbang, SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
AnalysisHeapHistogramPrinter.print(bigbang, SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
}
if (PointstoOptions.PrintPointsToStatistics.getValue(options)) {
PointsToStats.report(bigbang, ReportUtils.extractImageName(imageName));
}
if (PointstoOptions.PrintSynchronizedAnalysis.getValue(options)) {
TypeState allSynchronizedTypeState = bigbang.getAllSynchronizedTypeState();
String typesString = allSynchronizedTypeState.closeToAllInstantiated(bigbang) ? "close to all instantiated" :
StreamSupport.stream(allSynchronizedTypeState.types().spliterator(), false).map(AnalysisType::getName).collect(Collectors.joining(", "));
System.out.println();
System.out.println("AllSynchronizedTypes");
System.out.println("Synchronized types #: " + allSynchronizedTypeState.typesCount());
System.out.println("Types: " + typesString);
System.out.println();
}
}
}
if (NativeImageOptions.ReturnAfterAnalysis.getValue()) {
return true;
}
if (NativeImageOptions.ExitAfterAnalysis.getValue()) {
throw new InterruptImageBuilding("Exiting image generation because of " + SubstrateOptionsParser.commandArgument(NativeImageOptions.ExitAfterAnalysis, "+"));
}
return false;
}
@SuppressWarnings("try")
private void setupNativeImage(String imageName, OptionValues options, Map<Method, CEntryPointData> entryPoints, JavaMainSupport javaMainSupport, SubstitutionProcessor harnessSubstitutions,
ForkJoinPool analysisExecutor, SnippetReflectionProvider originalSnippetReflection, DebugContext debug) {
try (Indent ignored = debug.logAndIndent("setup native-image builder")) {
try (StopTimer ignored1 = new Timer(imageName, "setup").start()) {
SubstrateTargetDescription target = createTarget(loader.platform);
ImageSingletons.add(Platform.class, loader.platform);
ImageSingletons.add(SubstrateTargetDescription.class, target);
if (javaMainSupport != null) {
ImageSingletons.add(JavaMainSupport.class, javaMainSupport);
}
Providers originalProviders = GraalAccess.getOriginalProviders();
MetaAccessProvider originalMetaAccess = originalProviders.getMetaAccess();
ClassInitializationSupport classInitializationSupport = new ConfigurableClassInitialization(originalMetaAccess, loader);
ImageSingletons.add(RuntimeClassInitializationSupport.class, classInitializationSupport);
ClassInitializationFeature.processClassInitializationOptions(classInitializationSupport);
ImageSingletons.add(ExperimentalNativeImageInlineDuringParsingSupport.class, new ExperimentalNativeImageInlineDuringParsingSupport());
featureHandler.registerFeatures(loader, debug);
AfterRegistrationAccessImpl access = new AfterRegistrationAccessImpl(featureHandler, loader, originalMetaAccess, mainEntryPoint, debug);
featureHandler.forEachFeature(feature -> feature.afterRegistration(access));
setDefaultLibCIfMissing();
if (!Pair.<Method, CEntryPointData> empty().equals(access.getMainEntryPoint())) {
setAndVerifyMainEntryPoint(access, entryPoints);
}
registerEntryPoints(entryPoints);
HostedConfiguration.setDefaultIfEmpty();
GraalConfiguration.setDefaultIfEmpty();
AnnotationSubstitutionProcessor annotationSubstitutions = createDeclarativeSubstitutionProcessor(originalMetaAccess, loader, classInitializationSupport);
CEnumCallWrapperSubstitutionProcessor cEnumProcessor = new CEnumCallWrapperSubstitutionProcessor();
aUniverse = createAnalysisUniverse(options, target, loader, originalMetaAccess, originalSnippetReflection, annotationSubstitutions, cEnumProcessor,
classInitializationSupport, Collections.singletonList(harnessSubstitutions), buildExecutor);
AnalysisMetaAccess aMetaAccess = new SVMAnalysisMetaAccess(aUniverse, originalMetaAccess);
AnalysisConstantReflectionProvider aConstantReflection = new AnalysisConstantReflectionProvider(aUniverse, originalProviders.getConstantReflection(), classInitializationSupport);
WordTypes aWordTypes = new SubstrateWordTypes(aMetaAccess, FrameAccess.getWordKind());
HostedSnippetReflectionProvider aSnippetReflection = new HostedSnippetReflectionProvider(aWordTypes);
boolean withoutCompilerInvoker = CAnnotationProcessorCache.Options.ExitAfterQueryCodeGeneration.getValue() ||
(NativeImageOptions.ExitAfterRelocatableImageWrite.getValue() && CAnnotationProcessorCache.Options.UseCAPCache.getValue());
if (!withoutCompilerInvoker) {
CCompilerInvoker compilerInvoker = CCompilerInvoker.create(ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory());
compilerInvoker.verifyCompiler();
ImageSingletons.add(CCompilerInvoker.class, compilerInvoker);
}
nativeLibraries = setupNativeLibraries(imageName, aConstantReflection, aMetaAccess, aSnippetReflection, cEnumProcessor, classInitializationSupport, debug);
ForeignCallsProvider aForeignCalls = new SubstrateForeignCallsProvider();
bigbang = createBigBang(options, target, aUniverse, nativeLibraries, analysisExecutor, watchdog::recordActivity, aMetaAccess, aConstantReflection, aWordTypes, aSnippetReflection,
annotationSubstitutions, aForeignCalls, classInitializationSupport);
try (Indent ignored2 = debug.logAndIndent("process startup initializers")) {
FeatureImpl.DuringSetupAccessImpl config = new FeatureImpl.DuringSetupAccessImpl(featureHandler, loader, bigbang, debug);
featureHandler.forEachFeature(feature -> feature.duringSetup(config));
}
initializeBigBang(bigbang, options, featureHandler, nativeLibraries, debug, aMetaAccess, aUniverse.getSubstitutions(), loader, true,
new SubstrateClassInitializationPlugin((SVMHost) aUniverse.hostVM()));
entryPoints.forEach((method, entryPointData) -> CEntryPointCallStubSupport.singleton().registerStubForMethod(method, () -> entryPointData));
}
}
}
private static void setDefaultLibCIfMissing() {
if (!ImageSingletons.contains(LibCBase.class)) {
ImageSingletons.add(LibCBase.class, new NoLibC());
}
}
private void setAndVerifyMainEntryPoint(AfterRegistrationAccessImpl access, Map<Method, CEntryPointData> entryPoints) {
mainEntryPoint = access.getMainEntryPoint();
entryPoints.put(mainEntryPoint.getLeft(), mainEntryPoint.getRight());
}
public static AnalysisUniverse createAnalysisUniverse(OptionValues options, TargetDescription target, ImageClassLoader loader, MetaAccessProvider originalMetaAccess,
SnippetReflectionProvider originalSnippetReflection, AnnotationSubstitutionProcessor annotationSubstitutions, SubstitutionProcessor cEnumProcessor,
ClassInitializationSupport classInitializationSupport, List<SubstitutionProcessor> additionalSubstitutions, ForkJoinPool buildExecutor) {
UnsafeAutomaticSubstitutionProcessor automaticSubstitutions = createAutomaticUnsafeSubstitutions(originalSnippetReflection, annotationSubstitutions);
SubstitutionProcessor aSubstitutions = createAnalysisSubstitutionProcessor(originalMetaAccess, originalSnippetReflection, cEnumProcessor, automaticSubstitutions,
annotationSubstitutions, additionalSubstitutions);
SVMHost hostVM = new SVMHost(options, buildExecutor, loader.getClassLoader(), classInitializationSupport, automaticSubstitutions);
automaticSubstitutions.init(loader, originalMetaAccess, hostVM);
AnalysisPolicy analysisPolicy = PointstoOptions.AllocationSiteSensitiveHeap.getValue(options) ? new BytecodeSensitiveAnalysisPolicy(options)
: new DefaultAnalysisPolicy(options);
return new AnalysisUniverse(hostVM, target.wordJavaKind, loader.platform, analysisPolicy, aSubstitutions, originalMetaAccess, originalSnippetReflection,
new SubstrateSnippetReflectionProvider(new SubstrateWordTypes(originalMetaAccess, FrameAccess.getWordKind())));
}
public static AnnotationSubstitutionProcessor createDeclarativeSubstitutionProcessor(MetaAccessProvider originalMetaAccess, ImageClassLoader loader,
ClassInitializationSupport classInitializationSupport) {
AnnotationSubstitutionProcessor annotationSubstitutions = new DeclarativeSubstitutionProcessor(loader, originalMetaAccess, classInitializationSupport);
annotationSubstitutions.init();
return annotationSubstitutions;
}
public static UnsafeAutomaticSubstitutionProcessor createAutomaticUnsafeSubstitutions(SnippetReflectionProvider originalSnippetReflection,
AnnotationSubstitutionProcessor annotationSubstitutions) {
return new UnsafeAutomaticSubstitutionProcessor(annotationSubstitutions, originalSnippetReflection);
}
public static SubstitutionProcessor createAnalysisSubstitutionProcessor(MetaAccessProvider originalMetaAccess, SnippetReflectionProvider originalSnippetReflection,
SubstitutionProcessor cEnumProcessor, SubstitutionProcessor automaticSubstitutions, SubstitutionProcessor annotationSubstitutions,
List<SubstitutionProcessor> additionalSubstitutionProcessors) {
List<SubstitutionProcessor> allProcessors = new ArrayList<>();
SubstitutionProcessor cFunctionSubstitutions = new CFunctionSubstitutionProcessor();
allProcessors.addAll(Arrays.asList(new AnnotationSupport(originalMetaAccess, originalSnippetReflection),
annotationSubstitutions, cFunctionSubstitutions, automaticSubstitutions, cEnumProcessor));
allProcessors.addAll(additionalSubstitutionProcessors);
return SubstitutionProcessor.chainUpInOrder(allProcessors.toArray(new SubstitutionProcessor[0]));
}
@SuppressWarnings("try")
public static void initializeBigBang(Inflation bigbang, OptionValues options, FeatureHandler featureHandler, NativeLibraries nativeLibraries, DebugContext debug,
AnalysisMetaAccess aMetaAccess, SubstitutionProcessor substitutions, ImageClassLoader loader, boolean initForeignCalls, ClassInitializationPlugin classInitializationPlugin) {
SubstrateReplacements aReplacements = bigbang.getReplacements();
HostedProviders aProviders = bigbang.getProviders();
AnalysisUniverse aUniverse = bigbang.getUniverse();
bigbang.getAnnotationSubstitutionProcessor().processComputedValueFields(bigbang);
SubstitutionProcessor[] featureNativeSubstitutions = aUniverse.getFeatureNativeSubstitutions();
if (featureNativeSubstitutions.length > 0) {
SubstitutionProcessor chain = SubstitutionProcessor.chainUpInOrder(featureNativeSubstitutions);
SubstitutionProcessor nativeSubstitutionProcessor = new NativeMethodSubstitutionProcessor(chain, aReplacements);
SubstitutionProcessor.extendsTheChain(substitutions, new SubstitutionProcessor[]{nativeSubstitutionProcessor});
}
SubstitutionProcessor.extendsTheChain(substitutions, aUniverse.getFeatureSubstitutions());
try (Indent ignored = debug.logAndIndent("add initial classes/fields/methods")) {
bigbang.addSystemClass(Object.class, false, false).registerAsInHeap();
bigbang.addSystemField(DynamicHub.class, "vtable");
bigbang.addSystemClass(String.class, false, false).registerAsInHeap();
bigbang.addSystemClass(String[].class, false, false).registerAsInHeap();
bigbang.addSystemField(String.class, "value").registerAsInHeap();
bigbang.addSystemClass(long[].class, false, false).registerAsInHeap();
bigbang.addSystemClass(byte[].class, false, false).registerAsInHeap();
bigbang.addSystemClass(byte[][].class, false, false).registerAsInHeap();
bigbang.addSystemClass(Object[].class, false, false).registerAsInHeap();
bigbang.addSystemClass(CFunctionPointer[].class, false, false).registerAsInHeap();
bigbang.addSystemClass(PointerBase[].class, false, false).registerAsInHeap();
try {
bigbang.addRootMethod(ArraycopySnippets.class.getDeclaredMethod("doArraycopy", Object.class, int.class, Object.class, int.class, int.class));
bigbang.addRootMethod(Object.class.getDeclaredMethod("getClass"));
} catch (NoSuchMethodException ex) {
throw VMError.shouldNotReachHere(ex);
}
for (JavaKind kind : JavaKind.values()) {
if (kind.isPrimitive() && kind != JavaKind.Void) {
bigbang.addSystemClass(kind.toJavaClass(), false, true);
bigbang.addSystemField(kind.toBoxedJavaClass(), "value");
bigbang.addSystemMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass());
bigbang.addSystemMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value");
Class<?>[] innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
if (innerClasses != null && innerClasses.length > 0) {
bigbang.getMetaAccess().lookupJavaType(innerClasses[0]).registerAsReachable();
}
}
}
bigbang.getMetaAccess().lookupJavaType(JavaKind.Void.toJavaClass()).registerAsReachable();
bigbang.getMetaAccess().lookupJavaType(com.oracle.svm.core.util.Counter.class).registerAsReachable();
bigbang.getMetaAccess().lookupJavaType(com.oracle.svm.core.allocationprofile.AllocationCounter.class).registerAsReachable();
NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, null, null, nativeLibraries, loader, true, true,
bigbang.getAnnotationSubstitutionProcessor(), classInitializationPlugin, bigbang.getHostVM().getClassInitializationSupport(), ConfigurationValues.getTarget());
registerReplacements(debug, featureHandler, null, aProviders, aProviders.getSnippetReflection(), true, initForeignCalls);
for (StructuredGraph graph : aReplacements.getSnippetGraphs(GraalOptions.TrackNodeSourcePosition.getValue(options), options)) {
new SVMMethodTypeFlowBuilder(bigbang, graph).registerUsedElements(false);
}
}
}
public static Inflation createBigBang(OptionValues options, TargetDescription target, AnalysisUniverse aUniverse, NativeLibraries nativeLibraries, ForkJoinPool analysisExecutor,
Runnable heartbeatCallback,
AnalysisMetaAccess aMetaAccess, AnalysisConstantReflectionProvider aConstantReflection, WordTypes aWordTypes, SnippetReflectionProvider aSnippetReflection,
AnnotationSubstitutionProcessor annotationSubstitutionProcessor, ForeignCallsProvider aForeignCalls, ClassInitializationSupport classInitializationSupport) {
assert aUniverse != null : "Analysis universe must be initialized.";
assert nativeLibraries != null : "Native libraries must be set.";
aMetaAccess.lookupJavaType(String.class).registerAsReachable();
AnalysisConstantFieldProvider aConstantFieldProvider = new AnalysisConstantFieldProvider(aUniverse, aMetaAccess, aConstantReflection, classInitializationSupport);
aMetaAccess.lookupJavaType(Reference.class).registerAsReachable();
BarrierSet barrierSet = ImageSingletons.lookup(Heap.class).createBarrierSet(aMetaAccess);
SubstratePlatformConfigurationProvider platformConfig = new SubstratePlatformConfigurationProvider(barrierSet);
AnalysisMetaAccessExtensionProvider aMetaAccessExtensionProvider = new AnalysisMetaAccessExtensionProvider();
LoweringProvider aLoweringProvider = SubstrateLoweringProvider.create(aMetaAccess, null, platformConfig, aMetaAccessExtensionProvider);
StampProvider aStampProvider = new SubstrateStampProvider(aMetaAccess);
HostedProviders aProviders = new HostedProviders(aMetaAccess, null, aConstantReflection, aConstantFieldProvider, aForeignCalls, aLoweringProvider, null, aStampProvider, aSnippetReflection,
aWordTypes, platformConfig, aMetaAccessExtensionProvider);
BytecodeProvider bytecodeProvider = new ResolvedJavaMethodBytecodeProvider();
SubstrateReplacements aReplacments = new SubstrateReplacements(aProviders, aSnippetReflection, bytecodeProvider, target, aWordTypes, new SubstrateGraphMakerFactory(aWordTypes));
aProviders = new HostedProviders(aMetaAccess, null, aConstantReflection, aConstantFieldProvider, aForeignCalls, aLoweringProvider, aReplacments, aStampProvider,
aSnippetReflection, aWordTypes, platformConfig, aMetaAccessExtensionProvider);
return new Inflation(options, aUniverse, aProviders, annotationSubstitutionProcessor, analysisExecutor, heartbeatCallback);
}
@SuppressWarnings("try")
private NativeLibraries setupNativeLibraries(String imageName, ConstantReflectionProvider aConstantReflection, MetaAccessProvider aMetaAccess,
SnippetReflectionProvider aSnippetReflection, CEnumCallWrapperSubstitutionProcessor cEnumProcessor, ClassInitializationSupport classInitializationSupport, DebugContext debug) {
try (StopTimer ignored = new Timer(imageName, "(cap)").start()) {
NativeLibraries nativeLibs = new NativeLibraries(aConstantReflection, aMetaAccess, aSnippetReflection, ConfigurationValues.getTarget(), classInitializationSupport,
ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory(), debug);
cEnumProcessor.setNativeLibraries(nativeLibs);
processNativeLibraryImports(nativeLibs, aMetaAccess, classInitializationSupport);
ImageSingletons.add(SizeOfSupport.class, new SizeOfSupportImpl(nativeLibs, aMetaAccess));
ImageSingletons.add(OffsetOf.Support.class, new OffsetOfSupportImpl(nativeLibs, aMetaAccess));
ImageSingletons.add(CConstantValueSupport.class, new CConstantValueSupportImpl(nativeLibs, aMetaAccess));
if (CAnnotationProcessorCache.Options.ExitAfterQueryCodeGeneration.getValue()) {
throw new InterruptImageBuilding("Exiting image generation because of " + SubstrateOptionsParser.commandArgument(CAnnotationProcessorCache.Options.ExitAfterQueryCodeGeneration, "+"));
}
if (CAnnotationProcessorCache.Options.ExitAfterCAPCache.getValue()) {
throw new InterruptImageBuilding("Exiting image generation because of " + SubstrateOptionsParser.commandArgument(CAnnotationProcessorCache.Options.ExitAfterCAPCache, "+"));
}
return nativeLibs;
}
}
private void registerEntryPoints(Map<Method, CEntryPointData> entryPoints) {
for (Method m : loader.findAnnotatedMethods(CEntryPoint.class)) {
if (!Modifier.isStatic(m.getModifiers())) {
throw UserError.abort("Entry point method %s.%s is not static. Add a static modifier to the method.", m.getDeclaringClass().getName(), m.getName());
}
boolean include = true;
CEntryPointOptions options = m.getAnnotation(CEntryPointOptions.class);
if (options != null) {
include = ReflectionUtil.newInstance(options.include()).getAsBoolean();
}
if (include) {
entryPoints.put(m, CEntryPointData.create(m));
}
}
}
private static void recordRestrictHeapAccessCallees(Collection<AnalysisMethod> methods) {
((RestrictHeapAccessCalleesImpl) ImageSingletons.lookup(RestrictHeapAccessCallees.class)).aggregateMethods(methods);
}
public void interruptBuild() {
shutdownBuildExecutor();
}
private void shutdownBuildExecutor() {
if (buildExecutor != null) {
buildExecutor.shutdownNow();
}
}
@Platforms(Platform.HOSTED_ONLY.class)
static class SubstitutionInvocationPlugins extends InvocationPlugins {
private AnnotationSubstitutionProcessor annotationSubstitutionProcessor;
SubstitutionInvocationPlugins(AnnotationSubstitutionProcessor annotationSubstitutionProcessor) {
this.annotationSubstitutionProcessor = annotationSubstitutionProcessor;
}
@Override
protected void register(InvocationPlugin plugin, boolean isOptional, boolean allowOverwrite, Type declaringClass, String name, Type... argumentTypes) {
Type targetClass;
if (declaringClass instanceof Class) {
targetClass = annotationSubstitutionProcessor.getTargetClass((Class<?>) declaringClass);
} else {
targetClass = declaringClass;
}
super.register(plugin, isOptional, allowOverwrite, targetClass, name, argumentTypes);
}
}
public static void registerGraphBuilderPlugins(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, HostedProviders providers, AnalysisMetaAccess aMetaAccess,
AnalysisUniverse aUniverse, HostedMetaAccess hMetaAccess, HostedUniverse hUniverse, NativeLibraries nativeLibs, ImageClassLoader loader, boolean analysis, boolean hosted,
AnnotationSubstitutionProcessor annotationSubstitutionProcessor, ClassInitializationPlugin classInitializationPlugin, ClassInitializationSupport classInitializationSupport,
TargetDescription target) {
assert !analysis || hosted : "analysis must always be hosted";
GraphBuilderConfiguration.Plugins plugins = new GraphBuilderConfiguration.Plugins(new SubstitutionInvocationPlugins(annotationSubstitutionProcessor));
WordOperationPlugin wordOperationPlugin = new WordOperationPlugin(providers.getSnippetReflection(), providers.getWordTypes());
SubstrateReplacements replacements = (SubstrateReplacements) providers.getReplacements();
plugins.appendInlineInvokePlugin(replacements);
if (nativeImageInlineDuringParsingEnabled()) {
plugins.appendInlineInvokePlugin(new ExperimentalNativeImageInlineDuringParsingPlugin(analysis, providers));
}
plugins.appendNodePlugin(new IntrinsifyMethodHandlesInvocationPlugin(analysis, providers, aUniverse, hUniverse));
plugins.appendNodePlugin(new DeletedFieldsPlugin());
plugins.appendNodePlugin(new InjectedAccessorsPlugin());
ResolvedJavaType resolvedJavaType = providers.getMetaAccess().lookupJavaType(ClassInitializationTracking.class);
if (resolvedJavaType instanceof AnalysisType) {
((AnalysisType) resolvedJavaType).registerAsReachable();
ResolvedJavaField field = providers.getMetaAccess().lookupJavaField(ReflectionUtil.lookupField(ClassInitializationTracking.class, "IS_IMAGE_BUILD_TIME"));
((AnalysisField) field).registerAsAccessed();
}
plugins.appendNodePlugin(new EarlyConstantFoldLoadFieldPlugin(providers.getMetaAccess(), providers.getSnippetReflection()));
plugins.appendNodePlugin(new ConstantFoldLoadFieldPlugin(classInitializationSupport));
plugins.appendNodePlugin(new CInterfaceInvocationPlugin(providers.getMetaAccess(), providers.getWordTypes(), nativeLibs));
plugins.appendNodePlugin(new LocalizationFeature.CharsetNodePlugin());
plugins.appendInlineInvokePlugin(wordOperationPlugin);
plugins.appendTypePlugin(wordOperationPlugin);
plugins.appendTypePlugin(new TrustedInterfaceTypePlugin());
plugins.appendNodePlugin(wordOperationPlugin);
plugins.setClassInitializationPlugin(classInitializationPlugin);
featureHandler.forEachGraalFeature(feature -> feature.registerGraphBuilderPlugins(providers, plugins, analysis, hosted));
HostedSnippetReflectionProvider hostedSnippetReflection = new HostedSnippetReflectionProvider(new SubstrateWordTypes(aMetaAccess, FrameAccess.getWordKind()));
HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) HotSpotJVMCIRuntime.runtime().getCompiler();
NodeIntrinsificationProvider nodeIntrinsificationProvider;
if (!SubstrateUtil.isBuildingLibgraal()) {
nodeIntrinsificationProvider = new NodeIntrinsificationProvider(providers.getMetaAccess(), hostedSnippetReflection, providers.getForeignCalls(),
providers.getWordTypes(), target);
} else {
nodeIntrinsificationProvider = new NodeIntrinsificationProvider(providers.getMetaAccess(), hostedSnippetReflection,
providers.getForeignCalls(), providers.getWordTypes(), target) {
@Override
public <T> T getInjectedArgument(Class<T> type) {
if (type.isAssignableFrom(GraalHotSpotVMConfig.class)) {
return type.cast(compiler.getGraalRuntime().getVMConfig());
}
if (type.isAssignableFrom(HotSpotGraalRuntimeProvider.class)) {
return type.cast(compiler.getGraalRuntime());
}
return super.getInjectedArgument(type);
}
};
}
for (Class<? extends GeneratedPluginFactory> factoryClass : loader.findSubclasses(GeneratedPluginFactory.class, true)) {
if (!Modifier.isAbstract(factoryClass.getModifiers()) && !factoryClass.getName().contains("hotspot")) {
GeneratedPluginFactory factory;
try {
factory = factoryClass.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw VMError.shouldNotReachHere(ex);
}
factory.registerPlugins(plugins.getInvocationPlugins(), nodeIntrinsificationProvider);
}
}
final boolean explicitUnsafeNullChecks = SubstrateOptions.SpawnIsolates.getValue();
final boolean arrayEqualsSubstitution = !SubstrateOptions.useLLVMBackend();
registerInvocationPlugins(providers.getMetaAccess(), providers.getSnippetReflection(), plugins.getInvocationPlugins(), replacements, !hosted, explicitUnsafeNullChecks,
arrayEqualsSubstitution);
Architecture architecture = ConfigurationValues.getTarget().arch;
ImageSingletons.lookup(TargetGraphBuilderPlugins.class).register(plugins, replacements, architecture,
explicitUnsafeNullChecks, false,
SubstrateOptions.EmitStringEncodingSubstitutions.getValue() && JavaVersionUtil.JAVA_SPEC >= 11,
JavaVersionUtil.JAVA_SPEC >= 11);
MetaAccessProvider pluginsMetaAccess = hosted && !analysis ? hMetaAccess : aMetaAccess;
assert pluginsMetaAccess != null;
SubstrateGraphBuilderPlugins.registerInvocationPlugins(annotationSubstitutionProcessor, pluginsMetaAccess,
hostedSnippetReflection, plugins.getInvocationPlugins(), replacements, analysis);
featureHandler.forEachGraalFeature(feature -> feature.registerInvocationPlugins(providers, hostedSnippetReflection, plugins.getInvocationPlugins(), analysis, hosted));
providers.setGraphBuilderPlugins(plugins);
replacements.setGraphBuilderPlugins(plugins);
if (runtimeConfig != null && runtimeConfig.getProviders() instanceof HostedProviders) {
((HostedProviders) runtimeConfig.getProviders()).setGraphBuilderPlugins(plugins);
for (SubstrateBackend backend : runtimeConfig.getBackends()) {
((HostedProviders) backend.getProviders()).setGraphBuilderPlugins(plugins);
}
}
}
public static boolean nativeImageInlineDuringParsingEnabled() {
return ExperimentalNativeImageInlineDuringParsingPlugin.Options.InlineBeforeAnalysis.getValue() &&
!ImageSingletons.lookup(ExperimentalNativeImageInlineDuringParsingSupport.class).isNativeImageInlineDuringParsingDisabled() &&
!DeoptTester.Options.DeoptimizeAll.getValue();
}
@SuppressWarnings("try")
public static void registerReplacements(DebugContext debug, FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, Providers providers,
SnippetReflectionProvider snippetReflection, boolean hosted, boolean initForeignCalls) {
OptionValues options = hosted ? HostedOptionValues.singleton() : RuntimeOptionValues.singleton();
Providers runtimeCallProviders = runtimeConfig != null ? runtimeConfig.getBackendForNormalMethod().getProviders() : providers;
SubstrateForeignCallsProvider foreignCallsProvider = (SubstrateForeignCallsProvider) providers.getForeignCalls();
if (initForeignCalls) {
SnippetRuntime.registerForeignCalls(runtimeCallProviders, foreignCallsProvider);
}
featureHandler.forEachGraalFeature(feature -> feature.registerForeignCalls(runtimeConfig, runtimeCallProviders, snippetReflection, foreignCallsProvider, hosted));
try (DebugContext.Scope s = debug.scope("RegisterLowerings", new DebugDumpScope("RegisterLowerings"))) {
SubstrateLoweringProvider lowerer = (SubstrateLoweringProvider) providers.getLowerer();
Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings = lowerer.getLowerings();
Iterable<DebugHandlersFactory> factories = runtimeConfig != null ? runtimeConfig.getDebugHandlersFactories() : Collections.singletonList(new GraalDebugHandlersFactory(snippetReflection));
lowerer.setConfiguration(runtimeConfig, options, factories, providers, snippetReflection);
TypeSnippets.registerLowerings(runtimeConfig, options, factories, providers, snippetReflection, lowerings);
ExceptionSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
if (hosted) {
DeoptHostedSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
} else {
DeoptRuntimeSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
}
featureHandler.forEachGraalFeature(feature -> feature.registerLowerings(runtimeConfig, options, factories, providers, snippetReflection, lowerings, hosted));
} catch (Throwable e) {
throw debug.handle(e);
}
SubstrateReplacements replacements = (SubstrateReplacements) providers.getReplacements();
assert checkInvocationPluginMethods(replacements);
replacements.encodeSnippets();
}
private static boolean checkInvocationPluginMethods(SubstrateReplacements replacements) {
for (ResolvedJavaMethod method : replacements.getDelayedInvocationPluginMethods()) {
ResolvedJavaMethod unwrapped = method;
while (unwrapped instanceof WrappedJavaMethod) {
unwrapped = ((WrappedJavaMethod) unwrapped).getWrapped();
}
if (method != unwrapped) {
String runtimeDescriptor = method.getSignature().toMethodDescriptor();
String hostedDescriptor = unwrapped.getSignature().toMethodDescriptor();
if (!runtimeDescriptor.equals(hostedDescriptor)) {
String name = method.format("%H.%n");
throw new AssertionError(
String.format("Cannot have invocation plugin for a method whose runtime signature is different from its hosted signature:%n" +
" method: %s%n" +
" hosted signature: %s%n" +
" runtime signature: %s",
name, runtimeDescriptor, hostedDescriptor));
}
}
assert method == unwrapped || method.getSignature().toMethodDescriptor().equals(unwrapped.getSignature().toMethodDescriptor());
}
return true;
}
public static Suites createSuites(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, SnippetReflectionProvider snippetReflection, boolean hosted) {
SubstrateBackend backend = runtimeConfig.getBackendForNormalMethod();
OptionValues options = hosted ? HostedOptionValues.singleton() : RuntimeOptionValues.singleton();
Suites suites = GraalConfiguration.instance().createSuites(options, hosted);
return modifySuites(backend, suites, featureHandler, runtimeConfig, snippetReflection, hosted, false);
}
public static Suites createFirstTierSuites(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, SnippetReflectionProvider snippetReflection, boolean hosted) {
SubstrateBackend backend = runtimeConfig.getBackendForNormalMethod();
OptionValues options = hosted ? HostedOptionValues.singleton() : RuntimeOptionValues.singleton();
Suites suites = GraalConfiguration.instance().createFirstTierSuites(options, hosted);
return modifySuites(backend, suites, featureHandler, runtimeConfig, snippetReflection, hosted, true);
}
@SuppressWarnings("unused")
private static Suites modifySuites(SubstrateBackend backend, Suites suites, FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig,
SnippetReflectionProvider snippetReflection, boolean hosted, boolean firstTier) {
Providers runtimeCallProviders = backend.getProviders();
PhaseSuite<HighTierContext> highTier = suites.getHighTier();
PhaseSuite<MidTierContext> midTier = suites.getMidTier();
PhaseSuite<LowTierContext> lowTier = suites.getLowTier();
ListIterator<BasePhase<? super HighTierContext>> position;
if (hosted) {
position = GraalConfiguration.instance().createHostedInliners(highTier);
} else {
position = highTier.findPhase(InliningPhase.class);
}
if (position != null) {
position.add(new DeadStoreRemovalPhase());
position.add(new RemoveUnwindPhase());
} else {
highTier.prependPhase(new RemoveUnwindPhase());
highTier.prependPhase(new DeadStoreRemovalPhase());
}
ListIterator<BasePhase<? super LowTierContext>> pos = lowTier.findPhase(LoweringPhase.class);
pos.next();
pos.add(new StackValuePhase());
lowTier.addBeforeLast(new OptimizeExceptionCallsPhase());
Phase addressLoweringPhase = backend.newAddressLoweringPhase(runtimeCallProviders.getCodeCache());
if (firstTier) {
lowTier.findPhase(ExpandLogicPhase.class, true).add(addressLoweringPhase);
} else {
lowTier.findPhase(UseTrappingNullChecksPhase.class).add(addressLoweringPhase);
}
if (SubstrateOptions.MultiThreaded.getValue()) {
midTier.findPhase(LoopSafepointInsertionPhase.class).add(new MethodSafepointInsertionPhase());
} else {
VMError.guarantee(midTier.removePhase(LoopSafepointInsertionPhase.class));
}
if (hosted) {
lowTier.appendPhase(new VerifyNoGuardsPhase());
highTier.removePhase(InliningPhase.class);
highTier.findPhase(ConvertDeoptimizeToGuardPhase.class, true).remove();
midTier.findPhase(DeoptimizationGroupingPhase.class).remove();
} else {
if (firstTier) {
ListIterator<BasePhase<? super MidTierContext>> it = midTier.findPhase(FrameStateAssignmentPhase.class);
it.add(new CollectDeoptimizationSourcePositionsPhase());
it = midTier.findLastPhase();
it.add(CanonicalizerPhase.create());
} else {
ListIterator<BasePhase<? super MidTierContext>> it = midTier.findPhase(DeoptimizationGroupingPhase.class);
it.previous();
it.add(new CollectDeoptimizationSourcePositionsPhase());
}
}
featureHandler.forEachGraalFeature(feature -> feature.registerGraalPhases(runtimeCallProviders, snippetReflection, suites, hosted));
return suites;
}
@SuppressWarnings("unused")
public static LIRSuites createLIRSuites(FeatureHandler featureHandler, Providers providers, boolean hosted) {
LIRSuites lirSuites = GraalConfiguration.instance().createLIRSuites(hosted ? HostedOptionValues.singleton() : RuntimeOptionValues.singleton());
if (hosted) {
lirSuites.getPostAllocationOptimizationStage().appendPhase(new VerifyCFunctionReferenceMapsLIRPhase());
}
assert addAssertionLIRPhases(lirSuites, hosted);
return lirSuites;
}
@SuppressWarnings("unused")
public static LIRSuites createFirstTierLIRSuites(FeatureHandler featureHandler, Providers providers, boolean hosted) {
LIRSuites lirSuites = GraalConfiguration.instance().createFirstTierLIRSuites(hosted ? HostedOptionValues.singleton() : RuntimeOptionValues.singleton());
if (hosted) {
lirSuites.getPostAllocationOptimizationStage().appendPhase(new VerifyCFunctionReferenceMapsLIRPhase());
}
assert addAssertionLIRPhases(lirSuites, hosted);
return lirSuites;
}
private static boolean addAssertionLIRPhases(LIRSuites lirSuites, boolean hosted) {
if (hosted) {
lirSuites.getPostAllocationOptimizationStage().appendPhase(new VerifyDeoptFrameStatesLIRPhase());
}
return true;
}
private void checkUniverse() {
for (AnalysisMethod method : aUniverse.getMethods()) {
for (int i = 0; i < method.getTypeFlow().getOriginalMethodFlows().getParameters().length; i++) {
TypeState parameterState = method.getTypeFlow().getParameterTypeState(bigbang, i);
if (parameterState != null) {
AnalysisType declaredType = method.getTypeFlow().getOriginalMethodFlows().getParameter(i).getDeclaredType();
if (declaredType.isInterface()) {
TypeState declaredTypeState = declaredType.getTypeFlow(bigbang, true).getState();
parameterState = TypeState.forSubtraction(bigbang, parameterState, declaredTypeState);
if (!parameterState.isEmpty()) {
String methodKey = method.format("%H.%n(%p)");
bigbang.getUnsupportedFeatures().addMessage(methodKey, method,
"Parameter " + i + " of " + methodKey + " has declared type " + declaredType.toJavaName(true) +
" with state " + declaredTypeState + " which is incompatible with types in parameter state: " + parameterState);
}
}
}
}
}
for (AnalysisField field : aUniverse.getFields()) {
TypeState state = field.getTypeState();
if (state != null) {
AnalysisType declaredType = field.getType();
if (declaredType.isInterface()) {
state = TypeState.forSubtraction(bigbang, state, declaredType.getTypeFlow(bigbang, true).getState());
if (!state.isEmpty()) {
String fieldKey = field.format("%H.%n");
bigbang.getUnsupportedFeatures().addMessage(fieldKey, null,
"Field " + fieldKey + " has declared type " + declaredType.toJavaName(true) + " which is incompatible with types in state: " + state);
}
}
}
}
if (SubstrateOptions.VerifyNamingConventions.getValue()) {
for (AnalysisMethod method : aUniverse.getMethods()) {
if ((method.isInvoked() || method.isImplementationInvoked()) && method.getAnnotation(Fold.class) == null) {
checkName(method.format("%H.%n(%p)"), method);
}
}
for (AnalysisField field : aUniverse.getFields()) {
if (field.isAccessed()) {
checkName(field.format("%H.%n"), null);
}
}
for (AnalysisType type : aUniverse.getTypes()) {
if (type.isReachable()) {
checkName(type.toJavaName(true), null);
}
}
}
for (AnalysisMethod method : aUniverse.getMethods()) {
if (method.isEntryPoint()) {
Set<AnalysisMethod> invocations = method.getCallers();
if (invocations.size() > 0) {
String name = method.format("%H.%n(%p)");
StringBuilder msg = new StringBuilder("Native entry point is also called from within Java. Invocations: ");
String sep = "";
for (AnalysisMethod invocation : invocations) {
msg.append(sep).append(invocation.format("%H.%n(%p)"));
sep = ", ";
}
bigbang.getUnsupportedFeatures().addMessage(name, method, msg.toString());
}
}
}
}
private void checkName(String name, AnalysisMethod method) {
String lname = name.toLowerCase();
if (lname.contains("hosted")) {
bigbang.getUnsupportedFeatures().addMessage(name, method, "Hosted element used at run time: " + name);
} else if (SubstrateUtil.isBuildingLibgraal() && (!name.startsWith("jdk.internal")) && (lname.contains("hotspot"))) {
bigbang.getUnsupportedFeatures().addMessage(name, method, "HotSpot element used at run time: " + name);
}
}
@SuppressWarnings("try")
private void processNativeLibraryImports(NativeLibraries nativeLibs, MetaAccessProvider metaAccess, ClassInitializationSupport classInitializationSupport) {
for (Method method : loader.findAnnotatedMethods(CConstant.class)) {
if (LibCBase.isMethodProvidedInCurrentLibc(method)) {
classInitializationSupport.initializeAtBuildTime(method.getDeclaringClass(), "classes with " + CConstant.class.getSimpleName() + " annotations are always initialized");
nativeLibs.loadJavaMethod(metaAccess.lookupJavaMethod(method));
}
}
for (Method method : loader.findAnnotatedMethods(CFunction.class)) {
if (LibCBase.isMethodProvidedInCurrentLibc(method)) {
nativeLibs.loadJavaMethod(metaAccess.lookupJavaMethod(method));
}
}
for (Class<?> clazz : loader.findAnnotatedClasses(CStruct.class, false)) {
if (LibCBase.isTypeProvidedInCurrentLibc(clazz)) {
classInitializationSupport.initializeAtBuildTime(clazz, "classes annotated with " + CStruct.class.getSimpleName() + " are always initialized");
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
}
for (Class<?> clazz : loader.findAnnotatedClasses(RawStructure.class, false)) {
if (LibCBase.isTypeProvidedInCurrentLibc(clazz)) {
classInitializationSupport.initializeAtBuildTime(clazz, "classes annotated with " + RawStructure.class.getSimpleName() + " are always initialized");
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
}
for (Class<?> clazz : loader.findAnnotatedClasses(CPointerTo.class, false)) {
if (LibCBase.isTypeProvidedInCurrentLibc(clazz)) {
classInitializationSupport.initializeAtBuildTime(clazz, "classes annotated with " + CPointerTo.class.getSimpleName() + " are always initialized");
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
}
for (Class<?> clazz : loader.findAnnotatedClasses(CEnum.class, false)) {
if (LibCBase.isTypeProvidedInCurrentLibc(clazz)) {
ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
classInitializationSupport.initializeAtBuildTime(clazz, "classes annotated with " + CEnum.class.getSimpleName() + " are always initialized");
nativeLibs.loadJavaType(type);
}
}
for (Class<?> clazz : loader.findAnnotatedClasses(CContext.class, false)) {
if (LibCBase.isTypeProvidedInCurrentLibc(clazz)) {
classInitializationSupport.initializeAtBuildTime(clazz, "classes annotated with " + CContext.class.getSimpleName() + " are always initialized");
}
}
nativeLibs.processCLibraryAnnotations(loader);
nativeLibs.finish();
nativeLibs.reportErrors();
}
public AbstractBootImage getBuiltImage() {
return image;
}
public BigBang getBigbang() {
return bigbang;
}
private void printTypes() {
for (HostedType type : hUniverse.getTypes()) {
System.out.format("%8d %s ", type.getTypeID(), type.toJavaName(true));
if (type.getSuperclass() != null) {
System.out.format("extends %d %s ", type.getSuperclass().getTypeID(), type.getSuperclass().toJavaName(false));
}
if (type.getInterfaces().length > 0) {
System.out.print("implements ");
String sep = "";
for (HostedInterface interf : type.getInterfaces()) {
System.out.format("%s%d %s", sep, interf.getTypeID(), interf.toJavaName(false));
sep = ", ";
}
System.out.print(" ");
}
if (type.getWrapped().isInstantiated()) {
System.out.print("instantiated ");
}
if (type.getWrapped().isReachable()) {
System.out.print("reachable ");
}
System.out.format("type check start %d range %d slot # %d ", type.getTypeCheckStart(), type.getTypeCheckRange(), type.getTypeCheckSlot());
System.out.format("type check slots %s ", slotsToString(type.getTypeCheckSlots()));
int le = type.getHub().getLayoutEncoding();
if (LayoutEncoding.isPrimitive(le)) {
System.out.print("primitive ");
} else if (LayoutEncoding.isInterface(le)) {
System.out.print("interface ");
} else if (LayoutEncoding.isAbstract(le)) {
System.out.print("abstract ");
} else if (LayoutEncoding.isInstance(le)) {
System.out.format("instance size %d ", LayoutEncoding.getInstanceSize(le).rawValue());
} else if (LayoutEncoding.isObjectArray(le)) {
System.out.format("object array base %d shift %d scale %d ", LayoutEncoding.getArrayBaseOffset(le).rawValue(), LayoutEncoding.getArrayIndexShift(le),
LayoutEncoding.getArrayIndexScale(le));
} else if (LayoutEncoding.isPrimitiveArray(le)) {
System.out.format("primitive array base %d shift %d scale %d ", LayoutEncoding.getArrayBaseOffset(le).rawValue(), LayoutEncoding.getArrayIndexShift(le),
LayoutEncoding.getArrayIndexScale(le));
} else {
throw VMError.shouldNotReachHere();
}
System.out.println();
for (HostedType sub : type.getSubTypes()) {
System.out.format(" s %d %s\n", sub.getTypeID(), sub.toJavaName(false));
}
if (type.isInterface()) {
for (HostedMethod method : hUniverse.getMethods()) {
if (method.getDeclaringClass() == type) {
printMethod(method, -1);
}
}
} else if (type.isInstanceClass()) {
HostedField[] fields = type.getInstanceFields(false);
fields = Arrays.copyOf(fields, fields.length);
Arrays.sort(fields, Comparator.comparing(HostedField::toString));
for (HostedField field : fields) {
System.out.println(" f " + field.getLocation() + ": " + field.format("%T %n"));
}
HostedMethod[] vtable = type.getVTable();
for (int i = 0; i < vtable.length; i++) {
if (vtable[i] != null) {
printMethod(vtable[i], i);
}
}
for (HostedMethod method : hUniverse.getMethods()) {
if (method.getDeclaringClass() == type && !method.hasVTableIndex()) {
printMethod(method, -1);
}
}
}
}
}
private static void printMethod(HostedMethod method, int vtableIndex) {
if (vtableIndex != -1) {
System.out.print(" v " + vtableIndex + " ");
} else {
System.out.print(" m ");
}
if (method.hasVTableIndex()) {
System.out.print(method.getVTableIndex() + " ");
}
System.out.print(method.format("%r %n(%p)") + ": " + method.getImplementations().length + " [");
String sep = "";
for (HostedMethod impl : method.getImplementations()) {
System.out.print(sep + impl.getDeclaringClass().toJavaName(false));
sep = ", ";
}
System.out.println("]");
}
private static String slotsToString(short[] slots) {
if (slots == null) {
return "null";
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < slots.length; i += 2) {
result.append("[").append(slots[i]).append(", ").append(slots[i] + slots[i + 1] - 1).append("] ");
}
return result.toString();
}
public static Path generatedFiles(OptionValues optionValues) {
String pathName = SubstrateOptions.Path.getValue(optionValues);
Path path = FileSystems.getDefault().getPath(pathName);
if (!Files.exists(path)) {
try {
Files.createDirectories(path);
} catch (IOException ex) {
throw VMError.shouldNotReachHere(ex);
}
}
if (!Files.isDirectory(path)) {
throw VMError.shouldNotReachHere("Output path is not a directory: " + pathName);
}
return path.toAbsolutePath();
}
private static <T extends Enum<T>> Set<T> parseCSVtoEnum(Class<T> enumType, String[] csvEnumValues, T[] availValues) {
EnumSet<T> result = EnumSet.noneOf(enumType);
for (String enumValue : OptionUtils.flatten(",", csvEnumValues)) {
try {
result.add(Enum.valueOf(enumType, enumValue));
} catch (IllegalArgumentException iae) {
throw VMError.shouldNotReachHere("Value '" + enumValue + "' does not exist. Available values are:\n" + Arrays.toString(availValues));
}
}
return result;
}
}