use of com.oracle.graal.pointsto.meta.AnalysisType in project graal by oracle.
the class MethodTypeFlowBuilder method apply.
protected void apply() {
// assert method.getAnnotation(Fold.class) == null : method;
if (method.getAnnotation(NodeIntrinsic.class) != null) {
graph.getDebug().log("apply MethodTypeFlow on node intrinsic %s", method);
AnalysisType returnType = (AnalysisType) method.getSignature().getReturnType(method.getDeclaringClass());
if (returnType.getJavaKind() == JavaKind.Object) {
/*
* This is a method used in a snippet, so most likely the return value does not
* matter at all. However, some methods return an object, and the snippet continues
* to work with the object. So pretend that this method returns an object of the
* exact return type.
*/
TypeFlow<?> returnTypeFlow = methodFlow.getResultFlow().getDeclaredType().getTypeFlow(this.bb, true);
returnTypeFlow = new ProxyTypeFlow(null, returnTypeFlow);
FormalReturnTypeFlow resultFlow = new FormalReturnTypeFlow(null, returnType, method);
returnTypeFlow.addOriginalUse(this.bb, resultFlow);
methodFlow.addMiscEntry(returnTypeFlow);
methodFlow.setResult(resultFlow);
}
return;
}
if (!parse()) {
return;
}
this.bb.getUnsupportedFeatures().checkMethod(method, graph);
processedNodes = new NodeBitMap(graph);
TypeFlowsOfNodes typeFlows = new TypeFlowsOfNodes();
for (Node n : graph.getNodes()) {
if (n instanceof ParameterNode) {
ParameterNode node = (ParameterNode) n;
if (node.getStackKind() == JavaKind.Object) {
TypeFlowBuilder<?> paramBuilder = TypeFlowBuilder.create(bb, node, FormalParamTypeFlow.class, () -> {
boolean isStatic = Modifier.isStatic(method.getModifiers());
int index = node.index();
FormalParamTypeFlow parameter;
if (!isStatic && index == 0) {
AnalysisType paramType = method.getDeclaringClass();
parameter = new FormalReceiverTypeFlow(node, paramType, method);
} else {
int offset = isStatic ? 0 : 1;
AnalysisType paramType = (AnalysisType) method.getSignature().getParameterType(index - offset, method.getDeclaringClass());
parameter = new FormalParamTypeFlow(node, paramType, method, index);
}
methodFlow.setParameter(index, parameter);
return parameter;
});
typeFlowGraphBuilder.checkFormalParameterBuilder(paramBuilder);
typeFlows.add(node, paramBuilder);
}
} else if (n instanceof BoxNode) {
BoxNode node = (BoxNode) n;
Object key = uniqueKey(node);
BytecodeLocation boxSite = bb.analysisPolicy().createAllocationSite(bb, key, methodFlow.getMethod());
AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
TypeFlowBuilder<?> boxBuilder = TypeFlowBuilder.create(bb, node, BoxTypeFlow.class, () -> {
BoxTypeFlow boxFlow = new BoxTypeFlow(node, type, boxSite);
methodFlow.addAllocation(boxFlow);
return boxFlow;
});
typeFlows.add(node, boxBuilder);
}
for (Node input : n.inputs()) {
/*
* TODO change the handling of constants so that the SourceTypeFlow is created on
* demand, with the optimization that only one SourceTypeFlow is created ever for
* every distinct object (using, e.g., caching in a global IdentityHashMap).
*/
if (input instanceof ConstantNode && !typeFlows.contains((ConstantNode) input)) {
ConstantNode node = (ConstantNode) input;
if (node.asJavaConstant().isNull()) {
TypeFlowBuilder<SourceTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, SourceTypeFlow.class, () -> {
SourceTypeFlow constantSource = new SourceTypeFlow(node, TypeState.forNull());
methodFlow.addSource(constantSource);
return constantSource;
});
typeFlows.add(node, sourceBuilder);
} else if (node.asJavaConstant().getJavaKind() == JavaKind.Object) {
/*
* TODO a SubstrateObjectConstant wrapping a PrimitiveConstant has kind
* equals to Object. Do we care about the effective value of these primitive
* constants in the analysis?
*/
assert StampTool.isExactType(node);
AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
assert type.isInstantiated();
TypeFlowBuilder<SourceTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, SourceTypeFlow.class, () -> {
SourceTypeFlow constantSource = new SourceTypeFlow(node, TypeState.forConstant(this.bb, node.asJavaConstant(), type));
methodFlow.addSource(constantSource);
return constantSource;
});
typeFlows.add(node, sourceBuilder);
}
}
}
}
// Propagate the type flows through the method's graph
new NodeIterator(graph.start(), typeFlows).apply();
/* Prune the method graph. Eliminate nodes with no uses. */
typeFlowGraphBuilder.build();
/*
* Make sure that all existing InstanceOfNodes are registered even when only used as an
* input of a conditional.
*/
for (Node n : graph.getNodes()) {
if (n instanceof InstanceOfNode) {
InstanceOfNode instanceOf = (InstanceOfNode) n;
markFieldsUsedInComparison(instanceOf.getValue());
} else if (n instanceof ObjectEqualsNode) {
ObjectEqualsNode compareNode = (ObjectEqualsNode) n;
markFieldsUsedInComparison(compareNode.getX());
markFieldsUsedInComparison(compareNode.getY());
}
}
}
use of com.oracle.graal.pointsto.meta.AnalysisType in project graal by oracle.
the class TypeStateUtils method holdsSingleTypeState.
@SuppressWarnings("RedundantIfStatement")
static boolean holdsSingleTypeState(AnalysisObject[] objects, int size) {
assert size > 0;
AnalysisType firstType = objects[0].type();
AnalysisType lastType = objects[size - 1].type();
if (firstType.equals(lastType)) {
/* Objects are sorted, first and last have the same type, must be single type. */
return true;
}
return false;
}
use of com.oracle.graal.pointsto.meta.AnalysisType in project graal by oracle.
the class NativeImageGenerator method checkUniverse.
private void checkUniverse() {
/*
* Check that the type states for method parameters and fields are compatible with the
* declared type. This is required for interface types because interfaces are not trusted
* according to the Java language specification, but we trust all interface types (see
* HostedType.isTrustedInterfaceType)
*
* TODO Enable checks for non-interface types too.
*/
for (AnalysisMethod method : aUniverse.getMethods()) {
for (int i = 0; i < method.getTypeFlow().getOriginalMethodFlows().getParameters().length; i++) {
TypeState state = method.getTypeFlow().getParameterTypeState(bigbang, i);
if (state != null) {
AnalysisType declaredType = method.getTypeFlow().getOriginalMethodFlows().getParameter(i).getDeclaredType();
if (declaredType.isInterface()) {
state = TypeState.forSubtraction(bigbang, state, declaredType.getTypeFlow(bigbang, true).getState());
if (!state.isEmpty()) {
bigbang.getUnsupportedFeatures().addMessage(method.format("%H.%n(%p)"), method, "Method parameter " + i + " has declaredType " + declaredType.toJavaName(true) + " and incompatible types in state: " + state);
}
}
}
}
}
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()) {
bigbang.getUnsupportedFeatures().addMessage(field.format("%H.%n"), null, "Field has declaredType " + declaredType.toJavaName(true) + " and incompatible 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.isInstantiated() || type.isInTypeCheck())) {
checkName(type.toJavaName(true), null);
}
}
}
/*
* Entry points use a different calling convention (the native C ABI calling convention), so
* they must not be called from other Java methods.
*/
for (AnalysisMethod method : aUniverse.getMethods()) {
if (method.isEntryPoint()) {
List<AnalysisMethod> invocations = method.getJavaInvocations();
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());
}
}
}
// the unsupported features are reported after checkUniverse is invoked
}
use of com.oracle.graal.pointsto.meta.AnalysisType 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));
}
}
}
use of com.oracle.graal.pointsto.meta.AnalysisType in project graal by oracle.
the class Inflation method handleUnknownValueField.
private void handleUnknownValueField(AnalysisField field) {
if (handledUnknownValueFields.contains(field)) {
return;
}
UnknownObjectField unknownObjectField = field.getAnnotation(UnknownObjectField.class);
UnknownPrimitiveField unknownPrimitiveField = field.getAnnotation(UnknownPrimitiveField.class);
if (unknownObjectField != null) {
assert !Modifier.isFinal(field.getModifiers()) : "@UnknownObjectField annotated field " + field.format("%H.%n") + " cannot be final";
assert field.getJavaKind() == JavaKind.Object;
field.setCanBeNull(unknownObjectField.canBeNull());
List<AnalysisType> aAnnotationTypes = extractAnnotationTypes(field, unknownObjectField);
/*
* Only if an UnknownValue field is really accessed, we register all the field's
* sub-types as allocated.
*/
if (field.isAccessed()) {
for (AnalysisType type : aAnnotationTypes) {
type.registerAsAllocated(null);
}
}
/*
* Use the annotation types, instead of the declared type, in the UnknownObjectField
* annotated fields initialization.
*/
handleUnknownObjectField(field, aAnnotationTypes.toArray(new AnalysisType[aAnnotationTypes.size()]));
} else if (unknownPrimitiveField != null) {
assert !Modifier.isFinal(field.getModifiers()) : "@UnknownPrimitiveField annotated field " + field.format("%H.%n") + " cannot be final";
/*
* Register a primitive field as containing unknown values(s), i.e., is usually written
* only in hosted code.
*/
field.registerAsWritten(null);
}
handledUnknownValueFields.add(field);
}
Aggregations