use of com.oracle.graal.pointsto.util.Timer.StopTimer in project graal by oracle.
the class BigBang method finish.
/**
* Performs the analysis.
*
* @return Returns true if any changes are made, i.e. if any type flows are updated
*/
@SuppressWarnings("try")
public boolean finish() throws InterruptedException {
try (Indent indent = debug.logAndIndent("starting analysis in BigBang.finish")) {
universe.setAnalysisDataValid(this, false);
boolean didSomeWork = false;
int numTypes;
do {
try (StopTimer t = typeFlowTimer.start()) {
executor.start();
executor.complete();
didSomeWork |= (executor.getPostedOperations() > 0);
executor.shutdown();
}
/* Initialize for the next iteration. */
executor.init(timing);
/*
* Check if the object graph introduces any new types, which leads to new operations
* being posted.
*/
assert executor.getPostedOperations() == 0;
numTypes = universe.getTypes().size();
try (StopTimer t = checkObjectsTimer.start()) {
// track static fields
checkObjectGraph();
}
} while (executor.getPostedOperations() != 0 || numTypes != universe.getTypes().size());
universe.setAnalysisDataValid(this, true);
if (PointstoOptions.ReportUnsupportedFeaturesDuringAnalysis.getValue(options)) {
unsupportedFeatures.report(this);
}
return didSomeWork;
}
}
use of com.oracle.graal.pointsto.util.Timer.StopTimer in project graal by oracle.
the class NativeImageGenerator method processNativeLibraryImports.
@SuppressWarnings("try")
private NativeLibraries processNativeLibraryImports(MetaAccessProvider metaAccess, AnalysisConstantReflectionProvider aConstantReflection, SnippetReflectionProvider snippetReflection) {
CAnnotationProcessorCache.initialize();
try (StopTimer t = new Timer("(cap)").start()) {
NativeLibraries nativeLibs = new NativeLibraries(aConstantReflection, metaAccess, snippetReflection, ConfigurationValues.getTarget());
for (Method method : loader.findAnnotatedMethods(CConstant.class)) {
nativeLibs.loadJavaMethod(metaAccess.lookupJavaMethod(method));
}
for (Class<?> clazz : loader.findAnnotatedClasses(CStruct.class)) {
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
for (Class<?> clazz : loader.findAnnotatedClasses(RawStructure.class)) {
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
for (Class<?> clazz : loader.findAnnotatedClasses(CPointerTo.class)) {
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
for (Class<?> clazz : loader.findAnnotatedClasses(CEnum.class)) {
nativeLibs.loadJavaType(metaAccess.lookupJavaType(clazz));
}
for (CLibrary library : loader.findAnnotations(CLibrary.class)) {
nativeLibs.addLibrary(library.value());
}
nativeLibs.finish(tempDirectory());
nativeLibs.reportErrors();
return nativeLibs;
}
}
use of com.oracle.graal.pointsto.util.Timer.StopTimer in project graal by oracle.
the class NativeImageGeneratorRunner method buildImage.
@SuppressWarnings("try")
private int buildImage(String[] arguments, String[] classpath, ClassLoader classLoader) {
if (!verifyValidJavaVersionAndPlatform()) {
return -1;
}
Timer totalTimer = new Timer("[total]", false);
ForkJoinPool analysisExecutor = null;
ForkJoinPool compilationExecutor = null;
try (StopTimer ignored = totalTimer.start()) {
ImageClassLoader imageClassLoader;
Timer classlistTimer = new Timer("classlist", false);
try (StopTimer ignored1 = classlistTimer.start()) {
imageClassLoader = ImageClassLoader.create(defaultPlatform(), classpath, classLoader);
}
HostedOptionParser optionParser = new HostedOptionParser(imageClassLoader);
String[] remainingArgs = optionParser.parse(arguments);
if (remainingArgs.length > 0) {
throw UserError.abort("Unknown options: " + Arrays.toString(remainingArgs));
}
/*
* We do not have the VMConfiguration and the HostedOptionValues set up yet, so we need
* to pass the OptionValues explicitly when accessing options.
*/
OptionValues parsedHostedOptions = new OptionValues(optionParser.getHostedValues());
DebugContext debug = DebugContext.create(parsedHostedOptions, new GraalDebugHandlersFactory(GraalAccess.getOriginalSnippetReflection()));
String imageName = NativeImageOptions.Name.getValue(parsedHostedOptions);
if (imageName.length() == 0) {
throw UserError.abort("No output file name specified. " + "Use '" + SubstrateOptionsParser.commandArgument(NativeImageOptions.Name, "<output-file>") + "'.");
}
// print the time here to avoid interactions with flags processing
classlistTimer.print();
Map<Method, CEntryPointData> entryPoints = new HashMap<>();
Method mainEntryPoint = null;
JavaMainSupport javaMainSupport = null;
AbstractBootImage.NativeImageKind k = AbstractBootImage.NativeImageKind.valueOf(NativeImageOptions.Kind.getValue(parsedHostedOptions));
if (k == AbstractBootImage.NativeImageKind.EXECUTABLE) {
String className = NativeImageOptions.Class.getValue(parsedHostedOptions);
if (className == null || className.length() == 0) {
throw UserError.abort("Must specify main entry point class when building " + AbstractBootImage.NativeImageKind.EXECUTABLE + " native image. " + "Use '" + SubstrateOptionsParser.commandArgument(NativeImageOptions.Class, "<fully-qualified-class-name>") + "'.");
}
Class<?> mainClass;
try {
mainClass = Class.forName(className, false, classLoader);
} catch (ClassNotFoundException ex) {
throw UserError.abort("Main entry point class '" + className + "' not found.");
}
String mainEntryPointName = NativeImageOptions.Method.getValue(parsedHostedOptions);
if (mainEntryPointName == null || mainEntryPointName.length() == 0) {
throw UserError.abort("Must specify main entry point method when building " + AbstractBootImage.NativeImageKind.EXECUTABLE + " native image. " + "Use '" + SubstrateOptionsParser.commandArgument(NativeImageOptions.Method, "<method-name>") + "'.");
}
try {
/* First look for an main method with the C-level signature for arguments. */
mainEntryPoint = mainClass.getDeclaredMethod(mainEntryPointName, int.class, CCharPointerPointer.class);
} catch (NoSuchMethodException ignored2) {
try {
/*
* If no C-level main method was found, look for a Java-level main method
* and use our wrapper to invoke it.
*/
Method javaMainMethod = mainClass.getDeclaredMethod(mainEntryPointName, String[].class);
javaMainMethod.setAccessible(true);
if (javaMainMethod.getReturnType() != void.class) {
throw UserError.abort("Java main method must have return type void. Change the return type of method '" + mainClass.getName() + "." + mainEntryPointName + "(String[])'.");
}
final int mainMethodModifiers = javaMainMethod.getModifiers();
if (!Modifier.isPublic(mainMethodModifiers)) {
throw UserError.abort("Method '" + mainClass.getName() + "." + mainEntryPointName + "(String[])' is not accessible. Please make it 'public'.");
}
javaMainSupport = new JavaMainSupport(javaMainMethod);
mainEntryPoint = JavaMainWrapper.class.getDeclaredMethod("run", int.class, CCharPointerPointer.class);
} catch (NoSuchMethodException ex) {
throw UserError.abort("Method '" + mainClass.getName() + "." + mainEntryPointName + "' is declared as the main entry point but it can not be found. " + "Make sure that class '" + mainClass.getName() + "' is on the classpath and that method '" + mainEntryPointName + "(String[])' exists in that class.");
}
}
CEntryPoint annotation = mainEntryPoint.getAnnotation(CEntryPoint.class);
if (annotation == null) {
throw UserError.abort("Entry point must have the '@" + CEntryPoint.class.getSimpleName() + "' annotation");
}
entryPoints.put(mainEntryPoint, CEntryPointData.create(mainEntryPoint));
Class<?>[] pt = mainEntryPoint.getParameterTypes();
if (pt.length != 2 || pt[0] != int.class || pt[1] != CCharPointerPointer.class || mainEntryPoint.getReturnType() != int.class) {
throw UserError.abort("Main entry point must have signature 'int main(int argc, CCharPointerPointer argv)'.");
}
}
int maxConcurrentThreads = NativeImageOptions.getMaximumNumberOfConcurrentThreads(parsedHostedOptions);
analysisExecutor = Inflation.createExecutor(debug, NativeImageOptions.getMaximumNumberOfAnalysisThreads(parsedHostedOptions));
compilationExecutor = Inflation.createExecutor(debug, maxConcurrentThreads);
generator = new NativeImageGenerator(imageClassLoader, optionParser);
generator.run(entryPoints, mainEntryPoint, javaMainSupport, imageName, k, SubstitutionProcessor.IDENTITY, analysisExecutor, compilationExecutor, optionParser.getRuntimeOptionNames());
} catch (InterruptImageBuilding e) {
if (analysisExecutor != null) {
analysisExecutor.shutdownNow();
}
if (compilationExecutor != null) {
compilationExecutor.shutdownNow();
}
e.getReason().ifPresent(NativeImageGeneratorRunner::info);
return 0;
} catch (UserException e) {
e.getMessages().iterator().forEachRemaining(NativeImageGeneratorRunner::reportUserError);
return -1;
} catch (AnalysisError e) {
NativeImageGeneratorRunner.reportUserError(e.getMessage());
return -1;
} catch (ParallelExecutionException pee) {
boolean hasUserError = false;
for (Throwable exception : pee.getExceptions()) {
if (exception instanceof UserException) {
((UserException) exception).getMessages().iterator().forEachRemaining(NativeImageGeneratorRunner::reportUserError);
hasUserError = true;
} else if (exception instanceof AnalysisError) {
NativeImageGeneratorRunner.reportUserError(exception.getMessage());
hasUserError = true;
}
}
if (hasUserError) {
return -1;
}
if (pee.getExceptions().size() > 1) {
System.err.println(pee.getExceptions().size() + " fatal errors detected:");
}
for (Throwable exception : pee.getExceptions()) {
NativeImageGeneratorRunner.reportFatalError(exception);
}
return -1;
} catch (Throwable e) {
NativeImageGeneratorRunner.reportFatalError(e);
return -1;
}
totalTimer.print();
return 0;
}
use of com.oracle.graal.pointsto.util.Timer.StopTimer in project graal by oracle.
the class CompileQueue method finish.
@SuppressWarnings("try")
public void finish(DebugContext debug) {
try {
try (StopTimer t = new Timer("(parse)").start()) {
parseAll();
}
// Checking @Uninterruptible annotations does not take long enough to justify a timer.
UninterruptibleAnnotationChecker.check(debug, universe.getMethods());
// Checking @RestrictHeapAccess annotations does not take long enough to justify a
// timer.
RestrictHeapAccessAnnotationChecker.check(debug, universe, universe.getMethods());
// Checking @MustNotSynchronize annotations does not take long enough to justify a
// timer.
MustNotSynchronizeAnnotationChecker.check(debug, universe.getMethods());
beforeCompileAll(debug);
if (SubstrateOptions.AOTInline.getValue()) {
try (StopTimer ignored = new Timer("(inline)").start()) {
inlineTrivialMethods(debug);
}
}
try (StopTimer t = new Timer("(compile)").start()) {
compileAll();
}
} catch (InterruptedException ie) {
throw new InterruptImageBuilding();
}
if (NativeImageOptions.PrintMethodHistogram.getValue()) {
printMethodHistogram();
}
}
use of com.oracle.graal.pointsto.util.Timer.StopTimer 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