diff graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java @ 9793:b4f12c603be5

added support for the runtime to specify for each foreign call whether it is re-executable and what memory locations it kills
author Doug Simon <doug.simon@oracle.com>
date Wed, 22 May 2013 16:27:25 +0200
parents 06dc2d2324d6
children 7f92277c3a37
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Tue May 21 21:46:26 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed May 22 16:27:25 2013 +0200
@@ -33,22 +33,31 @@
  * Node for a {@linkplain ForeignCallDescriptor foreign} call.
  */
 @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}")
-public class ForeignCallNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint {
+public class ForeignCallNode extends AbstractStateSplit implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint {
 
     @Input private final NodeInputList<ValueNode> arguments;
+    private final MetaAccessProvider runtime;
+    @Input private FrameState deoptState;
 
     private final ForeignCallDescriptor descriptor;
 
-    public ForeignCallNode(ForeignCallDescriptor descriptor, ValueNode... arguments) {
+    public ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) {
         super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
         this.arguments = new NodeInputList<>(this, arguments);
         this.descriptor = descriptor;
+        this.runtime = runtime;
     }
 
-    protected ForeignCallNode(ForeignCallDescriptor descriptor, Stamp stamp) {
+    protected ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, Stamp stamp) {
         super(stamp);
         this.arguments = new NodeInputList<>(this);
         this.descriptor = descriptor;
+        this.runtime = runtime;
+    }
+
+    @Override
+    public boolean hasSideEffect() {
+        return !runtime.isReexecutable(descriptor);
     }
 
     public ForeignCallDescriptor getDescriptor() {
@@ -57,7 +66,7 @@
 
     @Override
     public LocationIdentity[] getLocationIdentities() {
-        return new LocationIdentity[]{LocationIdentity.ANY_LOCATION};
+        return runtime.getKilledLocationIdentities(descriptor);
     }
 
     protected Value[] operands(LIRGeneratorTool gen) {
@@ -79,6 +88,30 @@
     }
 
     @Override
+    public FrameState getDeoptimizationState() {
+        if (deoptState != null) {
+            return deoptState;
+        } else if (stateAfter() != null) {
+            FrameState stateDuring = stateAfter();
+            if ((stateDuring.stackSize() > 0 && stateDuring.stackAt(stateDuring.stackSize() - 1) == this) || (stateDuring.stackSize() > 1 && stateDuring.stackAt(stateDuring.stackSize() - 2) == this)) {
+                stateDuring = stateDuring.duplicateModified(stateDuring.bci, stateDuring.rethrowException(), this.kind());
+            }
+            setDeoptimizationState(stateDuring);
+            return stateDuring;
+        }
+        return null;
+    }
+
+    @Override
+    public void setDeoptimizationState(FrameState f) {
+        updateUsages(deoptState, f);
+        if (deoptState != null) {
+            throw new IllegalStateException(toString(Verbosity.Debugger));
+        }
+        deoptState = f;
+    }
+
+    @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
             return super.toString(verbosity) + "#" + descriptor;
@@ -95,4 +128,9 @@
     public DeoptimizationReason getDeoptimizationReason() {
         return null;
     }
+
+    @Override
+    public boolean isCallSiteDeoptimization() {
+        return false;
+    }
 }