use of org.graalvm.compiler.debug.DebugCloseable in project graal by oracle.
the class BytecodeParser method appendLoopBegin.
@SuppressWarnings("try")
private LoopBeginNode appendLoopBegin(FixedWithNextNode fixedWithNext, int startBci) {
try (DebugCloseable context = openNodeContext(frameState, startBci)) {
EndNode preLoopEnd = graph.add(new EndNode());
LoopBeginNode loopBegin = graph.add(new LoopBeginNode());
if (disableLoopSafepoint()) {
loopBegin.disableSafepoint();
}
fixedWithNext.setNext(preLoopEnd);
// Add the single non-loop predecessor of the loop header.
loopBegin.addForwardEnd(preLoopEnd);
return loopBegin;
}
}
use of org.graalvm.compiler.debug.DebugCloseable in project graal by oracle.
the class BytecodeParser method createTarget.
@SuppressWarnings("try")
private FixedNode createTarget(BciBlock block, FrameStateBuilder state, boolean canReuseInstruction, boolean canReuseState) {
assert block != null && state != null;
assert !block.isExceptionEntry || state.stackSize() == 1;
try (DebugCloseable context = openNodeContext(state, block.startBci)) {
if (getFirstInstruction(block) == null) {
/*
* This is the first time we see this block as a branch target. Create and return a
* placeholder that later can be replaced with a MergeNode when we see this block
* again.
*/
FixedNode targetNode;
if (canReuseInstruction && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) {
setFirstInstruction(block, lastInstr);
lastInstr = null;
} else {
setFirstInstruction(block, graph.add(new BeginNode()));
}
targetNode = getFirstInstruction(block);
Target target = checkLoopExit(targetNode, block, state);
FixedNode result = target.fixed;
FrameStateBuilder currentEntryState = target.state == state ? (canReuseState ? state : state.copy()) : target.state;
setEntryState(block, currentEntryState);
currentEntryState.clearNonLiveLocals(block, liveness, true);
debug.log("createTarget %s: first visit, result: %s", block, targetNode);
return result;
}
// We already saw this block before, so we have to merge states.
if (!getEntryState(block).isCompatibleWith(state)) {
throw bailout("stacks do not match; bytecodes would not verify");
}
if (getFirstInstruction(block) instanceof LoopBeginNode) {
assert (block.isLoopHeader && currentBlock.getId() >= block.getId()) : "must be backward branch";
/*
* Backward loop edge. We need to create a special LoopEndNode and merge with the
* loop begin node created before.
*/
LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block);
LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin));
Target target = checkLoopExit(loopEnd, block, state);
FixedNode result = target.fixed;
getEntryState(block).merge(loopBegin, target.state);
debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result);
return result;
}
assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch";
assert getFirstInstruction(block).next() == null : "bytecodes already parsed for block";
if (getFirstInstruction(block) instanceof AbstractBeginNode && !(getFirstInstruction(block) instanceof AbstractMergeNode)) {
/*
* This is the second time we see this block. Create the actual MergeNode and the
* End Node for the already existing edge.
*/
AbstractBeginNode beginNode = (AbstractBeginNode) getFirstInstruction(block);
// The EndNode for the already existing edge.
EndNode end = graph.add(new EndNode());
// The MergeNode that replaces the placeholder.
AbstractMergeNode mergeNode = graph.add(new MergeNode());
FixedNode next = beginNode.next();
if (beginNode.predecessor() instanceof ControlSplitNode) {
beginNode.setNext(end);
} else {
beginNode.replaceAtPredecessor(end);
beginNode.safeDelete();
}
mergeNode.addForwardEnd(end);
mergeNode.setNext(next);
setFirstInstruction(block, mergeNode);
}
AbstractMergeNode mergeNode = (AbstractMergeNode) getFirstInstruction(block);
// The EndNode for the newly merged edge.
EndNode newEnd = graph.add(new EndNode());
Target target = checkLoopExit(newEnd, block, state);
FixedNode result = target.fixed;
getEntryState(block).merge(mergeNode, target.state);
mergeNode.addForwardEnd(newEnd);
debug.log("createTarget %s: merging state, result: %s", block, result);
return result;
}
}
use of org.graalvm.compiler.debug.DebugCloseable in project graal by oracle.
the class CheckGraalInvariants method runTest.
@SuppressWarnings("try")
public static void runTest(InvariantsTool tool) {
RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class);
Providers providers = rt.getHostBackend().getProviders();
MetaAccessProvider metaAccess = providers.getMetaAccess();
PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
Plugins plugins = new Plugins(new InvocationPlugins());
GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus());
String bootclasspath = tool.getClassPath();
Assert.assertNotNull("Cannot find boot class path", bootclasspath);
final List<String> classNames = new ArrayList<>();
for (String path : bootclasspath.split(File.pathSeparator)) {
if (tool.shouldProcess(path)) {
try {
final ZipFile zipFile = new ZipFile(new File(path));
for (final Enumeration<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements(); ) {
final ZipEntry zipEntry = entry.nextElement();
String name = zipEntry.getName();
if (name.endsWith(".class") && !name.startsWith("META-INF/versions/")) {
String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
if (isInNativeImage(className)) {
/*
* Native Image is an external tool and does not need to follow the
* Graal invariants.
*/
continue;
}
classNames.add(className);
}
}
} catch (IOException ex) {
Assert.fail(ex.toString());
}
}
}
Assert.assertFalse("Could not find graal jars on boot class path: " + bootclasspath, classNames.isEmpty());
// Allows a subset of methods to be checked through use of a system property
String property = System.getProperty(CheckGraalInvariants.class.getName() + ".filters");
String[] filters = property == null ? null : property.split(",");
OptionValues options = getInitialOptions();
CompilerThreadFactory factory = new CompilerThreadFactory("CheckInvariantsThread");
int availableProcessors = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(availableProcessors, availableProcessors, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
List<String> errors = Collections.synchronizedList(new ArrayList<>());
for (Method m : BadUsageWithEquals.class.getDeclaredMethods()) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).method(method).build();
try (DebugCloseable s = debug.disableIntercept();
DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
graphBuilderSuite.apply(graph, context);
// update phi stamps
graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
checkGraph(context, graph);
errors.add(String.format("Expected error while checking %s", m));
} catch (VerificationError e) {
// expected!
} catch (Throwable e) {
errors.add(String.format("Error while checking %s:%n%s", m, printStackTraceToString(e)));
}
}
}
if (errors.isEmpty()) {
// Order outer classes before the inner classes
classNames.sort((String a, String b) -> a.compareTo(b));
// Initialize classes in single thread to avoid deadlocking issues during initialization
List<Class<?>> classes = initializeClasses(tool, classNames);
for (Class<?> c : classes) {
String className = c.getName();
executor.execute(() -> {
try {
checkClass(c, metaAccess);
} catch (Throwable e) {
errors.add(String.format("Error while checking %s:%n%s", className, printStackTraceToString(e)));
}
});
for (Method m : c.getDeclaredMethods()) {
if (Modifier.isNative(m.getModifiers()) || Modifier.isAbstract(m.getModifiers())) {
// ignore
} else {
String methodName = className + "." + m.getName();
if (matches(filters, methodName)) {
executor.execute(() -> {
try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).build();
try (DebugCloseable s = debug.disableIntercept();
DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
checkMethod(method);
graphBuilderSuite.apply(graph, context);
// update phi stamps
graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
checkGraph(context, graph);
} catch (VerificationError e) {
errors.add(e.getMessage());
} catch (LinkageError e) {
// suppress linkages errors resulting from eager resolution
} catch (BailoutException e) {
// Graal bail outs on certain patterns in Java bytecode
// (e.g.,
// unbalanced monitors introduced by jacoco).
} catch (Throwable e) {
try {
tool.handleParsingException(e);
} catch (Throwable t) {
errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e)));
}
}
}
});
}
}
}
}
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
}
if (!errors.isEmpty()) {
StringBuilder msg = new StringBuilder();
String nl = String.format("%n");
for (String e : errors) {
if (msg.length() != 0) {
msg.append(nl);
}
msg.append(e);
}
Assert.fail(msg.toString());
}
}
use of org.graalvm.compiler.debug.DebugCloseable in project graal by oracle.
the class WriteBarrierAdditionPhase method run.
@SuppressWarnings("try")
@Override
protected void run(StructuredGraph graph) {
for (Node n : graph.getNodes()) {
try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) {
if (n instanceof ReadNode) {
addReadNodeBarriers((ReadNode) n, graph);
} else if (n instanceof WriteNode) {
addWriteNodeBarriers((WriteNode) n, graph);
} else if (n instanceof LoweredAtomicReadAndWriteNode) {
LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n;
addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph);
} else if (n instanceof AbstractCompareAndSwapNode) {
addCASBarriers((AbstractCompareAndSwapNode) n, graph);
} else if (n instanceof ArrayRangeWrite) {
ArrayRangeWrite node = (ArrayRangeWrite) n;
if (node.writesObjectArray()) {
addArrayRangeBarriers(node, graph);
}
}
}
}
}
use of org.graalvm.compiler.debug.DebugCloseable in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method propagateFixed.
@SuppressWarnings("try")
private void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, LoweringProvider loweringProvider) {
Node current = from;
while (current != null) {
if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
FixedGuardNode otherGuard = (FixedGuardNode) current;
if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
moveAsDeoptAfter(otherGuard, deopt);
return;
}
} else if (current instanceof AbstractBeginNode) {
if (current instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) current;
FixedNode next = mergeNode.next();
while (mergeNode.isAlive()) {
AbstractEndNode end = mergeNode.forwardEnds().first();
propagateFixed(end, deopt, loweringProvider);
}
assert next.isAlive();
propagateFixed(next, deopt, loweringProvider);
return;
} else if (current.predecessor() instanceof IfNode) {
IfNode ifNode = (IfNode) current.predecessor();
// Prioritize the source position of the IfNode
try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
StructuredGraph graph = ifNode.graph();
LogicNode conditionNode = ifNode.condition();
boolean negateGuardCondition = current == ifNode.trueSuccessor();
FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition));
FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
AbstractBeginNode survivingSuccessor;
if (negateGuardCondition) {
survivingSuccessor = ifNode.falseSuccessor();
} else {
survivingSuccessor = ifNode.trueSuccessor();
}
graph.removeSplitPropagate(ifNode, survivingSuccessor);
Node newGuard = guard;
if (survivingSuccessor instanceof LoopExitNode) {
newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
}
survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
FixedNode next = pred.next();
pred.setNext(guard);
guard.setNext(next);
SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
survivingSuccessor.simplify(simplifierTool);
return;
}
} else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
moveAsDeoptAfter((AbstractBeginNode) current, deopt);
return;
}
}
current = current.predecessor();
}
}
Aggregations