< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java
Print this page
*** 20,33 ****
--- 20,39 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot.phases;
+ import static jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
+ import jdk.vm.ci.meta.DeoptimizationAction;
+ import jdk.vm.ci.meta.DeoptimizationReason;
+ import jdk.vm.ci.meta.JavaConstant;
+ import jdk.vm.ci.meta.JavaKind;
import org.graalvm.compiler.core.common.PermanentBailoutException;
import org.graalvm.compiler.core.common.cfg.Loop;
+ import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
*** 35,60 ****
import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.loop.phases.LoopTransformations;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.AbstractBeginNode;
- import org.graalvm.compiler.nodes.AbstractLocalNode;
import org.graalvm.compiler.nodes.EntryMarkerNode;
import org.graalvm.compiler.nodes.EntryProxyNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.extended.OSRLocalNode;
import org.graalvm.compiler.nodes.extended.OSRLockNode;
import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode;
import org.graalvm.compiler.nodes.extended.OSRStartNode;
import org.graalvm.compiler.nodes.java.AccessMonitorNode;
import org.graalvm.compiler.nodes.java.MonitorEnterNode;
import org.graalvm.compiler.nodes.java.MonitorExitNode;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.Option;
--- 41,69 ----
import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.loop.phases.LoopTransformations;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.EntryMarkerNode;
import org.graalvm.compiler.nodes.EntryProxyNode;
+ import org.graalvm.compiler.nodes.FixedGuardNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FrameState;
+ import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.ParameterNode;
+ import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.extended.OSRLocalNode;
import org.graalvm.compiler.nodes.extended.OSRLockNode;
import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode;
import org.graalvm.compiler.nodes.extended.OSRStartNode;
import org.graalvm.compiler.nodes.java.AccessMonitorNode;
+ import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.java.MonitorEnterNode;
import org.graalvm.compiler.nodes.java.MonitorExitNode;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.Option;
*** 170,188 ****
value = osrState.localAt(i);
}
if (value instanceof EntryProxyNode) {
EntryProxyNode proxy = (EntryProxyNode) value;
/*
! * we need to drop the stamp since the types we see during OSR may be too precise
! * (if a branch was not parsed for example).
*/
! Stamp s = proxy.stamp().unrestricted();
! AbstractLocalNode osrLocal = null;
if (i >= localsSize) {
! osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, s));
} else {
! osrLocal = graph.addOrUnique(new OSRLocalNode(i, s));
}
proxy.replaceAndDelete(osrLocal);
} else {
assert value == null || value instanceof OSRLocalNode;
}
--- 179,214 ----
value = osrState.localAt(i);
}
if (value instanceof EntryProxyNode) {
EntryProxyNode proxy = (EntryProxyNode) value;
/*
! * We need to drop the stamp since the types we see during OSR may be too precise
! * (if a branch was not parsed for example). In cases when this is possible, we
! * insert a guard and narrow the OSRLocal stamp at its usages.
*/
! Stamp narrowedStamp = proxy.value().stamp();
! Stamp unrestrictedStamp = proxy.stamp().unrestricted();
! ValueNode osrLocal;
if (i >= localsSize) {
! osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
} else {
! osrLocal = graph.addOrUnique(new OSRLocalNode(i, unrestrictedStamp));
! }
! // Speculate on the OSRLocal stamps that could be more precise.
! OSRLocalSpeculationReason reason = new OSRLocalSpeculationReason(osrState.bci, narrowedStamp, i);
! if (graph.getSpeculationLog().maySpeculate(reason) && osrLocal instanceof OSRLocalNode && value.getStackKind().equals(JavaKind.Object) && !narrowedStamp.isUnrestricted()) {
! // Add guard.
! LogicNode check = graph.addOrUniqueWithInputs(InstanceOfNode.createHelper((ObjectStamp) narrowedStamp, osrLocal, null, null));
! JavaConstant constant = graph.getSpeculationLog().speculate(reason);
! FixedGuardNode guard = graph.add(new FixedGuardNode(check, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, constant, false));
! graph.addAfterFixed(osrStart, guard);
!
! // Replace with a more specific type at usages.
! // We know that we are at the root,
! // so we need to replace the proxy in the state.
! proxy.replaceAtMatchingUsages(osrLocal, n -> n == osrState);
! osrLocal = graph.addOrUnique(new PiNode(osrLocal, narrowedStamp, guard));
}
proxy.replaceAndDelete(osrLocal);
} else {
assert value == null || value instanceof OSRLocalNode;
}
*** 266,271 ****
--- 292,323 ----
@Override
public float codeSizeIncrease() {
return 5.0f;
}
+
+ private static class OSRLocalSpeculationReason implements SpeculationReason {
+ private int bci;
+ private Stamp speculatedStamp;
+ private int localIndex;
+
+ OSRLocalSpeculationReason(int bci, Stamp speculatedStamp, int localIndex) {
+ this.bci = bci;
+ this.speculatedStamp = speculatedStamp;
+ this.localIndex = localIndex;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof OSRLocalSpeculationReason) {
+ OSRLocalSpeculationReason that = (OSRLocalSpeculationReason) obj;
+ return this.bci == that.bci && this.speculatedStamp.equals(that.speculatedStamp) && this.localIndex == that.localIndex;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (bci << 16) ^ speculatedStamp.hashCode() ^ localIndex;
+ }
+ }
}
< prev index next >