# HG changeset patch # User Gilles Duboscq # Date 1399222696 -7200 # Sun May 04 18:58:16 2014 +0200 # Node ID e118d7bd3b66cf488a0d4e1e6dd9e650f55e5bf3 # Parent 5d0dd6a6f6b3f95fd95a7c92332ecd6091e28584 HSAIL Deopt support for VirtualObjects diff -r 5d0dd6a6f6b3 -r e118d7bd3b66 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java --- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Sun May 04 01:28:07 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Sun May 04 18:58:16 2014 +0200 @@ -135,7 +135,7 @@ * with HSAIL code. */ public boolean canHandleDeoptVirtualObjects() { - return false; + return true; } /** diff -r 5d0dd6a6f6b3 -r e118d7bd3b66 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Sun May 04 01:28:07 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Sun May 04 18:58:16 2014 +0200 @@ -32,6 +32,9 @@ import java.lang.reflect.*; import java.util.*; +import java.util.Map.Entry; +import java.util.function.*; +import java.util.stream.*; import com.amd.okra.*; import com.oracle.graal.api.code.*; @@ -69,9 +72,11 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.virtual.nodes.*; /** * HSAIL specific backend. @@ -1086,26 +1091,53 @@ } private static FrameState createFrameState(BytecodeFrame lowLevelFrame, ParameterNode hsailFrame, HotSpotProviders providers, HotSpotVMConfig config, int numSRegs, int numDRegs) { + return createFrameState(lowLevelFrame, hsailFrame, providers, config, numSRegs, numDRegs, new HashMap()); + } + + private static FrameState createFrameState(BytecodeFrame lowLevelFrame, ParameterNode hsailFrame, HotSpotProviders providers, HotSpotVMConfig config, int numSRegs, int numDRegs, + Map virtualObjects) { + FrameState outterFrameState = null; + if (lowLevelFrame.caller() != null) { + outterFrameState = createFrameState(lowLevelFrame.caller(), hsailFrame, providers, config, numSRegs, numDRegs, virtualObjects); + } StructuredGraph hostGraph = hsailFrame.graph(); + Function lirValueToHirNode = v -> getNodeForValueFromFrame(v, hsailFrame, hostGraph, providers, config, numSRegs, numDRegs, virtualObjects); ValueNode[] locals = new ValueNode[lowLevelFrame.numLocals]; for (int i = 0; i < lowLevelFrame.numLocals; i++) { - locals[i] = getNodeForValueFromFrame(lowLevelFrame.getLocalValue(i), hsailFrame, hostGraph, providers, config, numSRegs, numDRegs); + locals[i] = lirValueToHirNode.apply(lowLevelFrame.getLocalValue(i)); } List stack = new ArrayList<>(lowLevelFrame.numStack); for (int i = 0; i < lowLevelFrame.numStack; i++) { - stack.add(getNodeForValueFromFrame(lowLevelFrame.getStackValue(i), hsailFrame, hostGraph, providers, config, numSRegs, numDRegs)); + stack.add(lirValueToHirNode.apply(lowLevelFrame.getStackValue(i))); } ValueNode[] locks = new ValueNode[lowLevelFrame.numLocks]; MonitorIdNode[] monitorIds = new MonitorIdNode[lowLevelFrame.numLocks]; for (int i = 0; i < lowLevelFrame.numLocks; i++) { HotSpotMonitorValue lockValue = (HotSpotMonitorValue) lowLevelFrame.getLockValue(i); - locks[i] = getNodeForValueFromFrame(lockValue, hsailFrame, hostGraph, providers, config, numSRegs, numDRegs); + locks[i] = lirValueToHirNode.apply(lockValue); monitorIds[i] = getMonitorIdForHotSpotMonitorValueFromFrame(lockValue, hsailFrame, hostGraph); } FrameState frameState = hostGraph.add(new FrameState(lowLevelFrame.getMethod(), lowLevelFrame.getBCI(), locals, stack, locks, monitorIds, lowLevelFrame.rethrowException, false)); - if (lowLevelFrame.caller() != null) { - frameState.setOuterFrameState(createFrameState(lowLevelFrame.caller(), hsailFrame, providers, config, numSRegs, numDRegs)); + if (outterFrameState != null) { + frameState.setOuterFrameState(outterFrameState); } + Map virtualObjectsCopy; + // TODO this could be implemented more efficiently with a mark into the map + // unfortunately LinkedHashMap doesn't seem to provide that. + List virtualStates = new ArrayList<>(virtualObjects.size()); + do { + virtualObjectsCopy = new HashMap<>(virtualObjects); + virtualStates.clear(); + for (Entry entry : virtualObjectsCopy.entrySet()) { + VirtualObject virtualObject = entry.getKey(); + VirtualObjectNode virtualObjectNode = entry.getValue(); + List fieldValues = Arrays.stream(virtualObject.getValues()).map(lirValueToHirNode).collect(Collectors.toList()); + virtualStates.add(new VirtualObjectState(virtualObjectNode, fieldValues)); + } + // New virtual objects may have been discovered while processing the previous set. + // Wait until a fixed point is reached + } while (virtualObjectsCopy.size() < virtualObjects.size()); + virtualStates.forEach(vos -> frameState.addVirtualObjectMapping(hostGraph.unique(vos))); return frameState; } @@ -1118,18 +1150,18 @@ } private static ValueNode getNodeForValueFromFrame(Value localValue, ParameterNode hsailFrame, StructuredGraph hostGraph, HotSpotProviders providers, HotSpotVMConfig config, int numSRegs, - int numDRegs) { + int numDRegs, Map virtualObjects) { ValueNode valueNode; if (localValue instanceof Constant) { valueNode = ConstantNode.forConstant((Constant) localValue, providers.getMetaAccess(), hostGraph); } else if (localValue instanceof VirtualObject) { - throw GraalInternalError.unimplemented(); + valueNode = getNodeForVirtualObjectFromFrame((VirtualObject) localValue, virtualObjects, hostGraph); } else if (localValue instanceof StackSlot) { StackSlot slot = (StackSlot) localValue; valueNode = getNodeForStackSlotFromFrame(slot, localValue.getKind(), hsailFrame, hostGraph, providers, config, numSRegs, numDRegs); } else if (localValue instanceof HotSpotMonitorValue) { HotSpotMonitorValue hotSpotMonitorValue = (HotSpotMonitorValue) localValue; - return getNodeForValueFromFrame(hotSpotMonitorValue.getOwner(), hsailFrame, hostGraph, providers, config, numSRegs, numDRegs); + return getNodeForValueFromFrame(hotSpotMonitorValue.getOwner(), hsailFrame, hostGraph, providers, config, numSRegs, numDRegs, virtualObjects); } else if (localValue instanceof RegisterValue) { RegisterValue registerValue = (RegisterValue) localValue; int regNumber = registerValue.getRegister().number; @@ -1142,6 +1174,16 @@ return valueNode; } + private static ValueNode getNodeForVirtualObjectFromFrame(VirtualObject virtualObject, Map virtualObjects, StructuredGraph hostGraph) { + return virtualObjects.computeIfAbsent(virtualObject, vo -> { + if (vo.getType().isArray()) { + return hostGraph.add(new VirtualArrayNode(vo.getType().getComponentType(), vo.getValues().length)); + } else { + return hostGraph.add(new VirtualInstanceNode(vo.getType(), true)); + } + }); + } + private static ValueNode getNodeForRegisterFromFrame(int regNumber, Kind valueKind, ParameterNode hsailFrame, StructuredGraph hostGraph, HotSpotProviders providers, HotSpotVMConfig config, int numSRegs) { ValueNode valueNode; diff -r 5d0dd6a6f6b3 -r e118d7bd3b66 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Sun May 04 01:28:07 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Sun May 04 18:58:16 2014 +0200 @@ -45,7 +45,7 @@ this.fieldValues = new NodeInputList<>(this, fieldValues); } - private VirtualObjectState(VirtualObjectNode object, List fieldValues) { + public VirtualObjectState(VirtualObjectNode object, List fieldValues) { super(object); assert object.entryCount() == fieldValues.size(); this.fieldValues = new NodeInputList<>(this, fieldValues);