use of org.graalvm.compiler.debug.DebugContext in project graal by oracle.
the class LocationMarker method processBlock.
@SuppressWarnings("try")
private void processBlock(AbstractBlockBase<?> block, UniqueWorkList worklist) {
if (updateOutBlock(block)) {
DebugContext debug = lir.getDebug();
try (Indent indent = debug.logAndIndent("handle block %s", block)) {
currentSet = liveOutMap.get(block).copy();
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
for (int i = instructions.size() - 1; i >= 0; i--) {
LIRInstruction inst = instructions.get(i);
processInstructionBottomUp(inst);
}
liveInMap.put(block, currentSet);
currentSet = null;
for (AbstractBlockBase<?> b : block.getPredecessors()) {
worklist.add(b);
}
}
}
}
use of org.graalvm.compiler.debug.DebugContext in project graal by oracle.
the class NativeImageGenerator method registerReplacements.
@SuppressWarnings("try")
public static void registerReplacements(DebugContext debug, FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, Providers providers, SnippetReflectionProvider snippetReflection, boolean hosted) {
OptionValues options = hosted ? HostedOptionValues.singleton() : RuntimeOptionValues.singleton();
Providers runtimeCallProviders = runtimeConfig != null ? runtimeConfig.getBackendForNormalMethod().getProviders() : providers;
SubstrateForeignCallsProvider foreignCallsProvider = (SubstrateForeignCallsProvider) providers.getForeignCalls();
for (SubstrateForeignCallDescriptor descriptor : SnippetRuntime.getRuntimeCalls()) {
foreignCallsProvider.getForeignCalls().put(descriptor, new SubstrateForeignCallLinkage(runtimeCallProviders, descriptor));
}
featureHandler.forEachGraalFeature(feature -> feature.registerForeignCalls(runtimeConfig, runtimeCallProviders, snippetReflection, foreignCallsProvider.getForeignCalls(), 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);
NonSnippetLowerings.registerLowerings(runtimeConfig, options, factories, providers, snippetReflection, lowerings);
ArithmeticSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
MonitorSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
TypeSnippets.registerLowerings(runtimeConfig, options, factories, providers, snippetReflection, lowerings);
ExceptionSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
if (hosted) {
AssertSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
DeoptHostedSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
} else {
DeoptRuntimeSnippets.registerLowerings(options, factories, providers, snippetReflection, lowerings);
}
if (NativeImageOptions.DeoptimizeAll.getValue()) {
DeoptTestSnippets.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();
}
use of org.graalvm.compiler.debug.DebugContext 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 org.graalvm.compiler.debug.DebugContext in project graal by oracle.
the class CompileQueue method defaultParseFunction.
@SuppressWarnings("try")
private void defaultParseFunction(DebugContext debug, HostedMethod method, CompileReason reason, RuntimeConfiguration config) {
if (method.getAnnotation(Fold.class) != null || method.getAnnotation(NodeIntrinsic.class) != null) {
throw VMError.shouldNotReachHere("Parsing method annotated with @Fold or @NodeIntrinsic: " + method.format("%H.%n(%p)"));
}
HostedProviders providers = (HostedProviders) config.lookupBackend(method).getProviders();
boolean needParsing = false;
OptionValues options = HostedOptionValues.singleton();
StructuredGraph graph = method.buildGraph(debug, method, providers, Purpose.AOT_COMPILATION);
if (graph == null) {
InvocationPlugin plugin = providers.getGraphBuilderPlugins().getInvocationPlugins().lookupInvocation(method);
if (plugin != null && !plugin.inlineOnly()) {
Bytecode code = new ResolvedJavaMethodBytecode(method);
// DebugContext debug = new DebugContext(options, providers.getSnippetReflection());
graph = new SubstrateIntrinsicGraphBuilder(debug.getOptions(), debug, providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getStampProvider(), code).buildGraph(plugin);
}
}
if (graph == null && method.isNative() && NativeImageOptions.ReportUnsupportedElementsAtRuntime.getValue()) {
graph = DeletedMethod.buildGraph(debug, method, providers, DeletedMethod.NATIVE_MESSAGE);
}
if (graph == null) {
needParsing = true;
if (!method.compilationInfo.isDeoptTarget()) {
/*
* Disabling liveness analysis preserves the values of local variables beyond the
* bytecode-liveness. This greatly helps debugging. When local variable numbers are
* reused by javac, local variables can still get illegal values. Since we cannot
* "restore" such illegal values during deoptimization, we must do liveness analysis
* for deoptimization target methods.
*/
options = new OptionValues(options, GraalOptions.OptClearNonLiveLocals, false);
}
graph = new StructuredGraph.Builder(options, debug).method(method).build();
}
try (DebugContext.Scope s = debug.scope("Parsing", graph, method, this)) {
try {
if (needParsing) {
GraphBuilderConfiguration gbConf = createHostedGraphBuilderConfiguration(providers, method);
new HostedGraphBuilderPhase(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), gbConf, optimisticOpts, null, providers.getWordTypes()).apply(graph);
} else {
graph.setGuardsStage(GuardsStage.FIXED_DEOPTS);
}
new DeadStoreRemovalPhase().apply(graph);
new DevirtualizeCallsPhase().apply(graph);
new CanonicalizerPhase().apply(graph, new PhaseContext(providers));
/*
* The StrengthenStampsPhase may not insert type check nodes for specialized
* methods, because we would get type state mismatches regarding Const<Type> !=
* <Type>
*/
/*
* cwimmer: the old, commented out, condition always disabled checking of static
* analysis results. Therefore, the checks are broken right now.
*/
// new StrengthenStampsPhase(BootImageOptions.CheckStaticAnalysisResults.getValue()
// && method.compilationInfo.deoptTarget != null &&
// !method.compilationInfo.isDeoptTarget).apply(graph);
new StrengthenStampsPhase(false).apply(graph);
new CanonicalizerPhase().apply(graph, new PhaseContext(providers));
/* Check that graph is in good shape after parsing. */
assert GraphOrder.assertSchedulableGraph(graph);
method.compilationInfo.graph = graph;
for (Invoke invoke : graph.getInvokes()) {
if (!canBeUsedForInlining(invoke)) {
invoke.setUseForInlining(false);
}
if (invoke.callTarget() instanceof MethodCallTargetNode) {
MethodCallTargetNode targetNode = (MethodCallTargetNode) invoke.callTarget();
HostedMethod invokeTarget = (HostedMethod) targetNode.targetMethod();
if (targetNode.invokeKind().isDirect()) {
if (invokeTarget.wrapped.isImplementationInvoked()) {
handleSpecialization(method, targetNode, invokeTarget, invokeTarget);
ensureParsed(invokeTarget, new DirectCallReason(method, reason));
}
} else {
for (HostedMethod invokeImplementation : invokeTarget.getImplementations()) {
handleSpecialization(method, targetNode, invokeTarget, invokeImplementation);
ensureParsed(invokeImplementation, new VirtualCallReason(method, invokeImplementation, reason));
}
}
}
}
} catch (Throwable ex) {
GraalError error = ex instanceof GraalError ? (GraalError) ex : new GraalError(ex);
error.addContext("method: " + method.format("%r %H.%n(%p)"));
throw error;
}
} catch (Throwable e) {
throw debug.handle(e);
}
}
use of org.graalvm.compiler.debug.DebugContext in project graal by oracle.
the class UninterruptibleAnnotationChecker method checkUninterruptibleCallees.
/**
* Check that each method annotated with {@link Uninterruptible} calls only methods that are
* also annotated with {@link Uninterruptible}, or methods annotated with {@link CFunction} that
* specify "Transition = NO_TRANSITION".
*
* A caller can be annotated with "calleeMustBe = false" to allow calls to methods that are not
* annotated with {@link Uninterruptible}, to allow the few cases where that should be allowed.
*/
@SuppressWarnings("try")
private void checkUninterruptibleCallees(DebugContext debug) {
if (Options.PrintUninterruptibleCalleeDOTGraph.getValue()) {
System.out.println("/* DOT */ digraph uninterruptible {");
}
for (HostedMethod caller : methodCollection) {
try (DebugContext.Scope s = debug.scope("CheckUninterruptibleCallees", caller.compilationInfo.graph, caller, this)) {
Uninterruptible callerAnnotation = caller.getAnnotation(Uninterruptible.class);
StructuredGraph graph = caller.compilationInfo.getGraph();
if (callerAnnotation != null) {
if (callerAnnotation.calleeMustBe()) {
if (graph != null) {
for (Invoke invoke : graph.getInvokes()) {
HostedMethod callee = (HostedMethod) invoke.callTarget().targetMethod();
if (Options.PrintUninterruptibleCalleeDOTGraph.getValue()) {
printDotGraphEdge(caller, callee);
}
if (!isNotInterruptible(callee)) {
postUninterruptibleWarning("Unannotated callee: " + callee.format("%h.%n(%p)") + " called by annotated caller " + caller.format("%h.%n(%p)"));
}
}
}
} else {
// Print DOT graph edge even if callee need not be annotated.
if (graph != null) {
for (Invoke invoke : graph.getInvokes()) {
HostedMethod callee = (HostedMethod) invoke.callTarget().targetMethod();
if (Options.PrintUninterruptibleCalleeDOTGraph.getValue()) {
printDotGraphEdge(caller, callee);
}
}
}
}
}
} catch (Throwable t) {
throw debug.handle(t);
}
}
if (Options.PrintUninterruptibleCalleeDOTGraph.getValue()) {
System.out.println("/* DOT */ }");
}
}
Aggregations