src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java

Print this page




  25 import static org.graalvm.compiler.bytecode.Bytecodes.DUP;
  26 import static org.graalvm.compiler.bytecode.Bytecodes.DUP2;
  27 import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X1;
  28 import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X2;
  29 import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X1;
  30 import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X2;
  31 import static org.graalvm.compiler.bytecode.Bytecodes.POP;
  32 import static org.graalvm.compiler.bytecode.Bytecodes.POP2;
  33 import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
  34 import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
  35 import static org.graalvm.compiler.java.BytecodeParserOptions.HideSubstitutionStates;
  36 import static org.graalvm.compiler.nodes.FrameState.TWO_SLOT_MARKER;
  37 
  38 import java.util.ArrayList;
  39 import java.util.Arrays;
  40 import java.util.List;
  41 import java.util.function.Function;
  42 
  43 import org.graalvm.compiler.bytecode.Bytecode;
  44 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
  45 import org.graalvm.compiler.common.PermanentBailoutException;

  46 import org.graalvm.compiler.core.common.type.StampFactory;
  47 import org.graalvm.compiler.core.common.type.StampPair;
  48 import org.graalvm.compiler.debug.Debug;
  49 import org.graalvm.compiler.graph.NodeSourcePosition;
  50 import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
  51 import org.graalvm.compiler.nodeinfo.Verbosity;
  52 import org.graalvm.compiler.nodes.AbstractMergeNode;
  53 import org.graalvm.compiler.nodes.ConstantNode;
  54 import org.graalvm.compiler.nodes.FrameState;
  55 import org.graalvm.compiler.nodes.LoopBeginNode;
  56 import org.graalvm.compiler.nodes.LoopExitNode;
  57 import org.graalvm.compiler.nodes.ParameterNode;
  58 import org.graalvm.compiler.nodes.PhiNode;
  59 import org.graalvm.compiler.nodes.ProxyNode;
  60 import org.graalvm.compiler.nodes.StateSplit;
  61 import org.graalvm.compiler.nodes.StructuredGraph;
  62 import org.graalvm.compiler.nodes.ValueNode;
  63 import org.graalvm.compiler.nodes.ValuePhiNode;
  64 import org.graalvm.compiler.nodes.calc.FloatingNode;
  65 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;


  82 
  83     private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0];
  84     private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0];
  85 
  86     private final BytecodeParser parser;
  87     private final GraphBuilderTool tool;
  88     private final Bytecode code;
  89     private int stackSize;
  90     protected final ValueNode[] locals;
  91     protected final ValueNode[] stack;
  92     private ValueNode[] lockedObjects;
  93     private boolean canVerifyKind;
  94 
  95     /**
  96      * @see BytecodeFrame#rethrowException
  97      */
  98     private boolean rethrowException;
  99 
 100     private MonitorIdNode[] monitorIds;
 101     private final StructuredGraph graph;

 102     private FrameState outerFrameState;
 103 
 104     /**
 105      * The closest {@link StateSplit#hasSideEffect() side-effect} predecessors. There will be more
 106      * than one when the current block contains no side-effects but merging predecessor blocks do.
 107      */
 108     private List<StateSplit> sideEffects;
 109 
 110     private JavaConstant constantReceiver;
 111 
 112     /**
 113      * Creates a new frame state builder for the given method and the given target graph.
 114      *
 115      * @param method the method whose frame is simulated
 116      * @param graph the target graph of Graal nodes created by the builder
 117      */
 118     public FrameStateBuilder(GraphBuilderTool tool, ResolvedJavaMethod method, StructuredGraph graph) {
 119         this(tool, new ResolvedJavaMethodBytecode(method), graph);
 120     }
 121 


 125      *
 126      * @param code the bytecode in which the frame exists
 127      * @param graph the target graph of Graal nodes created by the builder
 128      */
 129     public FrameStateBuilder(GraphBuilderTool tool, Bytecode code, StructuredGraph graph) {
 130         this.tool = tool;
 131         if (tool instanceof BytecodeParser) {
 132             this.parser = (BytecodeParser) tool;
 133         } else {
 134             this.parser = null;
 135         }
 136         this.code = code;
 137         this.locals = allocateArray(code.getMaxLocals());
 138         this.stack = allocateArray(Math.max(1, code.getMaxStackSize()));
 139         this.lockedObjects = allocateArray(0);
 140 
 141         assert graph != null;
 142 
 143         this.monitorIds = EMPTY_MONITOR_ARRAY;
 144         this.graph = graph;

 145         this.canVerifyKind = true;
 146     }
 147 
 148     public void disableKindVerification() {
 149         canVerifyKind = false;
 150     }
 151 
 152     public void initializeFromArgumentsArray(ValueNode[] arguments) {
 153 
 154         int javaIndex = 0;
 155         int index = 0;
 156         if (!getMethod().isStatic()) {
 157             // set the receiver
 158             locals[javaIndex] = arguments[index];
 159             javaIndex = 1;
 160             index = 1;
 161             constantReceiver = locals[0].asJavaConstant();
 162         }
 163         Signature sig = getMethod().getSignature();
 164         int max = sig.getParameterCount(false);


 246             index++;
 247         }
 248     }
 249 
 250     private FrameStateBuilder(FrameStateBuilder other) {
 251         this.parser = other.parser;
 252         this.tool = other.tool;
 253         this.code = other.code;
 254         this.stackSize = other.stackSize;
 255         this.locals = other.locals.clone();
 256         this.stack = other.stack.clone();
 257         this.lockedObjects = other.lockedObjects.length == 0 ? other.lockedObjects : other.lockedObjects.clone();
 258         this.rethrowException = other.rethrowException;
 259         this.canVerifyKind = other.canVerifyKind;
 260 
 261         assert locals.length == code.getMaxLocals();
 262         assert stack.length == Math.max(1, code.getMaxStackSize());
 263 
 264         assert other.graph != null;
 265         graph = other.graph;

 266         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
 267 
 268         assert locals.length == code.getMaxLocals();
 269         assert stack.length == Math.max(1, code.getMaxStackSize());
 270         assert lockedObjects.length == monitorIds.length;
 271     }
 272 
 273     private static ValueNode[] allocateArray(int length) {
 274         return length == 0 ? EMPTY_ARRAY : new ValueNode[length];
 275     }
 276 
 277     public ResolvedJavaMethod getMethod() {
 278         return code.getMethod();
 279     }
 280 
 281     @Override
 282     public String toString() {
 283         StringBuilder sb = new StringBuilder();
 284         sb.append("[locals: [");
 285         for (int i = 0; i < locals.length; i++) {


 330         if (pushedValues != null) {
 331             assert pushedSlotKinds.length == pushedValues.length;
 332             int stackSizeToRestore = stackSize;
 333             for (int i = 0; i < pushedValues.length; i++) {
 334                 push(pushedSlotKinds[i], pushedValues[i]);
 335             }
 336             FrameState res = graph.add(new FrameState(outerFrameState, code, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall));
 337             stackSize = stackSizeToRestore;
 338             return res;
 339         } else {
 340             if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
 341                 assert outerFrameState == null;
 342                 clearLocals();
 343             }
 344             return graph.add(new FrameState(outerFrameState, code, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall));
 345         }
 346     }
 347 
 348     public NodeSourcePosition createBytecodePosition(int bci) {
 349         BytecodeParser parent = parser.getParent();
 350         if (HideSubstitutionStates.getValue()) {
 351             if (parser.parsingIntrinsic()) {
 352                 // Attribute to the method being replaced
 353                 return new NodeSourcePosition(constantReceiver, parent.getFrameStateBuilder().createBytecodePosition(parent.bci()), parser.intrinsicContext.getOriginalMethod(), -1);
 354             }
 355             // Skip intrinsic frames
 356             parent = parser.getNonIntrinsicAncestor();
 357         }
 358         return create(null, constantReceiver, bci, parent);
 359     }
 360 
 361     private NodeSourcePosition create(NodeSourcePosition o, JavaConstant receiver, int bci, BytecodeParser parent) {
 362         NodeSourcePosition outer = o;
 363         if (outer == null && parent != null) {
 364             outer = parent.getFrameStateBuilder().createBytecodePosition(parent.bci());
 365         }
 366         if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI && parent != null) {
 367             return FrameState.toSourcePosition(outerFrameState);
 368         }
 369         if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
 370             throw shouldNotReachHere();


 607             if (stack[i] == value) {
 608                 return true;
 609             }
 610         }
 611         assert lockedObjects.length == monitorIds.length;
 612         for (int i = 0; i < lockedObjects.length; i++) {
 613             if (lockedObjects[i] == value || monitorIds[i] == value) {
 614                 return true;
 615             }
 616         }
 617         return false;
 618     }
 619 
 620     public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) {
 621         /*
 622          * (lstadler) if somebody is tempted to remove/disable this clearing code: it's possible to
 623          * remove it for normal compilations, but not for OSR compilations - otherwise dead object
 624          * slots at the OSR entry aren't cleared. it is also not enough to rely on PiNodes with
 625          * Kind.Illegal, because the conflicting branch might not have been parsed.
 626          */
 627         if (!parser.graphBuilderConfig.clearNonLiveLocals()) {
 628             return;
 629         }
 630         if (liveIn) {
 631             for (int i = 0; i < locals.length; i++) {
 632                 if (!liveness.localIsLiveIn(block, i)) {
 633                     assert locals[i] != TWO_SLOT_MARKER || locals[i - 1] == null : "Clearing of second slot must have cleared the first slot too";
 634                     locals[i] = null;
 635                 }
 636             }
 637         } else {
 638             for (int i = 0; i < locals.length; i++) {
 639                 if (!liveness.localIsLiveOut(block, i)) {
 640                     assert locals[i] != TWO_SLOT_MARKER || locals[i - 1] == null : "Clearing of second slot must have cleared the first slot too";
 641                     locals[i] = null;
 642                 }
 643             }
 644         }
 645     }
 646 
 647     /**




  25 import static org.graalvm.compiler.bytecode.Bytecodes.DUP;
  26 import static org.graalvm.compiler.bytecode.Bytecodes.DUP2;
  27 import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X1;
  28 import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X2;
  29 import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X1;
  30 import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X2;
  31 import static org.graalvm.compiler.bytecode.Bytecodes.POP;
  32 import static org.graalvm.compiler.bytecode.Bytecodes.POP2;
  33 import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
  34 import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
  35 import static org.graalvm.compiler.java.BytecodeParserOptions.HideSubstitutionStates;
  36 import static org.graalvm.compiler.nodes.FrameState.TWO_SLOT_MARKER;
  37 
  38 import java.util.ArrayList;
  39 import java.util.Arrays;
  40 import java.util.List;
  41 import java.util.function.Function;
  42 
  43 import org.graalvm.compiler.bytecode.Bytecode;
  44 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
  45 import org.graalvm.compiler.core.common.PermanentBailoutException;
  46 import org.graalvm.compiler.core.common.GraalOptions;
  47 import org.graalvm.compiler.core.common.type.StampFactory;
  48 import org.graalvm.compiler.core.common.type.StampPair;
  49 import org.graalvm.compiler.debug.Debug;
  50 import org.graalvm.compiler.graph.NodeSourcePosition;
  51 import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
  52 import org.graalvm.compiler.nodeinfo.Verbosity;
  53 import org.graalvm.compiler.nodes.AbstractMergeNode;
  54 import org.graalvm.compiler.nodes.ConstantNode;
  55 import org.graalvm.compiler.nodes.FrameState;
  56 import org.graalvm.compiler.nodes.LoopBeginNode;
  57 import org.graalvm.compiler.nodes.LoopExitNode;
  58 import org.graalvm.compiler.nodes.ParameterNode;
  59 import org.graalvm.compiler.nodes.PhiNode;
  60 import org.graalvm.compiler.nodes.ProxyNode;
  61 import org.graalvm.compiler.nodes.StateSplit;
  62 import org.graalvm.compiler.nodes.StructuredGraph;
  63 import org.graalvm.compiler.nodes.ValueNode;
  64 import org.graalvm.compiler.nodes.ValuePhiNode;
  65 import org.graalvm.compiler.nodes.calc.FloatingNode;
  66 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;


  83 
  84     private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0];
  85     private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0];
  86 
  87     private final BytecodeParser parser;
  88     private final GraphBuilderTool tool;
  89     private final Bytecode code;
  90     private int stackSize;
  91     protected final ValueNode[] locals;
  92     protected final ValueNode[] stack;
  93     private ValueNode[] lockedObjects;
  94     private boolean canVerifyKind;
  95 
  96     /**
  97      * @see BytecodeFrame#rethrowException
  98      */
  99     private boolean rethrowException;
 100 
 101     private MonitorIdNode[] monitorIds;
 102     private final StructuredGraph graph;
 103     private final boolean clearNonLiveLocals;
 104     private FrameState outerFrameState;
 105 
 106     /**
 107      * The closest {@link StateSplit#hasSideEffect() side-effect} predecessors. There will be more
 108      * than one when the current block contains no side-effects but merging predecessor blocks do.
 109      */
 110     private List<StateSplit> sideEffects;
 111 
 112     private JavaConstant constantReceiver;
 113 
 114     /**
 115      * Creates a new frame state builder for the given method and the given target graph.
 116      *
 117      * @param method the method whose frame is simulated
 118      * @param graph the target graph of Graal nodes created by the builder
 119      */
 120     public FrameStateBuilder(GraphBuilderTool tool, ResolvedJavaMethod method, StructuredGraph graph) {
 121         this(tool, new ResolvedJavaMethodBytecode(method), graph);
 122     }
 123 


 127      *
 128      * @param code the bytecode in which the frame exists
 129      * @param graph the target graph of Graal nodes created by the builder
 130      */
 131     public FrameStateBuilder(GraphBuilderTool tool, Bytecode code, StructuredGraph graph) {
 132         this.tool = tool;
 133         if (tool instanceof BytecodeParser) {
 134             this.parser = (BytecodeParser) tool;
 135         } else {
 136             this.parser = null;
 137         }
 138         this.code = code;
 139         this.locals = allocateArray(code.getMaxLocals());
 140         this.stack = allocateArray(Math.max(1, code.getMaxStackSize()));
 141         this.lockedObjects = allocateArray(0);
 142 
 143         assert graph != null;
 144 
 145         this.monitorIds = EMPTY_MONITOR_ARRAY;
 146         this.graph = graph;
 147         this.clearNonLiveLocals = GraalOptions.OptClearNonLiveLocals.getValue(graph.getOptions());
 148         this.canVerifyKind = true;
 149     }
 150 
 151     public void disableKindVerification() {
 152         canVerifyKind = false;
 153     }
 154 
 155     public void initializeFromArgumentsArray(ValueNode[] arguments) {
 156 
 157         int javaIndex = 0;
 158         int index = 0;
 159         if (!getMethod().isStatic()) {
 160             // set the receiver
 161             locals[javaIndex] = arguments[index];
 162             javaIndex = 1;
 163             index = 1;
 164             constantReceiver = locals[0].asJavaConstant();
 165         }
 166         Signature sig = getMethod().getSignature();
 167         int max = sig.getParameterCount(false);


 249             index++;
 250         }
 251     }
 252 
 253     private FrameStateBuilder(FrameStateBuilder other) {
 254         this.parser = other.parser;
 255         this.tool = other.tool;
 256         this.code = other.code;
 257         this.stackSize = other.stackSize;
 258         this.locals = other.locals.clone();
 259         this.stack = other.stack.clone();
 260         this.lockedObjects = other.lockedObjects.length == 0 ? other.lockedObjects : other.lockedObjects.clone();
 261         this.rethrowException = other.rethrowException;
 262         this.canVerifyKind = other.canVerifyKind;
 263 
 264         assert locals.length == code.getMaxLocals();
 265         assert stack.length == Math.max(1, code.getMaxStackSize());
 266 
 267         assert other.graph != null;
 268         graph = other.graph;
 269         clearNonLiveLocals = other.clearNonLiveLocals;
 270         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
 271 
 272         assert locals.length == code.getMaxLocals();
 273         assert stack.length == Math.max(1, code.getMaxStackSize());
 274         assert lockedObjects.length == monitorIds.length;
 275     }
 276 
 277     private static ValueNode[] allocateArray(int length) {
 278         return length == 0 ? EMPTY_ARRAY : new ValueNode[length];
 279     }
 280 
 281     public ResolvedJavaMethod getMethod() {
 282         return code.getMethod();
 283     }
 284 
 285     @Override
 286     public String toString() {
 287         StringBuilder sb = new StringBuilder();
 288         sb.append("[locals: [");
 289         for (int i = 0; i < locals.length; i++) {


 334         if (pushedValues != null) {
 335             assert pushedSlotKinds.length == pushedValues.length;
 336             int stackSizeToRestore = stackSize;
 337             for (int i = 0; i < pushedValues.length; i++) {
 338                 push(pushedSlotKinds[i], pushedValues[i]);
 339             }
 340             FrameState res = graph.add(new FrameState(outerFrameState, code, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall));
 341             stackSize = stackSizeToRestore;
 342             return res;
 343         } else {
 344             if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
 345                 assert outerFrameState == null;
 346                 clearLocals();
 347             }
 348             return graph.add(new FrameState(outerFrameState, code, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall));
 349         }
 350     }
 351 
 352     public NodeSourcePosition createBytecodePosition(int bci) {
 353         BytecodeParser parent = parser.getParent();
 354         if (HideSubstitutionStates.getValue(parser.graph.getOptions())) {
 355             if (parser.parsingIntrinsic()) {
 356                 // Attribute to the method being replaced
 357                 return new NodeSourcePosition(constantReceiver, parent.getFrameStateBuilder().createBytecodePosition(parent.bci()), parser.intrinsicContext.getOriginalMethod(), -1);
 358             }
 359             // Skip intrinsic frames
 360             parent = parser.getNonIntrinsicAncestor();
 361         }
 362         return create(null, constantReceiver, bci, parent);
 363     }
 364 
 365     private NodeSourcePosition create(NodeSourcePosition o, JavaConstant receiver, int bci, BytecodeParser parent) {
 366         NodeSourcePosition outer = o;
 367         if (outer == null && parent != null) {
 368             outer = parent.getFrameStateBuilder().createBytecodePosition(parent.bci());
 369         }
 370         if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI && parent != null) {
 371             return FrameState.toSourcePosition(outerFrameState);
 372         }
 373         if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
 374             throw shouldNotReachHere();


 611             if (stack[i] == value) {
 612                 return true;
 613             }
 614         }
 615         assert lockedObjects.length == monitorIds.length;
 616         for (int i = 0; i < lockedObjects.length; i++) {
 617             if (lockedObjects[i] == value || monitorIds[i] == value) {
 618                 return true;
 619             }
 620         }
 621         return false;
 622     }
 623 
 624     public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) {
 625         /*
 626          * (lstadler) if somebody is tempted to remove/disable this clearing code: it's possible to
 627          * remove it for normal compilations, but not for OSR compilations - otherwise dead object
 628          * slots at the OSR entry aren't cleared. it is also not enough to rely on PiNodes with
 629          * Kind.Illegal, because the conflicting branch might not have been parsed.
 630          */
 631         if (!clearNonLiveLocals) {
 632             return;
 633         }
 634         if (liveIn) {
 635             for (int i = 0; i < locals.length; i++) {
 636                 if (!liveness.localIsLiveIn(block, i)) {
 637                     assert locals[i] != TWO_SLOT_MARKER || locals[i - 1] == null : "Clearing of second slot must have cleared the first slot too";
 638                     locals[i] = null;
 639                 }
 640             }
 641         } else {
 642             for (int i = 0; i < locals.length; i++) {
 643                 if (!liveness.localIsLiveOut(block, i)) {
 644                     assert locals[i] != TWO_SLOT_MARKER || locals[i - 1] == null : "Clearing of second slot must have cleared the first slot too";
 645                     locals[i] = null;
 646                 }
 647             }
 648         }
 649     }
 650 
 651     /**


src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File