# HG changeset patch # User Michael Haupt # Date 1365666790 -7200 # Node ID a8fea2979e63092bd56811a220f5ef6c4fe5c6b8 # Parent 8ddaac81cb21c41f771ada9be700d7ae3f3a9ed8 eager infopoint mode (fka debug mode) diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Thu Apr 11 09:53:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,42 +52,45 @@ } /** - * Represents a safepoint with associated debug info. + * Represents an infopoint with associated debug info. Note that safepoints are also infopoints. */ - public static class Safepoint extends Site implements Comparable { + public static class Infopoint extends Site implements Comparable { private static final long serialVersionUID = 2479806696381720162L; public final DebugInfo debugInfo; - public Safepoint(int pcOffset, DebugInfo debugInfo) { + public final InfopointReason reason; + + public Infopoint(int pcOffset, DebugInfo debugInfo, InfopointReason reason) { super(pcOffset); this.debugInfo = debugInfo; + this.reason = reason; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(pcOffset); - sb.append("[]"); + sb.append("[]"); appendDebugInfo(sb, debugInfo); return sb.toString(); } @Override - public int compareTo(Safepoint o) { + public int compareTo(Infopoint o) { if (pcOffset < o.pcOffset) { return -1; } else if (pcOffset > o.pcOffset) { return 1; } - return 0; + return this.reason.compareTo(o.reason); } } /** * Represents a call in the code. */ - public static final class Call extends Safepoint { + public static final class Call extends Infopoint { private static final long serialVersionUID = 1440741241631046954L; @@ -109,7 +112,7 @@ public final boolean direct; public Call(InvokeTarget target, int pcOffset, int size, boolean direct, DebugInfo debugInfo) { - super(pcOffset, debugInfo); + super(pcOffset, debugInfo, InfopointReason.CALL); this.size = size; this.target = target; this.direct = direct; @@ -284,7 +287,7 @@ } } - private final List safepoints = new ArrayList<>(); + private final List infopoints = new ArrayList<>(); private final List dataReferences = new ArrayList<>(); private final List exceptionHandlers = new ArrayList<>(); private final List marks = new ArrayList<>(); @@ -377,7 +380,7 @@ */ public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) { final Call call = new Call(target, codePos, size, direct, debugInfo); - addSafepoint(call); + addInfopoint(call); } /** @@ -391,22 +394,22 @@ } /** - * Records a safepoint in the code array. + * Records an infopoint in the code array. * - * @param codePos the position of the safepoint in the code array - * @param debugInfo the debug info for the safepoint + * @param codePos the position of the infopoint in the code array + * @param debugInfo the debug info for the infopoint */ - public void recordSafepoint(int codePos, DebugInfo debugInfo) { - addSafepoint(new Safepoint(codePos, debugInfo)); + public void recordInfopoint(int codePos, DebugInfo debugInfo, InfopointReason reason) { + addInfopoint(new Infopoint(codePos, debugInfo, reason)); } - private void addSafepoint(Safepoint safepoint) { - // The safepoints list must always be sorted - if (!getSafepoints().isEmpty() && getSafepoints().get(getSafepoints().size() - 1).pcOffset >= safepoint.pcOffset) { + private void addInfopoint(Infopoint infopoint) { + // The infopoints list must always be sorted + if (!getInfopoints().isEmpty() && getInfopoints().get(getInfopoints().size() - 1).pcOffset >= infopoint.pcOffset) { // This re-sorting should be very rare - Collections.sort(getSafepoints()); + Collections.sort(getInfopoints()); } - getSafepoints().add(safepoint); + getInfopoints().add(infopoint); } /** @@ -522,10 +525,10 @@ } /** - * @return the list of safepoints, sorted by {@link Site#pcOffset} + * @return the list of infopoints, sorted by {@link Site#pcOffset} */ - public List getSafepoints() { - return safepoints; + public List getInfopoints() { + return infopoints; } /** diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InfopointReason.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InfopointReason.java Thu Apr 11 09:53:10 2013 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.code; + +/** + * A reason for infopoint insertion. + */ +public enum InfopointReason { + + UNKNOWN, SAFEPOINT, CALL, IMPLICIT_EXCEPTION, METHOD_START, METHOD_END, LINE_NUMBER; + +} diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Apr 11 09:53:10 2013 +0200 @@ -926,4 +926,9 @@ Value[] parameters = visitInvokeArguments(cc, node.arguments); append(new AMD64BreakpointOp(parameters)); } + + @Override + public void visitInfopointNode(InfopointNode i) { + append(new InfopointOp(stateFor(i.stateAfter(), DeoptimizationReason.None), i.reason)); + } } diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Thu Apr 11 09:53:10 2013 +0200 @@ -472,4 +472,9 @@ public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { throw new InternalError("NYI"); } + + @Override + public void visitInfopointNode(InfopointNode i) { + throw new InternalError("NYI"); + } } diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Apr 11 09:53:10 2013 +0200 @@ -368,4 +368,10 @@ // SPARC: Auto-generated method stub } + + @Override + public void visitInfopointNode(InfopointNode i) { + // SPARC: Auto-generated method stub + + } } diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Apr 11 09:53:10 2013 +0200 @@ -400,7 +400,8 @@ GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); editPhasePlan(method, graph, phasePlan); - CompilationResult compResult = GraalCompiler.compileMethod(runtime(), replacements, backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog()); + CompilationResult compResult = GraalCompiler.compileMethod(runtime(), replacements, backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL, + new SpeculationLog()); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); } @@ -442,25 +443,41 @@ * Parses a Java method to produce a graph. */ protected StructuredGraph parse(Method m) { - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(m); - StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); - return graph; + return parse0(m, GraphBuilderConfiguration.getEagerDefault()); } /** * Parses a Java method to produce a graph. */ protected StructuredGraph parseProfiled(Method m) { + return parse0(m, GraphBuilderConfiguration.getDefault()); + } + + /** + * Parses a Java method in debug mode to produce a graph with extra infopoints. + */ + protected StructuredGraph parseDebug(Method m) { + GraphBuilderConfiguration gbConf = GraphBuilderConfiguration.getEagerDefault(); + gbConf.setEagerInfopointMode(true); + return parse0(m, gbConf); + } + + private StructuredGraph parse0(Method m, GraphBuilderConfiguration conf) { ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(m); StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph); return graph; } protected PhasePlan getDefaultPhasePlan() { + return getDefaultPhasePlan(false); + } + + protected PhasePlan getDefaultPhasePlan(boolean eagerInfopointMode) { PhasePlan plan = new PhasePlan(); - plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL)); + GraphBuilderConfiguration gbConf = GraphBuilderConfiguration.getEagerDefault(); + gbConf.setEagerInfopointMode(eagerInfopointMode); + plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, gbConf, OptimisticOptimizations.ALL)); return plan; } } diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Thu Apr 11 09:53:10 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import static org.junit.Assert.*; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.Call; +import com.oracle.graal.api.code.CompilationResult.Infopoint; +import com.oracle.graal.compiler.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.*; + +/** + * Test that infopoints in {@link CompilationResult}s have correctly assigned reasons. + */ +public class InfopointReasonTest extends GraalCompilerTest { + + public static final String[] STRINGS = new String[]{"world", "everyone", "you"}; + + public String testMethod() { + StringBuilder sb = new StringBuilder("Hello "); + for (String s : STRINGS) { + sb.append(s).append(", "); + } + sb.replace(sb.length() - 2, sb.length(), "!"); + return sb.toString(); + } + + @Test + public void callInfopoints() { + final Method method = getMethod("testMethod"); + final StructuredGraph graph = parse(method); + final CompilationResult cr = GraalCompiler.compileMethod(runtime, replacements, backend, runtime.getTarget(), runtime.lookupJavaMethod(method), graph, null, getDefaultPhasePlan(), + OptimisticOptimizations.ALL, new SpeculationLog()); + for (Infopoint sp : cr.getInfopoints()) { + assertNotNull(sp.reason); + if (sp instanceof Call) { + assertEquals(InfopointReason.CALL, sp.reason); + } + } + } + + @Test + public void lineInfopoints() { + final Method method = getMethod("testMethod"); + final StructuredGraph graph = parseDebug(method); + int graphLineSPs = 0; + for (InfopointNode ipn : graph.getNodes(InfopointNode.class)) { + if (ipn.reason == InfopointReason.LINE_NUMBER) { + ++graphLineSPs; + } + } + assertTrue(graphLineSPs > 0); + final CompilationResult cr = GraalCompiler.compileMethod(runtime, replacements, backend, runtime.getTarget(), runtime.lookupJavaMethod(method), graph, null, getDefaultPhasePlan(true), + OptimisticOptimizations.ALL, new SpeculationLog()); + int lineSPs = 0; + for (Infopoint sp : cr.getInfopoints()) { + assertNotNull(sp.reason); + if (sp.reason == InfopointReason.LINE_NUMBER) { + ++lineSPs; + } + } + assertTrue(lineSPs > 0); + } + +} diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Thu Apr 11 09:53:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,8 +41,14 @@ @Test public void testInvokeStaticInlining() { - assertInlined(getGraph("invokeStaticSnippet")); - assertInlined(getGraph("invokeStaticOnInstanceSnippet")); + assertInlined(getGraph("invokeStaticSnippet", false)); + assertInlined(getGraph("invokeStaticOnInstanceSnippet", false)); + } + + @Test + public void testInvokeStaticInliningIP() { + assertInlineInfopoints(assertInlined(getGraph("invokeStaticSnippet", true))); + assertInlineInfopoints(assertInlined(getGraph("invokeStaticOnInstanceSnippet", true))); } @SuppressWarnings("all") @@ -57,9 +63,16 @@ @Test public void testStaticBindableInlining() { - assertInlined(getGraph("invokeConstructorSnippet")); - assertInlined(getGraph("invokeFinalMethodSnippet")); - assertInlined(getGraph("invokeMethodOnFinalClassSnippet")); + assertInlined(getGraph("invokeConstructorSnippet", false)); + assertInlined(getGraph("invokeFinalMethodSnippet", false)); + assertInlined(getGraph("invokeMethodOnFinalClassSnippet", false)); + } + + @Test + public void testStaticBindableInliningIP() { + assertInlineInfopoints(assertInlined(getGraph("invokeConstructorSnippet", true))); + assertInlineInfopoints(assertInlined(getGraph("invokeFinalMethodSnippet", true))); + assertInlineInfopoints(assertInlined(getGraph("invokeMethodOnFinalClassSnippet", true))); } @SuppressWarnings("all") @@ -81,14 +94,28 @@ @Test public void testClassHierarchyAnalysis() { - assertInlined(getGraph("invokeLeafClassMethodSnippet")); - assertInlined(getGraph("invokeConcreteMethodSnippet")); - assertInlined(getGraph("invokeSingleImplementorInterfaceSnippet")); - // assertInlined(getGraph("invokeConcreteInterfaceMethodSnippet")); + assertInlined(getGraph("invokeLeafClassMethodSnippet", false)); + assertInlined(getGraph("invokeConcreteMethodSnippet", false)); + assertInlined(getGraph("invokeSingleImplementorInterfaceSnippet", false)); + // assertInlined(getGraph("invokeConcreteInterfaceMethodSnippet", false)); + + assertNotInlined(getGraph("invokeOverriddenPublicMethodSnippet", false)); + assertNotInlined(getGraph("invokeOverriddenProtectedMethodSnippet", false)); + assertNotInlined(getGraph("invokeOverriddenInterfaceMethodSnippet", false)); + } - assertNotInlined(getGraph("invokeOverriddenPublicMethodSnippet")); - assertNotInlined(getGraph("invokeOverriddenProtectedMethodSnippet")); - assertNotInlined(getGraph("invokeOverriddenInterfaceMethodSnippet")); + @Test + public void testClassHierarchyAnalysisIP() { + assertInlineInfopoints(assertInlined(getGraph("invokeLeafClassMethodSnippet", true))); + assertInlineInfopoints(assertInlined(getGraph("invokeConcreteMethodSnippet", true))); + assertInlineInfopoints(assertInlined(getGraph("invokeSingleImplementorInterfaceSnippet", true))); + //@formatter:off + // assertInlineInfopoints(assertInlined(getGraph("invokeConcreteInterfaceMethodSnippet", true))); + //@formatter:on + + assertNoInlineInfopoints(assertNotInlined(getGraph("invokeOverriddenPublicMethodSnippet", true))); + assertNoInlineInfopoints(assertNotInlined(getGraph("invokeOverriddenProtectedMethodSnippet", true))); + assertNoInlineInfopoints(assertNotInlined(getGraph("invokeOverriddenInterfaceMethodSnippet", true))); } @SuppressWarnings("all") @@ -126,13 +153,13 @@ return superClass.protectedOverriddenMethod(); } - private StructuredGraph getGraph(final String snippet) { + private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) { return Debug.scope("InliningTest", new DebugDumpScope(snippet), new Callable() { @Override public StructuredGraph call() { StructuredGraph graph = parse(snippet); - PhasePlan phasePlan = getDefaultPhasePlan(); + PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode); Assumptions assumptions = new Assumptions(true); new ComputeProbabilityPhase().apply(graph); Debug.dump(graph, "Graph"); @@ -172,6 +199,31 @@ return graph; } + private static StructuredGraph assertInlineInfopoints(StructuredGraph graph) { + int start = 0; + int end = 0; + for (InfopointNode ipn : graph.getNodes(InfopointNode.class)) { + if (ipn.reason == InfopointReason.METHOD_START) { + ++start; + } else if (ipn.reason == InfopointReason.METHOD_END) { + ++end; + } + } + if (start < 1 || end < 1) { + fail(String.format("Graph does not contain required inline infopoints: %d starts, %d ends.", start, end)); + } + return graph; + } + + private static StructuredGraph assertNoInlineInfopoints(StructuredGraph graph) { + for (InfopointNode ipn : graph.getNodes(InfopointNode.class)) { + if (ipn.reason == InfopointReason.METHOD_START || ipn.reason == InfopointReason.METHOD_END) { + fail("Graph contains inline infopoints."); + } + } + return graph; + } + // some interfaces and classes for testing private interface MultipleImplementorsInterface { diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Thu Apr 11 09:53:10 2013 +0200 @@ -127,7 +127,7 @@ if (state.outerFrameState() != null) { caller = computeFrameForState(state.outerFrameState()); } - assert state.bci >= 0 || state.bci == FrameState.BEFORE_BCI : "bci == " + state.bci; + assert state.bci != FrameState.UNKNOWN_BCI : "bci == " + state.bci; return new BytecodeFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, numLocals, numStack, numLocks); } diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Thu Apr 11 09:53:10 2013 +0200 @@ -63,11 +63,11 @@ if (config.isPollingPageFar) { asm.movq(scratch.getRegister(), config.safepointPollingAddress + offset); tasm.recordMark(Marks.MARK_POLL_FAR); - tasm.recordSafepoint(pos, state); + tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); asm.movq(scratch.getRegister(), new AMD64Address(scratch.getRegister())); } else { tasm.recordMark(Marks.MARK_POLL_NEAR); - tasm.recordSafepoint(pos, state); + tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); // The C++ code transforms the polling page offset into an RIP displacement // to the real address at that offset in the polling page. asm.movq(scratch.getRegister(), new AMD64Address(rip, offset)); diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java Thu Apr 11 09:53:10 2013 +0200 @@ -67,7 +67,7 @@ } private static Site[] getSortedSites(CompilationResult target) { - List[] lists = new List[]{target.getSafepoints(), target.getDataReferences(), target.getMarks()}; + List[] lists = new List[]{target.getInfopoints(), target.getDataReferences(), target.getMarks()}; int count = 0; for (List list : lists) { count += list.size(); diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Apr 11 09:53:10 2013 +0200 @@ -48,7 +48,7 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Mark; -import com.oracle.graal.api.code.CompilationResult.Safepoint; +import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.Register.RegisterFlag; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; @@ -373,18 +373,18 @@ addExceptionHandlersComment(compResult, hcf); Register fp = regConfig.getFrameRegister(); RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0); - for (Safepoint safepoint : compResult.getSafepoints()) { - if (safepoint instanceof Call) { - Call call = (Call) safepoint; + for (Infopoint infopoint : compResult.getInfopoints()) { + if (infopoint instanceof Call) { + Call call = (Call) infopoint; if (call.debugInfo != null) { hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString()); } addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}"); } else { - if (safepoint.debugInfo != null) { - hcf.addComment(safepoint.pcOffset, CodeUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString()); + if (infopoint.debugInfo != null) { + hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString()); } - addOperandComment(hcf, safepoint.pcOffset, "{safepoint}"); + addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}"); } } for (DataPatch site : compResult.getDataReferences()) { diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Thu Apr 11 09:53:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ package com.oracle.graal.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; public class GraphBuilderConfiguration { @@ -30,6 +31,13 @@ private final boolean omitAllExceptionEdges; private ResolvedJavaType[] skippedExceptionTypes; + /** + * When the graph builder is in eager infopoint mode, it inserts {@link InfopointNode}s in + * places where no safepoints would be inserted: inlining boundaries, and line number switches. + * This is relevant when code is to be generated for native, machine-code level debugging. + */ + private boolean eagerInfopointMode; + protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges) { this.eagerResolving = eagerResolving; this.omitAllExceptionEdges = omitAllExceptionEdges; @@ -39,6 +47,10 @@ this.skippedExceptionTypes = skippedExceptionTypes; } + public void setEagerInfopointMode(boolean eagerInfopointMode) { + this.eagerInfopointMode = eagerInfopointMode; + } + public ResolvedJavaType[] getSkippedExceptionTypes() { return skippedExceptionTypes; } @@ -51,6 +63,10 @@ return omitAllExceptionEdges; } + public boolean eagerInfopointMode() { + return eagerInfopointMode; + } + public static GraphBuilderConfiguration getDefault() { return new GraphBuilderConfiguration(false, false); } @@ -64,9 +80,9 @@ } /** - * Returns {@code true} if it is an error for a class/field/method resolution to fail. - * The default is the same result as returned by {@link #eagerResolving()}. - * However, it may be overridden to allow failure even when {@link #eagerResolving} is {@code true}. + * Returns {@code true} if it is an error for a class/field/method resolution to fail. The + * default is the same result as returned by {@link #eagerResolving()}. However, it may be + * overridden to allow failure even when {@link #eagerResolving} is {@code true}. */ public boolean unresolvedIsError() { return eagerResolving; diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Apr 11 09:53:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,10 @@ */ public static final int TRACELEVEL_STATE = 2; + private LineNumberTable lnt; + private int previousLineNumber; + private int currentLineNumber; + protected StructuredGraph currentGraph; private final MetaAccessProvider runtime; @@ -141,6 +145,10 @@ @Override protected void run(StructuredGraph graph) { method = graph.method(); + if (graphBuilderConfig.eagerInfopointMode()) { + lnt = method.getLineNumberTable(); + previousLineNumber = -1; + } entryBCI = graph.getEntryBCI(); profilingInfo = method.getProfilingInfo(); assert method.getCode() != null : "method must contain bytecodes: " + method; @@ -193,6 +201,13 @@ } frameState.clearNonLiveLocals(blockMap.startBlock.localsLiveIn); + if (graphBuilderConfig.eagerInfopointMode()) { + ((StateSplit) lastInstr).setStateAfter(frameState.create(0)); + InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_START)); + lastInstr.setNext(ipn); + lastInstr = ipn; + } + // finish the start block ((StateSplit) lastInstr).setStateAfter(frameState.create(0)); @@ -1493,7 +1508,7 @@ } private void processBlock(Block block) { - // Ignore blocks that have no predecessors by the time it their bytecodes are parsed + // Ignore blocks that have no predecessors by the time their bytecodes are parsed if (block == null || block.firstInstruction == null) { Debug.log("Ignoring block %s", block); return; @@ -1574,6 +1589,12 @@ } ReturnNode returnNode = currentGraph.add(new ReturnNode(x)); + if (graphBuilderConfig.eagerInfopointMode()) { + InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_END)); + ipn.setStateAfter(frameState.create(FrameState.AFTER_BCI)); + append(ipn); + } + append(returnNode); } @@ -1684,6 +1705,16 @@ BytecodesParsed.add(block.endBci - bci); while (bci < endBCI) { + if (graphBuilderConfig.eagerInfopointMode() && lnt != null) { + currentLineNumber = lnt.getLineNumber(bci); + if (currentLineNumber != previousLineNumber) { + InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.LINE_NUMBER)); + ipn.setStateAfter(frameState.create(bci)); + append(ipn); + previousLineNumber = currentLineNumber; + } + } + // read the opcode int opcode = stream.currentBC(); traceState(); diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java Thu Apr 11 09:53:10 2013 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir; + +import static com.oracle.graal.lir.LIRInstruction.Opcode; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.lir.asm.*; + +/** + * Emits an infopoint (only mark the position). + */ +@Opcode("INFOPOINT") +public class InfopointOp extends LIRInstruction { + + @State protected LIRFrameState state; + + private final InfopointReason reason; + + public InfopointOp(LIRFrameState state, InfopointReason reason) { + this.state = state; + this.reason = reason; + } + + @Override + public void emitCode(TargetMethodAssembler tasm) { + tasm.recordInfopoint(tasm.asm.codeBuffer.position(), state, reason); + } +} diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Thu Apr 11 09:53:10 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,7 +101,7 @@ Debug.metric("TargetMethods").increment(); Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize()); - Debug.metric("SafepointsEmitted").add(compilationResult.getSafepoints().size()); + Debug.metric("SafepointsEmitted").add(compilationResult.getInfopoints().size()); Debug.metric("DataPatches").add(compilationResult.getDataReferences().size()); Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size()); Debug.log("Finished target method %s, isStub %b", name, isStub); @@ -122,7 +122,7 @@ public void recordImplicitException(int pcOffset, LIRFrameState info) { // record an implicit exception point if (info != null) { - compilationResult.recordSafepoint(pcOffset, info.debugInfo()); + compilationResult.recordInfopoint(pcOffset, info.debugInfo(), InfopointReason.IMPLICIT_EXCEPTION); assert info.exceptionEdge == null; } } @@ -137,10 +137,10 @@ compilationResult.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false); } - public void recordSafepoint(int pos, LIRFrameState info) { - // safepoints always need debug info + public void recordInfopoint(int pos, LIRFrameState info, InfopointReason reason) { + // infopoints always need debug info DebugInfo debugInfo = info.debugInfo(); - compilationResult.recordSafepoint(pos, debugInfo); + compilationResult.recordInfopoint(pos, debugInfo, reason); } public AbstractAddress recordDataReferenceInCode(Constant data, int alignment, boolean inlined) { diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Thu Apr 11 09:53:10 2013 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.graph.Node.IterableNodeType; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Nodes of this type are inserted into the graph to denote points of interest to debugging. + */ +public class InfopointNode extends AbstractStateSplit implements LIRLowerable, IterableNodeType { + + public final InfopointReason reason; + + public InfopointNode(InfopointReason reason) { + super(StampFactory.forVoid()); + this.reason = reason; + } + + @Override + public void generate(LIRGeneratorTool generator) { + generator.visitInfopointNode(this); + } + + @Override + public boolean hasSideEffect() { + return false; + } + +} diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Apr 11 09:53:10 2013 +0200 @@ -137,4 +137,6 @@ */ public void beforeRegisterAllocation() { } + + public abstract void visitInfopointNode(InfopointNode i); } diff -r 8ddaac81cb21 -r a8fea2979e63 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Mon Apr 08 18:47:06 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Apr 11 09:53:10 2013 +0200 @@ -1117,7 +1117,7 @@ } if (node instanceof FrameState) { FrameState frameState = (FrameState) node; - assert frameState.bci != FrameState.BEFORE_BCI; + assert frameState.bci != FrameState.BEFORE_BCI : frameState; if (frameState.bci == FrameState.AFTER_BCI) { frameState.replaceAndDelete(stateAfter); } else if (frameState.bci == FrameState.AFTER_EXCEPTION_BCI) { diff -r 8ddaac81cb21 -r a8fea2979e63 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Apr 08 18:47:06 2013 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Apr 11 09:53:10 2013 +0200 @@ -209,8 +209,9 @@ do_klass(CompilationResult_DataPatch_klass, com_oracle_graal_api_code_CompilationResult_DataPatch, Opt) \ do_klass(CompilationResult_ExceptionHandler_klass, com_oracle_graal_api_code_CompilationResult_ExceptionHandler, Opt) \ do_klass(CompilationResult_Mark_klass, com_oracle_graal_api_code_CompilationResult_Mark, Opt) \ - do_klass(CompilationResult_Safepoint_klass, com_oracle_graal_api_code_CompilationResult_Safepoint, Opt) \ + do_klass(CompilationResult_Infopoint_klass, com_oracle_graal_api_code_CompilationResult_Infopoint, Opt) \ do_klass(CompilationResult_Site_klass, com_oracle_graal_api_code_CompilationResult_Site, Opt) \ + do_klass(InfopointReason_klass, com_oracle_graal_api_code_InfopointReason, Opt) \ do_klass(code_Register_klass, com_oracle_graal_api_code_Register, Opt) \ do_klass(RegisterValue_klass, com_oracle_graal_api_code_RegisterValue, Opt) \ do_klass(StackSlot_klass, com_oracle_graal_api_code_StackSlot, Opt) \ diff -r 8ddaac81cb21 -r a8fea2979e63 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Apr 08 18:47:06 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Apr 11 09:53:10 2013 +0200 @@ -328,8 +328,9 @@ template(com_oracle_graal_api_code_CompilationResult_DataPatch, "com/oracle/graal/api/code/CompilationResult$DataPatch") \ template(com_oracle_graal_api_code_CompilationResult_ExceptionHandler, "com/oracle/graal/api/code/CompilationResult$ExceptionHandler") \ template(com_oracle_graal_api_code_CompilationResult_Mark, "com/oracle/graal/api/code/CompilationResult$Mark") \ - template(com_oracle_graal_api_code_CompilationResult_Safepoint, "com/oracle/graal/api/code/CompilationResult$Safepoint") \ + template(com_oracle_graal_api_code_CompilationResult_Infopoint, "com/oracle/graal/api/code/CompilationResult$Infopoint") \ template(com_oracle_graal_api_code_CompilationResult_Site, "com/oracle/graal/api/code/CompilationResult$Site") \ + template(com_oracle_graal_api_code_InfopointReason, "com/oracle/graal/api/code/InfopointReason") \ template(com_oracle_graal_api_code_BytecodeFrame, "com/oracle/graal/api/code/BytecodeFrame") \ template(com_oracle_graal_api_code_BytecodePosition, "com/oracle/graal/api/code/BytecodePosition") \ template(com_oracle_graal_api_code_DebugInfo, "com/oracle/graal/api/code/DebugInfo") \ diff -r 8ddaac81cb21 -r a8fea2979e63 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Apr 08 18:47:06 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Thu Apr 11 09:53:10 2013 +0200 @@ -416,9 +416,17 @@ if (site->is_a(CompilationResult_Call::klass())) { TRACE_graal_4("call at %i", pc_offset); site_Call(buffer, pc_offset, site); - } else if (site->is_a(CompilationResult_Safepoint::klass())) { - TRACE_graal_4("safepoint at %i", pc_offset); - site_Safepoint(buffer, pc_offset, site); + } else if (site->is_a(CompilationResult_Infopoint::klass())) { + // three reasons for infopoints denote actual safepoints + oop reason = CompilationResult_Infopoint::reason(site); + if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { + TRACE_graal_4("safepoint at %i", pc_offset); + site_Safepoint(buffer, pc_offset, site); + } else { + // if the infopoint is not an actual safepoint, it must have one of the other reasons + // (safeguard against new safepoint types that require handling above) + assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, ""); + } } else if (site->is_a(CompilationResult_DataPatch::klass())) { TRACE_graal_4("datapatch at %i", pc_offset); site_DataPatch(buffer, pc_offset, site); @@ -578,7 +586,7 @@ } void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { - oop debug_info = CompilationResult_Safepoint::debugInfo(site); + oop debug_info = CompilationResult_Infopoint::debugInfo(site); assert(debug_info != NULL, "debug info expected"); // address instruction = _instructions->start() + pc_offset; diff -r 8ddaac81cb21 -r a8fea2979e63 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 08 18:47:06 2013 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Thu Apr 11 09:53:10 2013 +0200 @@ -131,8 +131,18 @@ int_field(CompilationResult_DataPatch, alignment) \ boolean_field(CompilationResult_DataPatch, inlined) \ end_class \ - start_class(CompilationResult_Safepoint) \ - oop_field(CompilationResult_Safepoint, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ + start_class(InfopointReason) \ + static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;") \ + static_oop_field(InfopointReason, SAFEPOINT, "Lcom/oracle/graal/api/code/InfopointReason;") \ + static_oop_field(InfopointReason, CALL, "Lcom/oracle/graal/api/code/InfopointReason;") \ + static_oop_field(InfopointReason, IMPLICIT_EXCEPTION, "Lcom/oracle/graal/api/code/InfopointReason;") \ + static_oop_field(InfopointReason, METHOD_START, "Lcom/oracle/graal/api/code/InfopointReason;") \ + static_oop_field(InfopointReason, METHOD_END, "Lcom/oracle/graal/api/code/InfopointReason;") \ + static_oop_field(InfopointReason, LINE_NUMBER, "Lcom/oracle/graal/api/code/InfopointReason;") \ + end_class \ + start_class(CompilationResult_Infopoint) \ + oop_field(CompilationResult_Infopoint, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ + oop_field(CompilationResult_Infopoint, reason, "Lcom/oracle/graal/api/code/InfopointReason;") \ end_class \ start_class(CompilationResult_ExceptionHandler) \ int_field(CompilationResult_ExceptionHandler, handlerPos) \