changeset 16290:e6622e77e8c7

split MacroNode into MacroNode and MacroStateSplitNode
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 30 Jun 2014 11:38:54 +0200
parents b2b362cc1a9f
children da8f16efaa4c
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java
diffstat 15 files changed, 165 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -34,7 +34,7 @@
  *
  * @see ClassSubstitutions#cast(Class, Object)
  */
-public class ClassCastNode extends MacroNode implements Canonicalizable.Binary<ValueNode> {
+public class ClassCastNode extends MacroStateSplitNode implements Canonicalizable.Binary<ValueNode> {
 
     public ClassCastNode(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java	Mon Jun 30 11:38:54 2014 +0200
@@ -35,7 +35,7 @@
  * @see ClassSubstitutions#getClassLoader0(Class)
  */
 @SuppressWarnings("javadoc")
-public class ClassGetClassLoader0Node extends MacroNode implements Canonicalizable {
+public class ClassGetClassLoader0Node extends MacroStateSplitNode implements Canonicalizable {
 
     public ClassGetClassLoader0Node(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -38,7 +38,7 @@
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.replacements.nodes.*;
 
-public class ArrayCopyNode extends MacroNode implements Virtualizable, Lowerable {
+public class ArrayCopyNode extends MacroStateSplitNode implements Virtualizable, Lowerable {
 
     public ArrayCopyNode(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -33,7 +33,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
-public class CallSiteTargetNode extends MacroNode implements Canonicalizable, Lowerable {
+public class CallSiteTargetNode extends MacroStateSplitNode implements Canonicalizable, Lowerable {
 
     public CallSiteTargetNode(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -44,7 +44,7 @@
 /**
  * Node for invocation methods defined on the class {@link MethodHandle}.
  */
-public class MethodHandleNode extends MacroNode implements Simplifiable {
+public class MethodHandleNode extends MacroStateSplitNode implements Simplifiable {
 
     /** The method that this node is representing. */
     private final IntrinsicMethod intrinsicMethod;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -39,7 +39,7 @@
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.replacements.nodes.*;
 
-public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider {
+public class ObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider {
 
     public ObjectCloneNode(Invoke invoke) {
         super(invoke);
@@ -107,7 +107,7 @@
     /*
      * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an
      * exact type) and if it is a cloneable type.
-     * 
+     *
      * If yes, then the exact type is returned, otherwise it returns null.
      */
     private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -33,7 +33,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
-public class ReflectionGetCallerClassNode extends MacroNode implements Canonicalizable, Lowerable {
+public class ReflectionGetCallerClassNode extends MacroStateSplitNode implements Canonicalizable, Lowerable {
 
     public ReflectionGetCallerClassNode(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,13 +24,13 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.spi.*;
@@ -39,7 +39,22 @@
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.replacements.*;
 
-public class MacroNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
+/**
+ * Macro nodes can be used to temporarily replace an invoke (usually by using the
+ * {@link MacroSubstitution} annotation). They can, for example, be used to implement constant
+ * folding for known JDK functions like {@link Class#isInterface()}.<br/>
+ * <br/>
+ * During lowering, multiple sources are queried in order to look for a replacement:
+ * <ul>
+ * <li>If {@link #getLoweredSnippetGraph(LoweringTool)} returns a non-null result, this graph is
+ * used as a replacement.</li>
+ * <li>If a {@link MethodSubstitution} for the target method is found, this substitution is used as
+ * a replacement.</li>
+ * <li>Otherwise, the macro node is replaced with an {@link InvokeNode}. Note that this is only
+ * possible if the macro node is a {@link MacroStateSplitNode}.</li>
+ * </ul>
+ */
+public class MacroNode extends FixedWithNextNode implements Lowerable {
 
     @Input protected final NodeInputList<ValueNode> arguments;
 
@@ -49,7 +64,7 @@
     private final InvokeKind invokeKind;
 
     protected MacroNode(Invoke invoke) {
-        super(invoke.asNode().stamp(), invoke.stateAfter());
+        super(StampFactory.forKind(((MethodCallTargetNode) invoke.callTarget()).targetMethod().getSignature().getReturnKind()));
         MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget();
         this.arguments = new NodeInputList<>(this, methodCallTarget.arguments());
         this.bci = invoke.bci();
@@ -70,6 +85,10 @@
         return returnType;
     }
 
+    protected FrameState stateAfter() {
+        return null;
+    }
+
     /**
      * Gets a snippet to be used for lowering this macro node. The returned graph (if non-null) must
      * have been {@linkplain #lowerReplacement(StructuredGraph, LoweringTool) lowered}.
@@ -145,6 +164,7 @@
             InliningUtil.inline(invoke, replacementGraph, false, null);
             Debug.dump(graph(), "After inlining replacement %s", replacementGraph);
         } else {
+            assert stateAfter() != null : "cannot lower to invoke without state: " + this;
             invoke.lower(tool);
         }
     }
@@ -166,23 +186,4 @@
         }
         return invoke;
     }
-
-    protected void replaceSnippetInvokes(StructuredGraph snippetGraph) {
-        for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) {
-            Invoke invoke = call.invoke();
-            if (!call.targetMethod().equals(getTargetMethod())) {
-                throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName());
-            }
-            assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
-            // Here we need to fix the bci of the invoke
-            InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci()));
-            newInvoke.setStateAfter(invoke.stateAfter());
-            snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
-        }
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.ANY_LOCATION;
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * This is an extension of {@link MacroNode} that is a {@link StateSplit} and a
+ * {@link MemoryCheckpoint}.
+ */
+public class MacroStateSplitNode extends MacroNode implements StateSplit, MemoryCheckpoint.Single {
+
+    @Input(InputType.State) private FrameState stateAfter;
+
+    protected MacroStateSplitNode(Invoke invoke) {
+        super(invoke);
+        this.stateAfter = invoke.stateAfter();
+    }
+
+    @Override
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
+
+    public LocationIdentity getLocationIdentity() {
+        return LocationIdentity.ANY_LOCATION;
+    }
+
+    public MemoryCheckpoint asMemoryCheckpoint() {
+        return this;
+    }
+
+    public MemoryPhiNode asMemoryPhi() {
+        return null;
+    }
+
+    protected void replaceSnippetInvokes(StructuredGraph snippetGraph) {
+        for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) {
+            Invoke invoke = call.invoke();
+            if (!call.targetMethod().equals(getTargetMethod())) {
+                throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName());
+            }
+            assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
+            // Here we need to fix the bci of the invoke
+            InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci()));
+            newInvoke.setStateAfter(invoke.stateAfter());
+            snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
+        }
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -31,7 +31,7 @@
  * This node class can be used to create {@link MacroNode}s for simple pure functions like
  * {@link System#identityHashCode(Object)}.
  */
-public abstract class PureFunctionMacroNode extends MacroNode implements Canonicalizable {
+public abstract class PureFunctionMacroNode extends MacroStateSplitNode implements Canonicalizable {
 
     public PureFunctionMacroNode(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,11 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.truffle.*;
 
@@ -50,6 +53,11 @@
     }
 
     @Override
+    public void lower(LoweringTool tool) {
+        throw new GraalInternalError(GraphUtil.approxSourceException(this, new RuntimeException("assumption could not be evaluated to a constant")));
+    }
+
+    @Override
     public void simplify(SimplifierTool tool) {
         ValueNode assumption = getAssumption();
         if (tool.assumptions() != null && assumption.isConstant()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 public class BailoutNode extends MacroNode implements Canonicalizable {
@@ -35,13 +36,20 @@
         assert arguments.size() == 1;
     }
 
+    public ValueNode getMessage() {
+        return arguments.get(0);
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        throw new BailoutException("bailout (message is not compile-time constant, so no additional information is available)");
+    }
+
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        ValueNode arg = arguments.get(0);
-        String message = "";
-        if (arg.isConstant()) {
-            message = arg.asConstant().toValueString();
+        if (getMessage().isConstant()) {
+            throw new BailoutException(getMessage().asConstant().toValueString());
         }
-        throw new BailoutException(message);
+        return this;
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -26,7 +26,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
-public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType {
+public class NeverInlineMacroNode extends MacroStateSplitNode implements com.oracle.graal.graph.IterableNodeType {
 
     public NeverInlineMacroNode(Invoke invoke) {
         super(invoke);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,10 +22,11 @@
  */
 package com.oracle.graal.truffle.nodes.asserts;
 
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.nodes.*;
 
-public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType {
+public class NeverPartOfCompilationNode extends MacroNode implements IterableNodeType {
 
     private final String message;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Thu Jun 26 13:26:58 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Mon Jun 30 11:38:54 2014 +0200
@@ -34,7 +34,9 @@
 /**
  * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}.
  */
-public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable, StateSplit {
+
+    @Input(InputType.State) private FrameState stateAfter;
 
     private static final int ARGUMENT_COUNT = 4;
     private static final int OBJECT_ARGUMENT_INDEX = 0;
@@ -45,6 +47,7 @@
     public CustomizedUnsafeStoreMacroNode(Invoke invoke) {
         super(invoke, "The location argument could not be resolved to a constant.");
         assert arguments.size() == ARGUMENT_COUNT;
+        this.stateAfter = invoke.stateAfter();
     }
 
     @Override
@@ -61,8 +64,21 @@
                 locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
             }
 
-            return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter());
+            return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter);
         }
         return this;
     }
+
+    @Override
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        this.stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
 }