Skip to content

Commit 56e9b06

Browse files
committed
Fix: Do not generate bci translation logic if tags provided but disabled; transition continuations to cached even if bytecode not updatable
1 parent 87ae08d commit 56e9b06

File tree

2 files changed

+72
-53
lines changed

2 files changed

+72
-53
lines changed

truffle/src/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/bytecode/generator/BytecodeRootNodeElement.java

Lines changed: 71 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -768,12 +768,20 @@ private CodeExecutableElement createContinueAt() {
768768
b.lineComment("Bytecode or tier changed");
769769
b.tree(GeneratorUtils.createTransferToInterpreterAndInvalidate());
770770

771-
if (model.isBytecodeUpdatable()) {
771+
if (model.isBytecodeUpdatable() || model.hasYieldOperation()) {
772772
b.declaration(abstractBytecodeNode.asType(), "oldBytecode", "bc");
773773
b.statement("bc = this.bytecode");
774-
b.startAssign("state").startCall("oldBytecode.transitionState");
774+
775+
if (model.isBytecodeUpdatable()) {
776+
b.startAssign("state");
777+
} else {
778+
b.startStatement();
779+
}
780+
b.startCall("oldBytecode.transition");
775781
b.string("bc");
776-
b.string("state");
782+
if (model.isBytecodeUpdatable()) {
783+
b.string("state");
784+
}
777785
if (model.hasYieldOperation()) {
778786
b.string("continuationRootNode");
779787
}
@@ -11772,8 +11780,10 @@ final class AbstractBytecodeNodeElement extends CodeTypeElement {
1177211780
}
1177311781

1177411782
this.add(createTranslateBytecodeIndex());
11783+
if (model.isBytecodeUpdatable() || model.hasYieldOperation()) {
11784+
this.add(createTransition());
11785+
}
1177511786
if (model.isBytecodeUpdatable()) {
11776-
this.add(createTransitionState());
1177711787
this.add(createToStableBytecodeIndex());
1177811788
this.add(createFromStableBytecodeIndex());
1177911789
this.add(createTransitionInstrumentationIndex());
@@ -12612,7 +12622,7 @@ private CodeExecutableElement createTranslateBytecodeIndex() {
1261212622
if (model.isBytecodeUpdatable()) {
1261312623

1261412624
CodeTreeBuilder tb = CodeTreeBuilder.createBuilder();
12615-
tb.startCall("transitionState");
12625+
tb.startCall("transition");
1261612626
tb.startGroup();
1261712627
tb.cast(this.asType());
1261812628
tb.string("newNode");
@@ -12632,18 +12642,20 @@ private CodeExecutableElement createTranslateBytecodeIndex() {
1263212642
return ex;
1263312643
}
1263412644

12635-
private CodeExecutableElement createTransitionState() {
12636-
CodeExecutableElement transitionState = new CodeExecutableElement(Set.of(FINAL), type(long.class), "transitionState");
12637-
transitionState.addParameter(new CodeVariableElement(this.asType(), "newBytecode"));
12638-
transitionState.addParameter(new CodeVariableElement(type(long.class), "state"));
12645+
private CodeExecutableElement createTransition() {
12646+
// Returns updated state long, if updatable.
12647+
TypeMirror returnType = model.isBytecodeUpdatable() ? type(long.class) : type(void.class);
12648+
12649+
CodeExecutableElement ex = new CodeExecutableElement(Set.of(FINAL), returnType, "transition");
12650+
ex.addParameter(new CodeVariableElement(this.asType(), "newBytecode"));
12651+
if (model.isBytecodeUpdatable()) {
12652+
ex.addParameter(new CodeVariableElement(type(long.class), "state"));
12653+
}
1263912654
if (model.hasYieldOperation()) {
12640-
transitionState.addParameter(new CodeVariableElement(continuationRootNodeImpl.asType(), "continuationRootNode"));
12655+
ex.addParameter(new CodeVariableElement(continuationRootNodeImpl.asType(), "continuationRootNode"));
1264112656
}
1264212657

12643-
CodeTreeBuilder b = transitionState.createBuilder();
12644-
12645-
b.declaration(arrayOf(type(byte.class)), "oldBc", "this.oldBytecodes");
12646-
b.declaration(arrayOf(type(byte.class)), "newBc", "newBytecode.bytecodes");
12658+
CodeTreeBuilder b = ex.createBuilder();
1264712659

1264812660
if (model.hasYieldOperation()) {
1264912661
/*
@@ -12657,7 +12669,7 @@ private CodeExecutableElement createTransitionState() {
1265712669
* patches all ContinuationRootNodes with the new bytecode, we don't have to update
1265812670
* anything.
1265912671
*/
12660-
b.startIf().string("continuationRootNode != null && oldBc == null").end().startBlock();
12672+
b.startIf().string("continuationRootNode != null && this.getTier() == ").staticReference(types.BytecodeTier, "UNCACHED").end().startBlock();
1266112673
b.lineComment("Transition continuationRootNode to cached.");
1266212674

1266312675
b.startDeclaration(types.BytecodeLocation, "newContinuationLocation");
@@ -12675,34 +12687,38 @@ private CodeExecutableElement createTransitionState() {
1267512687
b.end();
1267612688
}
1267712689

12678-
b.startIf().string("oldBc == null || this == newBytecode || this.bytecodes == newBc").end().startBlock();
12679-
b.lineComment("No change in bytecodes.");
12680-
b.startReturn().string("state").end();
12681-
b.end();
12690+
if (model.isBytecodeUpdatable()) {
12691+
b.declaration(arrayOf(type(byte.class)), "oldBc", "this.oldBytecodes");
12692+
b.declaration(arrayOf(type(byte.class)), "newBc", "newBytecode.bytecodes");
12693+
b.startIf().string("oldBc == null || this == newBytecode || this.bytecodes == newBc").end().startBlock();
12694+
b.lineComment("No change in bytecodes.");
12695+
b.startReturn().string("state").end();
12696+
b.end();
1268212697

12683-
b.declaration(type(int.class), "oldBci", decodeBci("state"));
12698+
b.declaration(type(int.class), "oldBci", decodeBci("state"));
1268412699

12685-
b.startDeclaration(type(int.class), "newBci");
12686-
b.startCall("computeNewBci").string("oldBci").string("oldBc").string("newBc");
12687-
if (model.enableTagInstrumentation) {
12688-
b.string("this.getTagNodes()");
12689-
b.string("newBytecode.getTagNodes()");
12690-
}
12691-
b.end(); // call
12700+
b.startDeclaration(type(int.class), "newBci");
12701+
b.startCall("computeNewBci").string("oldBci").string("oldBc").string("newBc");
12702+
if (model.enableTagInstrumentation) {
12703+
b.string("this.getTagNodes()");
12704+
b.string("newBytecode.getTagNodes()");
12705+
}
12706+
b.end(); // call
1269212707

12693-
b.end();
12708+
b.end();
1269412709

12695-
if (model.overridesBytecodeDebugListenerMethod("onBytecodeStackTransition")) {
12696-
b.startStatement();
12697-
b.startCall("getRoot().onBytecodeStackTransition");
12698-
emitParseInstruction(b, "this", "oldBci", readInstruction("oldBc", "oldBci"));
12699-
emitParseInstruction(b, "newBytecode", "newBci", readInstruction("newBc", "newBci"));
12700-
b.end().end();
12701-
}
12710+
if (model.overridesBytecodeDebugListenerMethod("onBytecodeStackTransition")) {
12711+
b.startStatement();
12712+
b.startCall("getRoot().onBytecodeStackTransition");
12713+
emitParseInstruction(b, "this", "oldBci", readInstruction("oldBc", "oldBci"));
12714+
emitParseInstruction(b, "newBytecode", "newBci", readInstruction("newBc", "newBci"));
12715+
b.end().end();
12716+
}
1270212717

12703-
b.startReturn().string(encodeNewBci("newBci", "state")).end();
12718+
b.startReturn().string(encodeNewBci("newBci", "state")).end();
12719+
}
1270412720

12705-
return transitionState;
12721+
return ex;
1270612722
}
1270712723

1270812724
private CodeExecutableElement createTransitionInstrumentationIndex() {
@@ -12740,19 +12756,21 @@ public int compareTo(InstructionGroup o) {
1274012756
}
1274112757
}
1274212758

12743-
CodeExecutableElement invalidate = new CodeExecutableElement(Set.of(PRIVATE, STATIC), type(int.class), "transitionInstrumentationIndex");
12744-
invalidate.addParameter(new CodeVariableElement(arrayOf(type(byte.class)), "oldBc"));
12745-
invalidate.addParameter(new CodeVariableElement(type(int.class), "oldBciBase"));
12746-
invalidate.addParameter(new CodeVariableElement(type(int.class), "oldBciTarget"));
12747-
invalidate.addParameter(new CodeVariableElement(arrayOf(type(byte.class)), "newBc"));
12748-
invalidate.addParameter(new CodeVariableElement(type(int.class), "newBciBase"));
12759+
CodeExecutableElement ex = new CodeExecutableElement(Set.of(PRIVATE, STATIC), type(int.class), "transitionInstrumentationIndex");
12760+
ex.addParameter(new CodeVariableElement(arrayOf(type(byte.class)), "oldBc"));
12761+
ex.addParameter(new CodeVariableElement(type(int.class), "oldBciBase"));
12762+
ex.addParameter(new CodeVariableElement(type(int.class), "oldBciTarget"));
12763+
ex.addParameter(new CodeVariableElement(arrayOf(type(byte.class)), "newBc"));
12764+
ex.addParameter(new CodeVariableElement(type(int.class), "newBciBase"));
1274912765
if (model.enableTagInstrumentation) {
12750-
invalidate.addParameter(new CodeVariableElement(arrayOf(tagNode.asType()), "oldTagNodes"));
12751-
invalidate.addParameter(new CodeVariableElement(arrayOf(tagNode.asType()), "newTagNodes"));
12766+
ex.addParameter(new CodeVariableElement(arrayOf(tagNode.asType()), "oldTagNodes"));
12767+
ex.addParameter(new CodeVariableElement(arrayOf(tagNode.asType()), "newTagNodes"));
1275212768
}
12753-
CodeTreeBuilder b = invalidate.createBuilder();
12769+
CodeTreeBuilder b = ex.createBuilder();
1275412770
b.declaration(type(int.class), "oldBci", "oldBciBase");
1275512771
b.declaration(type(int.class), "newBci", "newBciBase");
12772+
b.lineComment("Find the last instrumentation instruction executed before oldBciTarget.");
12773+
b.lineComment("The new bci should point directly after this reference instruction in the new bytecode.");
1275612774
b.declaration(type(short.class), "searchOp", "-1");
1275712775
if (model.enableTagInstrumentation) {
1275812776
b.declaration(type(int.class), "searchTags", "-1");
@@ -12765,7 +12783,7 @@ public int compareTo(InstructionGroup o) {
1276512783
for (var groupEntry : groupInstructionsSortedBy(InstructionGroup::new)) {
1276612784
InstructionGroup group = groupEntry.getKey();
1276712785
if (!group.instrumentation) {
12768-
// seeing an instrumentation here is a failure
12786+
// only instrumentation instructions should be reached
1276912787
continue;
1277012788
}
1277112789
List<InstructionModel> instructions = groupEntry.getValue();
@@ -12795,7 +12813,8 @@ public int compareTo(InstructionGroup o) {
1279512813
b.end(); // while block
1279612814

1279712815
b.startAssert().string("searchOp != -1").end();
12798-
12816+
b.lineComment("The instruction may occur multiple times between oldBci and oldTargetBci.");
12817+
b.lineComment("Count the number of occurrences so that we identify the correct reference instruction.");
1279912818
b.startAssign("oldBci").string("oldBciBase").end();
1280012819
b.declaration(type(int.class), "opCounter", "0");
1280112820

@@ -12805,7 +12824,7 @@ public int compareTo(InstructionGroup o) {
1280512824
for (var groupEntry : groupInstructionsSortedBy(InstructionGroup::new)) {
1280612825
InstructionGroup group = groupEntry.getKey();
1280712826
if (!group.instrumentation) {
12808-
// seeing an instrumentation here is a failure
12827+
// only instrumentation instructions should be reached
1280912828
continue;
1281012829
}
1281112830
List<InstructionModel> instructions = groupEntry.getValue();
@@ -12839,14 +12858,14 @@ public int compareTo(InstructionGroup o) {
1283912858
b.end(); // while block
1284012859

1284112860
b.startAssert().string("opCounter > 0").end();
12842-
12861+
b.lineComment("Walk the new bytecode to find the location directly after the reference instruction.");
1284312862
b.startWhile().string("opCounter > 0").end().startBlock();
1284412863
b.declaration(type(short.class), "op", readInstruction("newBc", "newBci"));
1284512864
b.startSwitch().string("op").end().startBlock();
1284612865
for (var groupEntry : groupInstructionsSortedBy(InstructionGroup::new)) {
1284712866
InstructionGroup group = groupEntry.getKey();
1284812867
if (!group.instrumentation) {
12849-
// seeing an instrumentation here is a failure
12868+
// only instrumentation instructions should be reached
1285012869
continue;
1285112870
}
1285212871
List<InstructionModel> instructions = groupEntry.getValue();
@@ -12881,7 +12900,7 @@ public int compareTo(InstructionGroup o) {
1288112900

1288212901
b.startReturn().string("newBci").end();
1288312902

12884-
return invalidate;
12903+
return ex;
1288512904
}
1288612905

1288712906
private CodeExecutableElement createComputeNewBci() {

truffle/src/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/bytecode/model/BytecodeDSLModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public TypeMirror getProvidedRootBodyTag() {
271271
}
272272

273273
public boolean isBytecodeUpdatable() {
274-
return !getInstrumentations().isEmpty() || !getProvidedTags().isEmpty();
274+
return !getInstrumentations().isEmpty() || (enableTagInstrumentation && !getProvidedTags().isEmpty());
275275
}
276276

277277
public boolean hasYieldOperation() {

0 commit comments

Comments
 (0)