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.GraalOptions;
46 import org.graalvm.compiler.core.common.PermanentBailoutException;
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;
67 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
68 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.SideEffectsState;
69 import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
486 node.inferStamp();
487 }
488 }
489
490 public void insertLoopPhis(LocalLiveness liveness, int loopId, LoopBeginNode loopBegin, boolean forcePhis, boolean stampFromValueForForcedPhis) {
491 for (int i = 0; i < localsSize(); i++) {
492 boolean changedInLoop = liveness.localIsChangedInLoop(loopId, i);
493 if (forcePhis || changedInLoop) {
494 locals[i] = createLoopPhi(loopBegin, locals[i], stampFromValueForForcedPhis && !changedInLoop);
495 }
496 }
497 for (int i = 0; i < stackSize(); i++) {
498 stack[i] = createLoopPhi(loopBegin, stack[i], false);
499 }
500 for (int i = 0; i < lockedObjects.length; i++) {
501 lockedObjects[i] = createLoopPhi(loopBegin, lockedObjects[i], false);
502 }
503 }
504
505 public void insertLoopProxies(LoopExitNode loopExit, FrameStateBuilder loopEntryState) {
506 for (int i = 0; i < localsSize(); i++) {
507 ValueNode value = locals[i];
508 if (value != null && value != TWO_SLOT_MARKER && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
509 Debug.log(" inserting proxy for %s", value);
510 locals[i] = ProxyNode.forValue(value, loopExit, graph);
511 }
512 }
513 for (int i = 0; i < stackSize(); i++) {
514 ValueNode value = stack[i];
515 if (value != null && value != TWO_SLOT_MARKER && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
516 Debug.log(" inserting proxy for %s", value);
517 stack[i] = ProxyNode.forValue(value, loopExit, graph);
518 }
519 }
520 for (int i = 0; i < lockedObjects.length; i++) {
521 ValueNode value = lockedObjects[i];
522 if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
523 Debug.log(" inserting proxy for %s", value);
524 lockedObjects[i] = ProxyNode.forValue(value, loopExit, graph);
525 }
526 }
527 }
528
529 public void insertProxies(Function<ValueNode, ValueNode> proxyFunction) {
530 for (int i = 0; i < localsSize(); i++) {
531 ValueNode value = locals[i];
532 if (value != null && value != TWO_SLOT_MARKER) {
533 Debug.log(" inserting proxy for %s", value);
534 locals[i] = proxyFunction.apply(value);
535 }
536 }
537 for (int i = 0; i < stackSize(); i++) {
538 ValueNode value = stack[i];
539 if (value != null && value != TWO_SLOT_MARKER) {
540 Debug.log(" inserting proxy for %s", value);
541 stack[i] = proxyFunction.apply(value);
542 }
543 }
544 for (int i = 0; i < lockedObjects.length; i++) {
545 ValueNode value = lockedObjects[i];
546 if (value != null) {
547 Debug.log(" inserting proxy for %s", value);
548 lockedObjects[i] = proxyFunction.apply(value);
549 }
550 }
551 }
552
553 private ValueNode createLoopPhi(AbstractMergeNode block, ValueNode value, boolean stampFromValue) {
554 if (value == null || value == TWO_SLOT_MARKER) {
555 return value;
556 }
557 assert !block.isPhiAtMerge(value) : "phi function for this block already created";
558
559 ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp() : value.stamp().unrestricted(), block));
560 phi.addInput(value);
561 return phi;
562 }
563
564 /**
565 * Adds a locked monitor to this frame state.
566 *
567 * @param object the object whose monitor will be locked.
979 public boolean isAfterSideEffect() {
980 return sideEffects != null;
981 }
982
983 @Override
984 public Iterable<StateSplit> sideEffects() {
985 return sideEffects;
986 }
987
988 @Override
989 public void addSideEffect(StateSplit sideEffect) {
990 assert sideEffect != null;
991 assert sideEffect.hasSideEffect();
992 if (sideEffects == null) {
993 sideEffects = new ArrayList<>(4);
994 }
995 sideEffects.add(sideEffect);
996 }
997
998 public void traceState() {
999 Debug.log("| state [nr locals = %d, stack depth = %d, method = %s]", localsSize(), stackSize(), getMethod());
1000 for (int i = 0; i < localsSize(); ++i) {
1001 ValueNode value = locals[i];
1002 Debug.log("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
1003 }
1004 for (int i = 0; i < stackSize(); ++i) {
1005 ValueNode value = stack[i];
1006 Debug.log("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
1007 }
1008 }
1009 }
|
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.GraalOptions;
46 import org.graalvm.compiler.core.common.PermanentBailoutException;
47 import org.graalvm.compiler.core.common.type.StampFactory;
48 import org.graalvm.compiler.core.common.type.StampPair;
49 import org.graalvm.compiler.debug.DebugContext;
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;
67 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
68 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.SideEffectsState;
69 import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
486 node.inferStamp();
487 }
488 }
489
490 public void insertLoopPhis(LocalLiveness liveness, int loopId, LoopBeginNode loopBegin, boolean forcePhis, boolean stampFromValueForForcedPhis) {
491 for (int i = 0; i < localsSize(); i++) {
492 boolean changedInLoop = liveness.localIsChangedInLoop(loopId, i);
493 if (forcePhis || changedInLoop) {
494 locals[i] = createLoopPhi(loopBegin, locals[i], stampFromValueForForcedPhis && !changedInLoop);
495 }
496 }
497 for (int i = 0; i < stackSize(); i++) {
498 stack[i] = createLoopPhi(loopBegin, stack[i], false);
499 }
500 for (int i = 0; i < lockedObjects.length; i++) {
501 lockedObjects[i] = createLoopPhi(loopBegin, lockedObjects[i], false);
502 }
503 }
504
505 public void insertLoopProxies(LoopExitNode loopExit, FrameStateBuilder loopEntryState) {
506 DebugContext debug = graph.getDebug();
507 for (int i = 0; i < localsSize(); i++) {
508 ValueNode value = locals[i];
509 if (value != null && value != TWO_SLOT_MARKER && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
510 debug.log(" inserting proxy for %s", value);
511 locals[i] = ProxyNode.forValue(value, loopExit, graph);
512 }
513 }
514 for (int i = 0; i < stackSize(); i++) {
515 ValueNode value = stack[i];
516 if (value != null && value != TWO_SLOT_MARKER && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
517 debug.log(" inserting proxy for %s", value);
518 stack[i] = ProxyNode.forValue(value, loopExit, graph);
519 }
520 }
521 for (int i = 0; i < lockedObjects.length; i++) {
522 ValueNode value = lockedObjects[i];
523 if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
524 debug.log(" inserting proxy for %s", value);
525 lockedObjects[i] = ProxyNode.forValue(value, loopExit, graph);
526 }
527 }
528 }
529
530 public void insertProxies(Function<ValueNode, ValueNode> proxyFunction) {
531 DebugContext debug = graph.getDebug();
532 for (int i = 0; i < localsSize(); i++) {
533 ValueNode value = locals[i];
534 if (value != null && value != TWO_SLOT_MARKER) {
535 debug.log(" inserting proxy for %s", value);
536 locals[i] = proxyFunction.apply(value);
537 }
538 }
539 for (int i = 0; i < stackSize(); i++) {
540 ValueNode value = stack[i];
541 if (value != null && value != TWO_SLOT_MARKER) {
542 debug.log(" inserting proxy for %s", value);
543 stack[i] = proxyFunction.apply(value);
544 }
545 }
546 for (int i = 0; i < lockedObjects.length; i++) {
547 ValueNode value = lockedObjects[i];
548 if (value != null) {
549 debug.log(" inserting proxy for %s", value);
550 lockedObjects[i] = proxyFunction.apply(value);
551 }
552 }
553 }
554
555 private ValueNode createLoopPhi(AbstractMergeNode block, ValueNode value, boolean stampFromValue) {
556 if (value == null || value == TWO_SLOT_MARKER) {
557 return value;
558 }
559 assert !block.isPhiAtMerge(value) : "phi function for this block already created";
560
561 ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp() : value.stamp().unrestricted(), block));
562 phi.addInput(value);
563 return phi;
564 }
565
566 /**
567 * Adds a locked monitor to this frame state.
568 *
569 * @param object the object whose monitor will be locked.
981 public boolean isAfterSideEffect() {
982 return sideEffects != null;
983 }
984
985 @Override
986 public Iterable<StateSplit> sideEffects() {
987 return sideEffects;
988 }
989
990 @Override
991 public void addSideEffect(StateSplit sideEffect) {
992 assert sideEffect != null;
993 assert sideEffect.hasSideEffect();
994 if (sideEffects == null) {
995 sideEffects = new ArrayList<>(4);
996 }
997 sideEffects.add(sideEffect);
998 }
999
1000 public void traceState() {
1001 DebugContext debug = graph.getDebug();
1002 debug.log("| state [nr locals = %d, stack depth = %d, method = %s]", localsSize(), stackSize(), getMethod());
1003 for (int i = 0; i < localsSize(); ++i) {
1004 ValueNode value = locals[i];
1005 debug.log("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
1006 }
1007 for (int i = 0; i < stackSize(); ++i) {
1008 ValueNode value = stack[i];
1009 debug.log("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value == TWO_SLOT_MARKER ? "second" : value.getStackKind().getJavaName(), value);
1010 }
1011 }
1012 }
|