use of com.oracle.svm.hosted.c.NativeLibraries in project graal by oracle.
the class CEntryPointCallStubMethod method adaptReturnValue.
private ValueNode adaptReturnValue(ResolvedJavaMethod method, HostedProviders providers, Purpose purpose, UniverseMetaAccess metaAccess, NativeLibraries nativeLibraries, HostedGraphKit kit, ValueNode invokeValue) {
ValueNode returnValue = invokeValue;
if (returnValue.getStackKind().isPrimitive()) {
return returnValue;
}
JavaType returnType = method.getSignature().getReturnType(null);
ElementInfo typeInfo = nativeLibraries.findElementInfo(returnType);
if (typeInfo instanceof EnumInfo) {
UserError.guarantee(typeInfo.getChildren().stream().anyMatch(EnumValueInfo.class::isInstance), "Enum class " + returnType.toJavaName() + " needs a method that is annotated with @" + CEnumValue.class + " because it is used as the return type of an entry point method: " + targetMethod.format("%H.%n(%p)"));
IsNullNode isNull = kit.unique(new IsNullNode(returnValue));
kit.startIf(isNull, BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY);
kit.thenPart();
ResolvedJavaType enumExceptionType = metaAccess.lookupJavaType(RuntimeException.class);
NewInstanceNode enumException = kit.append(new NewInstanceNode(enumExceptionType, true));
Iterator<ResolvedJavaMethod> enumExceptionCtor = Arrays.stream(enumExceptionType.getDeclaredConstructors()).filter(c -> c.getSignature().getParameterCount(false) == 1 && c.getSignature().getParameterType(0, null).equals(metaAccess.lookupJavaType(String.class))).iterator();
ConstantNode enumExceptionMessage = kit.createConstant(kit.getConstantReflection().forString("null return value cannot be converted to a C enum value"), JavaKind.Object);
kit.createJavaCallWithExceptionAndUnwind(InvokeKind.Special, enumExceptionCtor.next(), enumException, enumExceptionMessage);
assert !enumExceptionCtor.hasNext();
kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, enumException));
kit.append(new DeadEndNode());
kit.endIf();
// Always return enum values as a signed word because it should never be a problem if
// the caller expects a narrower integer type and the various checks already handle
// replacements with word types
CInterfaceEnumTool tool = new CInterfaceEnumTool(providers.getMetaAccess(), providers.getSnippetReflection());
JavaKind cEnumReturnType = providers.getWordTypes().getWordKind();
assert !cEnumReturnType.isUnsigned() : "requires correct representation of signed values";
returnValue = tool.createEnumValueInvoke(kit, (EnumInfo) typeInfo, cEnumReturnType, returnValue);
} else if (purpose != Purpose.ANALYSIS) {
// for analysis test cases: abort only during compilation
throw UserError.abort("Entry point method return types are restricted to primitive types, word types and enumerations (@" + CEnum.class.getSimpleName() + "): " + targetMethod.format("%H.%n(%p)"));
}
return returnValue;
}
use of com.oracle.svm.hosted.c.NativeLibraries in project graal by oracle.
the class CFunctionCallStubMethod method adaptSignatureAndConvertArguments.
private static Signature adaptSignatureAndConvertArguments(ResolvedJavaMethod method, HostedProviders providers, NativeLibraries nativeLibraries, HostedGraphKit kit, Signature signature, List<ValueNode> arguments) {
MetaAccessProvider metaAccess = providers.getMetaAccess();
JavaType returnType = signature.getReturnType(null);
JavaType[] parameterTypes = signature.toParameterTypes(null);
for (int i = 0; i < parameterTypes.length; i++) {
if (!isPrimitiveOrWord(providers, parameterTypes[i])) {
ElementInfo typeInfo = nativeLibraries.findElementInfo(parameterTypes[i]);
if (typeInfo instanceof EnumInfo) {
UserError.guarantee(typeInfo.getChildren().stream().anyMatch(EnumValueInfo.class::isInstance), "Enum class " + returnType.toJavaName() + " needs a method that is annotated with @" + CEnumValue.class.getSimpleName() + " because it is used as a parameter of a method annotated with @" + CFunction.class.getSimpleName() + ": " + method.format("%H.%n(%p)"));
ValueNode argumentValue = arguments.get(i);
IsNullNode isNull = kit.unique(new IsNullNode(argumentValue));
kit.startIf(isNull, BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY);
kit.thenPart();
ResolvedJavaType enumExceptionType = metaAccess.lookupJavaType(RuntimeException.class);
NewInstanceNode enumException = kit.append(new NewInstanceNode(enumExceptionType, true));
Iterator<ResolvedJavaMethod> enumExceptionCtor = Arrays.stream(enumExceptionType.getDeclaredConstructors()).filter(c -> c.getSignature().getParameterCount(false) == 1 && c.getSignature().getParameterType(0, null).equals(metaAccess.lookupJavaType(String.class))).iterator();
ConstantNode enumExceptionMessage = kit.createConstant(kit.getConstantReflection().forString("null return value cannot be converted to a C enum value"), JavaKind.Object);
kit.createJavaCallWithExceptionAndUnwind(InvokeKind.Special, enumExceptionCtor.next(), enumException, enumExceptionMessage);
assert !enumExceptionCtor.hasNext();
kit.append(new UnwindNode(enumException));
kit.endIf();
CInterfaceEnumTool tool = new CInterfaceEnumTool(metaAccess, providers.getSnippetReflection());
argumentValue = tool.createEnumValueInvoke(kit, (EnumInfo) typeInfo, cEnumKind, argumentValue);
arguments.set(i, argumentValue);
parameterTypes[i] = metaAccess.lookupJavaType(cEnumKind.toJavaClass());
} else {
throw UserError.abort("@" + CFunction.class.getSimpleName() + " parameter types are restricted to primitive types, word types and enumerations (@" + CEnum.class.getSimpleName() + "): " + method.format("%H.%n(%p)"));
}
}
}
if (!isPrimitiveOrWord(providers, returnType)) {
// Assume enum: actual checks and conversion are in adaptReturnValue()
returnType = providers.getWordTypes().getWordImplType();
}
JavaType actualReturnType = returnType;
return new Signature() {
@Override
public int getParameterCount(boolean receiver) {
return parameterTypes.length;
}
@Override
public JavaType getParameterType(int index, ResolvedJavaType accessingClass) {
return parameterTypes[index];
}
@Override
public JavaType getReturnType(ResolvedJavaType accessingClass) {
return actualReturnType;
}
};
}
use of com.oracle.svm.hosted.c.NativeLibraries in project graal by oracle.
the class NativeImageGenerator method doRun.
@SuppressWarnings("try")
private void doRun(Map<Method, CEntryPointData> entryPoints, Method mainEntryPoint, JavaMainSupport javaMainSupport, String imageName, AbstractBootImage.NativeImageKind k, SubstitutionProcessor harnessSubstitutions, ForkJoinPool compilationExecutor, ForkJoinPool analysisExecutor) {
List<HostedMethod> hostedEntryPoints = new ArrayList<>();
NativeLibraries nativeLibs;
SVMHost svmHost;
AnalysisMetaAccess aMetaAccess;
SnippetReflectionProvider aSnippetReflection;
HostedProviders aProviders;
Throwable error = null;
OptionValues options = HostedOptionValues.singleton();
SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
try (DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(originalSnippetReflection))) {
try (Indent indent = debug.logAndIndent("start analysis pass")) {
try (StopTimer t = new Timer("setup").start()) {
// TODO Make customizable via command line parameter.
Platform platform = defaultPlatform();
TargetDescription target = createTarget(platform);
OSInterface osInterface = createOSInterface(loader);
ObjectLayout objectLayout = new ObjectLayout(target, SubstrateAMD64Backend.getDeoptScatchSpace());
CompressEncoding compressEncoding = new CompressEncoding(SubstrateOptions.UseHeapBaseRegister.getValue() ? 1 : 0, 0);
ImageSingletons.add(Platform.class, platform);
ImageSingletons.add(TargetDescription.class, target);
ImageSingletons.add(OSInterface.class, osInterface);
ImageSingletons.add(ObjectLayout.class, objectLayout);
ImageSingletons.add(CompressEncoding.class, compressEncoding);
if (javaMainSupport != null) {
ImageSingletons.add(JavaMainSupport.class, javaMainSupport);
}
Providers originalProviders = GraalAccess.getOriginalProviders();
MetaAccessProvider originalMetaAccess = originalProviders.getMetaAccess();
AnalysisPolicy analysisPolicy;
if (PointstoOptions.AllocationSiteSensitiveHeap.getValue(options)) {
// context sensitive analysis
analysisPolicy = new SVMBytecodeAnalysisPolicy(options);
} else {
// context insensitive analysis
analysisPolicy = new SVMDefaultAnalysisPolicy(options);
}
svmHost = new SVMHost(options, platform, analysisPolicy, loader.getClassLoader());
featureHandler.registerFeatures(loader);
AfterRegistrationAccessImpl access = new AfterRegistrationAccessImpl(featureHandler, loader, originalMetaAccess);
featureHandler.forEachFeature(feature -> feature.afterRegistration(access));
registerEntryPoints(entryPoints);
/*
* Check if any configuration factory class was registered. If not, register the
* basic one.
*/
HostedConfiguration.setDefaultIfEmpty();
GraalConfiguration.setDefaultIfEmpty();
registerEntryPoints(entryPoints);
CFunctionSubstitutionProcessor cfunctionSubstitutions = new CFunctionSubstitutionProcessor();
AnnotationSubstitutionProcessor annotationSubstitutions = new DeclarativeSubstitutionProcessor(loader, originalMetaAccess);
ImageSingletons.add(AnnotationSubstitutionProcessor.class, annotationSubstitutions);
annotationSubstitutions.init();
UnsafeAutomaticSubstitutionProcessor automaticSubstitutions = new UnsafeAutomaticSubstitutionProcessor(annotationSubstitutions);
ImageSingletons.add(UnsafeAutomaticSubstitutionProcessor.class, automaticSubstitutions);
automaticSubstitutions.init(originalMetaAccess);
SubstitutionProcessor substitutions = SubstitutionProcessor.chainUpInOrder(harnessSubstitutions, new AnnotationSupport(originalMetaAccess, originalSnippetReflection), annotationSubstitutions, cfunctionSubstitutions, automaticSubstitutions);
aUniverse = new AnalysisUniverse(svmHost, target, substitutions, originalMetaAccess, originalSnippetReflection, new SubstrateSnippetReflectionProvider());
aMetaAccess = new AnalysisMetaAccess(aUniverse, originalMetaAccess);
// native libraries
AnalysisConstantReflectionProvider aConstantReflection = new AnalysisConstantReflectionProvider(svmHost, aUniverse, originalProviders.getConstantReflection());
AnalysisConstantFieldProvider aConstantFieldProvider = new AnalysisConstantFieldProvider(aUniverse, aMetaAccess);
aSnippetReflection = new HostedSnippetReflectionProvider(svmHost);
nativeLibs = processNativeLibraryImports(aMetaAccess, aConstantReflection, aSnippetReflection);
/*
* Install all snippets so that the types, methods, and fields used in the
* snippets get added to the universe.
*/
ForeignCallsProvider aForeignCalls = new SubstrateForeignCallsProvider();
LoweringProvider aLoweringProvider = SubstrateLoweringProvider.create(aMetaAccess, null);
StampProvider aStampProvider = new SubstrateStampProvider(aMetaAccess);
WordTypes aWordTypes = new WordTypes(aMetaAccess, FrameAccess.getWordKind());
aProviders = new HostedProviders(aMetaAccess, null, aConstantReflection, aConstantFieldProvider, aForeignCalls, aLoweringProvider, null, aStampProvider, aSnippetReflection, aWordTypes);
BytecodeProvider bytecodeProvider = new ResolvedJavaMethodBytecodeProvider();
SubstrateReplacements aReplacements = new SubstrateReplacements(options, aProviders, aSnippetReflection, bytecodeProvider, target, new SubstrateGraphMakerFactory(aWordTypes));
aProviders = new HostedProviders(aMetaAccess, null, aConstantReflection, aConstantFieldProvider, aForeignCalls, aLoweringProvider, aReplacements, aStampProvider, aSnippetReflection, aWordTypes);
bigbang = new Inflation(options, aUniverse, aProviders, svmHost, analysisExecutor);
/*
* Eagerly register all target fields of recomputed value fields as unsafe
* accessed.
*/
annotationSubstitutions.processComputedValueFields(bigbang);
try (Indent indent2 = debug.logAndIndent("process startup initializers")) {
DuringSetupAccessImpl config = new DuringSetupAccessImpl(featureHandler, loader, bigbang, svmHost);
featureHandler.forEachFeature(feature -> feature.duringSetup(config));
}
NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, null, null, nativeLibs, loader, true, true);
registerReplacements(debug, featureHandler, null, aProviders, aProviders.getSnippetReflection(), true);
/*
* Install feature supported substitutions.
*/
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());
/*
* System classes and fields are necessary to tell the static analysis that
* certain things really "exist". The most common reason for that is that there
* are no instances and allocations of these classes seen during the static
* analysis. The heap chunks are one good example.
*/
try (Indent indent2 = 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();
// Fields of BootImageInfo that get patched via relocation to addresses
// to the partitions of the native image heap.
bigbang.addSystemStaticField(NativeImageInfo.class, "firstReadOnlyPrimitiveObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "lastReadOnlyPrimitiveObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "firstReadOnlyReferenceObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "lastReadOnlyReferenceObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "firstWritablePrimitiveObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "lastWritablePrimitiveObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "firstWritableReferenceObject").registerAsInHeap();
bigbang.addSystemStaticField(NativeImageInfo.class, "lastWritableReferenceObject").registerAsInHeap();
// Graal uses it for type checks in the partial escape analysis phase.
bigbang.addSystemClass(Reference.class, false, false);
bigbang.addSystemClass(AllocationSite.class, false, false).registerAsInHeap();
bigbang.addSystemClass(AllocationCounter.class, false, false).registerAsInHeap();
bigbang.addSystemClass(AtomicReference.class, false, false).registerAsInHeap();
try {
/*
* TODO we want to get rid of these explicit registrations. All
* registered foreign calls should automatically be included in the
* static analysis.
*/
bigbang.addRootMethod(ArraycopySnippets.class.getDeclaredMethod("doArraycopy", Object.class, int.class, Object.class, int.class, int.class));
bigbang.addRootMethod(Object.class.getDeclaredMethod("getClass"));
if (NativeImageOptions.DeoptimizeAll.getValue()) {
bigbang.addRootMethod(DeoptTester.class.getMethod("deoptTest"));
}
} 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");
}
}
entryPoints.forEach((method, entryPointData) -> CEntryPointCallStubSupport.singleton().registerStubForMethod(method, () -> entryPointData));
for (StructuredGraph graph : aReplacements.getSnippetGraphs(GraalOptions.TrackNodeSourcePosition.getValue(options))) {
MethodTypeFlowBuilder.registerUsedElements(bigbang, graph, null);
}
}
try (Indent indent2 = debug.logAndIndent("process analysis initializers")) {
BeforeAnalysisAccessImpl config = new BeforeAnalysisAccessImpl(featureHandler, loader, bigbang, svmHost, nativeLibs);
featureHandler.forEachFeature(feature -> feature.beforeAnalysis(config));
}
}
try (StopTimer t = new Timer("analysis").start()) {
Timer processFeaturesTimer = new Timer("(features)", false);
/*
* Iterate until analysis reaches a fixpoint
*/
DuringAnalysisAccessImpl config = new DuringAnalysisAccessImpl(featureHandler, loader, bigbang, svmHost, nativeLibs);
int numIterations = 0;
while (true) {
try (Indent indent2 = debug.logAndIndent("new analysis iteration")) {
/*
* Do the analysis (which itself is done in a similar iterative process)
*/
boolean analysisChanged = bigbang.finish();
numIterations++;
if (numIterations > 1000) {
/*
* Usually there are < 10 iterations. If we have so many iterations,
* we probably have an endless loop (but at least we have a
* performance problem because we re-start the analysis so often).
*/
throw VMError.shouldNotReachHere("Static analysis did not reach a fix point after " + numIterations + " iterations because a Feature keeps requesting new analysis iterations. The analysis itself " + (analysisChanged ? "DID" : "DID NOT") + " find a change in type states in the last iteration.");
}
/*
* Allow features to change the universe
*/
try (StopTimer t2 = processFeaturesTimer.start()) {
int numTypes = aUniverse.getTypes().size();
int numMethods = aUniverse.getMethods().size();
int numFields = aUniverse.getFields().size();
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, of fields reachable, it must require another analysis iteration via DuringAnalysisAccess.requireAnalysisIteration()");
}
break;
}
}
}
}
AfterAnalysisAccessImpl postConfig = new AfterAnalysisAccessImpl(featureHandler, loader, bigbang);
featureHandler.forEachFeature(feature -> feature.afterAnalysis(postConfig));
checkUniverse();
bigbang.typeFlowTimer.print();
bigbang.checkObjectsTimer.print();
processFeaturesTimer.print();
/* report the unsupported features by throwing UnsupportedFeatureException */
bigbang.getUnsupportedFeatures().report(bigbang);
} catch (UnsupportedFeatureException ufe) {
if (NativeImageOptions.ReportUnsupportedFeaturesCause.getValue() && ufe.getCause() != null) {
System.err.println("Original exception: ");
ufe.getCause().printStackTrace();
}
throw UserError.abort(ufe.getMessage());
}
} catch (InterruptedException ie) {
throw new InterruptImageBuilding();
} catch (RuntimeException | Error e) {
// Prevents swallowing exceptions when ReturnAfterAnalysis is true
error = e;
throw e;
} finally {
OnAnalysisExitAccess onExitConfig = new OnAnalysisExitAccessImpl(featureHandler, loader, bigbang);
featureHandler.forEachFeature(feature -> {
try {
feature.onAnalysisExit(onExitConfig);
} catch (Exception ex) {
System.err.println("Exception during " + feature.getClass().getName() + ".onAnalysisExit()");
}
});
if (AnalysisReportsOptions.PrintAnalysisCallTree.getValue(options)) {
String reportName = imageName.substring(imageName.lastIndexOf("/") + 1);
CallTreePrinter.print(bigbang, SubstrateOptions.Path.getValue(), reportName);
}
if (AnalysisReportsOptions.PrintImageObjectTree.getValue(options)) {
String reportName = imageName.substring(imageName.lastIndexOf("/") + 1);
ObjectTreePrinter.print(bigbang, SubstrateOptions.Path.getValue(), reportName);
}
if (PointstoOptions.ReportAnalysisStatistics.getValue(options)) {
PointsToStats.report(bigbang, imageName.replace("images/", ""));
}
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 (error == null && NativeImageOptions.ReturnAfterAnalysis.getValue()) {
return;
}
if (NativeImageOptions.ExitAfterAnalysis.getValue()) {
throw new InterruptImageBuilding("interrupted image construction as ExitAfterAnalysis is set");
}
NativeImageHeap heap;
HostedMethod mainEntryPointHostedStub;
HostedMetaAccess hMetaAccess;
SharedRuntimeConfigurationBuilder runtime;
try (StopTimer t = new Timer("universe").start()) {
hUniverse = new HostedUniverse(bigbang, svmHost);
hMetaAccess = new HostedMetaAccess(hUniverse, aMetaAccess);
new UniverseBuilder(aUniverse, aMetaAccess, hUniverse, hMetaAccess, HostedConfiguration.instance().createStaticAnalysisResultsBuilder(bigbang, hUniverse), bigbang.getUnsupportedFeatures()).build(debug);
runtime = new HostedRuntimeConfigurationBuilder(options, svmHost, hUniverse, hMetaAccess, aProviders).build();
registerGraphBuilderPlugins(featureHandler, runtime.getRuntimeConfig(), (HostedProviders) runtime.getRuntimeConfig().getProviders(), aMetaAccess, aUniverse, hMetaAccess, hUniverse, nativeLibs, loader, false, true);
if (NativeImageOptions.PrintUniverse.getValue()) {
printTypes();
}
/* Find the entry point methods in the hosted world. */
for (AnalysisMethod m : aUniverse.getMethods()) {
if (m.isEntryPoint()) {
HostedMethod found = hUniverse.lookup(m);
assert found != null;
hostedEntryPoints.add(found);
}
}
/* Find main entry point */
if (mainEntryPoint != null) {
AnalysisMethod analysisStub = CEntryPointCallStubSupport.singleton().getStubForMethod(mainEntryPoint);
mainEntryPointHostedStub = (HostedMethod) hMetaAccess.getUniverse().lookup(analysisStub);
assert hostedEntryPoints.contains(mainEntryPointHostedStub);
} else {
mainEntryPointHostedStub = null;
}
if (hostedEntryPoints.size() == 0) {
throw UserError.abort("Warning: no entry points found, i.e., no method annotated with @" + CEntryPoint.class.getSimpleName());
}
heap = new NativeImageHeap(aUniverse, hUniverse, hMetaAccess);
BeforeCompilationAccessImpl config = new BeforeCompilationAccessImpl(featureHandler, loader, aUniverse, hUniverse, hMetaAccess, heap);
featureHandler.forEachFeature(feature -> feature.beforeCompilation(config));
bigbang.getUnsupportedFeatures().report(bigbang);
} catch (UnsupportedFeatureException ufe) {
throw UserError.abort(ufe.getMessage());
}
recordMethodsWithStackValues();
recordRestrictHeapAccessCallees(aUniverse.getMethods());
/*
* After this point, all TypeFlow (and therefore also TypeState) objects are unreachable
* and can be garbage collected. This is important to keep the overall memory footprint
* low. However, this also means we no longer have complete call chain information. Only
* the summarized information stored in the StaticAnalysisResult objects is available
* after this point.
*/
bigbang.cleanupAfterAnalysis();
NativeImageCodeCache codeCache;
CompileQueue compileQueue;
try (StopTimer t = new Timer("compile").start()) {
compileQueue = HostedConfiguration.instance().createCompileQueue(debug, featureHandler, hUniverse, runtime, NativeImageOptions.DeoptimizeAll.getValue(), aSnippetReflection, compilationExecutor);
compileQueue.finish(debug);
/* release memory taken by graphs for the image writing */
hUniverse.getMethods().forEach(HostedMethod::clear);
codeCache = new NativeImageCodeCache(compileQueue.getCompilations(), heap);
codeCache.layoutMethods(debug);
codeCache.layoutConstants();
AfterCompilationAccessImpl config = new AfterCompilationAccessImpl(featureHandler, loader, aUniverse, hUniverse, hMetaAccess, heap);
featureHandler.forEachFeature(feature -> feature.afterCompilation(config));
}
try (Indent indent = debug.logAndIndent("create native image")) {
try (DebugContext.Scope buildScope = debug.scope("CreateBootImage")) {
try (StopTimer t = new Timer("image").start()) {
// Start building the model of the native image heap.
heap.addInitialObjects(debug);
// Then build the model of the code cache, which can
// add objects to the native image heap.
codeCache.addConstantsToHeap(debug);
// Finish building the model of the native image heap.
heap.addTrailingObjects(debug);
AfterHeapLayoutAccessImpl config = new AfterHeapLayoutAccessImpl(featureHandler, loader, hMetaAccess);
featureHandler.forEachFeature(feature -> feature.afterHeapLayout(config));
this.image = AbstractBootImage.create(k, hUniverse, hMetaAccess, nativeLibs, heap, codeCache, hostedEntryPoints, mainEntryPointHostedStub);
image.build(debug);
if (NativeImageOptions.PrintUniverse.getValue()) {
/*
* This debug output must be printed _after_ and not _during_ image
* building, because it adds some PrintStream objects to static fields,
* which disrupts the heap.
*/
codeCache.printCompilationResults();
}
}
}
}
BeforeImageWriteAccessImpl beforeConfig = new BeforeImageWriteAccessImpl(featureHandler, loader, imageName, image, runtime.getRuntimeConfig(), aUniverse, hUniverse, optionProvider, hMetaAccess);
featureHandler.forEachFeature(feature -> feature.beforeImageWrite(beforeConfig));
try (StopTimer t = new Timer("write").start()) {
/*
* This will write the debug info too -- i.e. we may be writing more than one file,
* if the debug info is in a separate file. We need to push writing the file to the
* image implementation, because whether the debug info and image share a file or
* not is an implementation detail of the image.
*/
Path tmpDir = tempDirectory();
Path imagePath = image.write(debug, generatedFiles(HostedOptionValues.singleton()), tmpDir, imageName, beforeConfig);
AfterImageWriteAccessImpl afterConfig = new AfterImageWriteAccessImpl(featureHandler, loader, imagePath, tmpDir, image.getBootImageKind());
featureHandler.forEachFeature(feature -> feature.afterImageWrite(afterConfig));
}
}
}
Aggregations