Mercurial > hg > graal-compiler
diff graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java @ 13836:64c77f0577bb
More documentation and improvements of Simple Language
author | Christian Wimmer <christian.wimmer@oracle.com> |
---|---|
date | Thu, 30 Jan 2014 17:53:27 -0800 |
parents | b16ec83edc73 |
children | afd6fa5e8229 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java Thu Jan 30 17:52:24 2014 -0800 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java Thu Jan 30 17:53:27 2014 -0800 @@ -27,12 +27,25 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.sl.nodes.*; +/** + * Node to write a local variable to a function's {@link VirtualFrame frame}. The Truffle frame API + * allows to store primitive values of all Java primitive types, and Object values. + */ @NodeChild(value = "valueNode") @NodeField(name = "slot", type = FrameSlot.class) public abstract class SLWriteLocalVariableNode extends SLExpressionNode { + /** + * Returns the descriptor of the accessed local variable. The implementation of this method is + * created by the Truffle DSL based on the {@link NodeField} annotation on the class. + */ protected abstract FrameSlot getSlot(); + /** + * Specialized method to write a primitive {@code long} value}. This is only possible if the + * local variable also has currently the type {@code long}, therefore a Truffle DSL + * {@link #isLongKind() custom guard} is specified. + */ @Specialization(guards = "isLongKind") protected long write(VirtualFrame frame, long value) { frame.setLong(getSlot(), value); @@ -45,9 +58,24 @@ return value; } + /** + * Generic write method that works for all possible types. + * <p> + * Why is this method annotated with {@link Specialization} and not {@link Generic}? For a + * {@link Generic} method, the Truffle DSL generated code would try all other specializations + * first before calling this method. We know that all these specializations would fail their + * guards, so there is no point in calling them. Since this method takes a value of type + * {@link Object}, it is guaranteed to never fail, i.e., once we are in this specialization the + * node will never be re-specialized. + */ @Specialization protected Object write(VirtualFrame frame, Object value) { if (getSlot().getKind() != FrameSlotKind.Object) { + /* + * The local variable has still a primitive type, we need to change it to Object. Since + * the variable type is important when the compiler optimizes a method, we also discard + * compiled code. + */ CompilerDirectives.transferToInterpreterAndInvalidate(); getSlot().setKind(FrameSlotKind.Object); } @@ -55,6 +83,9 @@ return value; } + /** + * Guard function that the local variable has the type {@code long}. + */ protected boolean isLongKind() { return isKind(FrameSlotKind.Long); } @@ -65,12 +96,22 @@ private boolean isKind(FrameSlotKind kind) { if (getSlot().getKind() == kind) { + /* Success: the frame slot has the expected kind. */ return true; } else if (getSlot().getKind() == FrameSlotKind.Illegal) { + /* + * This is the first write to this local variable. We can set the type to the one we + * expect. Since the variable type is important when the compiler optimizes a method, we + * also discard compiled code. + */ CompilerDirectives.transferToInterpreterAndInvalidate(); getSlot().setKind(kind); return true; } else { + /* + * Failure: the frame slot has the wrong kind, the Truffle DSL generated code will + * choose a different specialization. + */ return false; } }