Skip to content

Commit

Permalink
Document default local behaviour; add PE constant assert for bci on l…
Browse files Browse the repository at this point in the history
…oop entry
  • Loading branch information
DSouzaM committed Oct 15, 2024
1 parent 4d21216 commit fe6e099
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 11 deletions.
3 changes: 2 additions & 1 deletion truffle/docs/bytecode_dsl/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ These helpers often have extra indirection, so the built-in operations and acces

Local reads/writes should always use these abstractions; **you should not directly read from or write to the frame**.

It is undefined behaviour to load a local before a value is stored into it.
Loading a local before a value is stored into it throws a [`FrameSlotTypeException`](https://github.com/oracle/graal/blob/master/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeException.java).
You can specify a `defaultLocalValue` in [`@GenerateBytecode`](https://github.com/oracle/graal/blob/master/truffle/src/com.oracle.truffle.api.bytecode/src/com/oracle/truffle/api/bytecode/GenerateBytecode.java) to instead give uninitialized locals a default value.


### Scoping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,7 @@ long continueAt(BasicInterpreterBase $root, VirtualFrame frame, VirtualFrame loc
int op;
long temp;
LoopCounter loopCounter = new LoopCounter();
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -6012,7 +6013,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}.
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,7 @@ long continueAt(BasicInterpreterUnsafe $root, VirtualFrame frame, VirtualFrame l
int op;
long temp;
LoopCounter loopCounter = new LoopCounter();
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -6012,7 +6013,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}.
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4959,6 +4959,7 @@ long continueAt(BasicInterpreterWithBE $root, VirtualFrame frame, VirtualFrame l
int op;
long temp;
LoopCounter loopCounter = new LoopCounter();
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -10041,7 +10042,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}.
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3245,6 +3245,7 @@ long continueAt(BasicInterpreterWithOptimizations $root, VirtualFrame frame, Vir
int op;
long temp;
LoopCounter loopCounter = new LoopCounter();
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -6009,7 +6010,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal produces the default local value (LOCAL_DEFAULT_VALUE).
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4975,6 +4975,7 @@ long continueAt(BasicInterpreterWithStoreBytecodeIndexInFrame $root, VirtualFram
int op;
long temp;
LoopCounter loopCounter = new LoopCounter();
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -8728,6 +8729,7 @@ long continueAt(BasicInterpreterWithStoreBytecodeIndexInFrame $root, VirtualFram
int sp = (short) (startState >>> 32);
int op;
long temp;
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -11241,7 +11243,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}.
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3261,6 +3261,7 @@ long continueAt(BasicInterpreterWithUncached $root, VirtualFrame frame, VirtualF
long temp;
LoopCounter loopCounter = new LoopCounter();
FRAMES.setInt(localFrame, BCI_INDEX, -1);
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -4743,6 +4744,7 @@ long continueAt(BasicInterpreterWithUncached $root, VirtualFrame frame, VirtualF
int sp = (short) (startState >>> 32);
int op;
long temp;
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -7033,7 +7035,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}.
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4347,6 +4347,7 @@ long continueAt(SLBytecodeRootNodeGen $root, VirtualFrame frame, long startState
long temp;
LoopCounter loopCounter = new LoopCounter();
FRAMES.setInt(frame, BCI_INDEX, -1);
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -7617,6 +7618,7 @@ long continueAt(SLBytecodeRootNodeGen $root, VirtualFrame frame, long startState
int sp = (short) (startState >>> 32);
int op;
long temp;
CompilerAsserts.partialEvaluationConstant(bci);
loop: while (true) {
op = BYTES.getShort(bc, bci);
try {
Expand Down Expand Up @@ -9760,7 +9762,7 @@ private void validateLocalScope(BytecodeLocal local) {
* Signature: LoadLocal() -> Object
* <p>
* LoadLocal reads {@code local} from the current frame.
* If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
* If a value has not been written to the local, LoadLocal throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}.
*
* @param local the local to load.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12816,6 +12816,8 @@ private List<CodeExecutableElement> createContinueAt() {
b.statement("FRAMES.setInt(" + localFrame() + ", " + BCI_INDEX + ", -1)");
}

b.startStatement().startStaticCall(types.CompilerAsserts, "partialEvaluationConstant").string("bci").end().end();

b.string("loop: ").startWhile().string("true").end().startBlock();

// filtered instructions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,10 @@ Conditional implements a conditional expression (e.g., {@code condition ? thens
.setInstruction(m.instruction(InstructionKind.LOAD_EXCEPTION, "load.exception", m.signature(Object.class))//
.addImmediate(ImmediateKind.STACK_POINTER, "exception_sp"));
m.loadLocalOperation = m.operation(OperationKind.LOAD_LOCAL, "LoadLocal",
"""
String.format("""
LoadLocal reads {@code local} from the current frame.
If a value has not been written to the local, LoadLocal produces the default value as defined in the {@link FrameDescriptor} ({@code null} by default).
""") //
If a value has not been written to the local, LoadLocal %s.
""", loadLocalUndefinedBehaviour(m))) //
.setOperationBeginArguments(new OperationArgument(types.BytecodeLocal, Encoding.LOCAL, "local", "the local to load")) //
.setInstruction(m.instruction(InstructionKind.LOAD_LOCAL, "load.local", m.signature(Object.class)) //
.addImmediate(ImmediateKind.LOCAL_OFFSET, "local_offset"));
Expand Down Expand Up @@ -372,6 +372,14 @@ public static void addCheckBooleanInstruction(BytecodeDSLModel m) {
}
}

private static String loadLocalUndefinedBehaviour(BytecodeDSLModel m) {
if (m.defaultLocalValue == null || m.defaultLocalValue.isEmpty()) {
return "throws a {@link com.oracle.truffle.api.frame.FrameSlotTypeException}";
} else {
return String.format("produces the default local value (%s)", m.defaultLocalValue);
}
}

private static DynamicOperandModel child(String name) {
return new DynamicOperandModel(List.of(name), false, false);
}
Expand Down

0 comments on commit fe6e099

Please sign in to comment.