Skip to content

Commit 6985f81

Browse files
committed
Add Instruction#isInstrumentation method
1 parent 2dbbcbb commit 6985f81

File tree

6 files changed

+99
-15
lines changed

6 files changed

+99
-15
lines changed

truffle/mx.truffle/suite.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,6 @@
16981698
"com.oracle.truffle.api.dsl",
16991699
"com.oracle.truffle.api.bytecode",
17001700
"com.oracle.truffle.api.bytecode.debug",
1701-
"com.oracle.truffle.api.bytecode.introspection",
17021701
"com.oracle.truffle.api.bytecode.serialization",
17031702
"com.oracle.truffle.api.bytecode.tracing",
17041703
"com.oracle.truffle.api.profiles",

truffle/src/com.oracle.truffle.api.bytecode.test/src/com/oracle/truffle/api/bytecode/test/TagTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import com.oracle.truffle.api.bytecode.EpilogExceptional;
7272
import com.oracle.truffle.api.bytecode.EpilogReturn;
7373
import com.oracle.truffle.api.bytecode.GenerateBytecode;
74+
import com.oracle.truffle.api.bytecode.Instruction;
7475
import com.oracle.truffle.api.bytecode.Operation;
7576
import com.oracle.truffle.api.bytecode.Prolog;
7677
import com.oracle.truffle.api.bytecode.TagTree;
@@ -243,6 +244,11 @@ public void testStatementsCached() {
243244
"load.local",
244245
"tag.leave",
245246
"return");
247+
boolean[] isInstrumentation = new boolean[] {true, false, false, true, true, false, true, false};
248+
List<Instruction> instructions = node.getBytecodeNode().getInstructionsAsList();
249+
for (int i = 0; i < instructions.size(); i++) {
250+
assertEquals(isInstrumentation[i], instructions.get(i).isInstrumentation());
251+
}
246252

247253
assertEquals(42, node.getCallTarget().call());
248254

@@ -255,6 +261,10 @@ public void testStatementsCached() {
255261
"load.local$Int$unboxed",
256262
"tag.leave$Int",
257263
"return");
264+
instructions = node.getBytecodeNode().getInstructionsAsList();
265+
for (int i = 0; i < instructions.size(); i++) {
266+
assertEquals(isInstrumentation[i], instructions.get(i).isInstrumentation());
267+
}
258268

259269
QuickeningCounts counts = assertQuickenings(node, 8, 4);
260270

truffle/src/com.oracle.truffle.api.bytecode.test/src/com/oracle/truffle/api/bytecode/test/basic_interpreter/BasicInterpreterTest.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,18 @@
7272
public class BasicInterpreterTest extends AbstractBasicInterpreterTest {
7373
// @formatter:off
7474

75-
private static void assertInstructionEquals(Instruction instr, int bci, String name) {
76-
assertEquals(bci, instr.getBytecodeIndex());
75+
private static void assertInstructionEquals(Instruction instr, Integer bci, String name) {
76+
assertInstructionEquals(instr, bci, name, null);
77+
}
78+
79+
private static void assertInstructionEquals(Instruction instr, Integer bci, String name, Boolean instrumentation) {
80+
if (bci != null) {
81+
assertEquals(bci.intValue(), instr.getBytecodeIndex());
82+
}
7783
assertEquals(name, instr.getName());
84+
if (instrumentation != null) {
85+
assertEquals(instrumentation.booleanValue(), instr.isInstrumentation());
86+
}
7887
}
7988

8089
@Test
@@ -1133,6 +1142,43 @@ public void testIntrospectionDataSourceInformation() {
11331142
assertEquals(instructions.get(3).getBytecodeIndex() + 1, s4.getEndBci());
11341143
}
11351144

1145+
@Test
1146+
public void testIntrospectionDataInstrumentationInstructions() {
1147+
BasicInterpreter node = parseNode("introspectionDataInstrumentationInstructions", b -> {
1148+
b.beginRoot(LANGUAGE);
1149+
1150+
b.beginReturn();
1151+
b.beginTag(ExpressionTag.class);
1152+
b.beginAddOperation();
1153+
b.emitLoadArgument(0);
1154+
b.beginIncrementValue();
1155+
b.emitLoadArgument(1);
1156+
b.endIncrementValue();
1157+
b.endAddOperation();
1158+
b.endTag(ExpressionTag.class);
1159+
b.endReturn();
1160+
1161+
b.endRoot();
1162+
});
1163+
1164+
List<Instruction> instructions = node.getBytecodeNode().getInstructionsAsList();
1165+
assertEquals(4, instructions.size());
1166+
assertInstructionEquals(instructions.get(0), null, "load.argument", false);
1167+
assertInstructionEquals(instructions.get(1), null, "load.argument", false);
1168+
assertInstructionEquals(instructions.get(2), null, "c.AddOperation", false);
1169+
assertInstructionEquals(instructions.get(3), null, "return", false);
1170+
1171+
node.getRootNodes().update(createBytecodeConfigBuilder().addInstrumentation(BasicInterpreter.IncrementValue.class).build());
1172+
1173+
instructions = node.getBytecodeNode().getInstructionsAsList();
1174+
assertEquals(5, instructions.size());
1175+
assertInstructionEquals(instructions.get(0), null, "load.argument", false);
1176+
assertInstructionEquals(instructions.get(1), null, "load.argument", false);
1177+
assertInstructionEquals(instructions.get(2), null, "c.IncrementValue", true);
1178+
assertInstructionEquals(instructions.get(3), null, "c.AddOperation", false);
1179+
assertInstructionEquals(instructions.get(4), null, "return", false);
1180+
}
1181+
11361182
@Test
11371183
public void testTags() {
11381184
RootCallTarget root = parse("tags", b -> {

truffle/src/com.oracle.truffle.api.bytecode/src/com/oracle/truffle/api/bytecode/Instruction.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public final BytecodeLocation getLocation() {
7373

7474
public abstract List<Argument> getArguments();
7575

76+
public abstract boolean isInstrumentation();
77+
7678
protected abstract Instruction next();
7779

7880
@Override
@@ -91,7 +93,7 @@ private String toString(String prefix) {
9193
return sb.toString();
9294
}
9395

94-
public static abstract class Argument {
96+
public abstract static class Argument {
9597

9698
protected Argument(Object token) {
9799
BytecodeRootNodes.checkToken(token);

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

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6388,6 +6388,7 @@ private void create() {
63886388
type.add(createGetLength());
63896389
type.add(createGetArguments());
63906390
type.add(createGetName());
6391+
type.add(createIsInstrumentation());
63916392
type.add(createNext());
63926393

63936394
Set<String> generated = new HashSet<>();
@@ -6446,6 +6447,33 @@ private CodeExecutableElement createGetName() {
64466447
return ex;
64476448
}
64486449

6450+
private CodeExecutableElement createIsInstrumentation() {
6451+
CodeExecutableElement ex = GeneratorUtils.overrideImplement(types.Instruction, "isInstrumentation");
6452+
CodeTreeBuilder b = ex.createBuilder();
6453+
6454+
Map<Boolean, List<InstructionModel>> grouped = groupInstructionsByInstrumentation(model.getInstructions());
6455+
6456+
if (!grouped.containsKey(true)) {
6457+
// Simplification: no instruction is an instrumentation instruction.
6458+
b.startReturn().string("false").end();
6459+
return ex;
6460+
}
6461+
6462+
b.startSwitch().string("opcode").end().startBlock();
6463+
for (var entry : grouped.entrySet()) {
6464+
for (InstructionModel instruction : entry.getValue()) {
6465+
b.startCase().tree(createInstructionConstant(instruction)).end();
6466+
}
6467+
b.startCaseBlock();
6468+
b.startReturn().string(Boolean.toString(entry.getKey())).end();
6469+
b.end();
6470+
}
6471+
6472+
b.end();
6473+
b.tree(GeneratorUtils.createShouldNotReachHere("Invalid opcode"));
6474+
return ex;
6475+
}
6476+
64496477
private CodeExecutableElement createGetLength() {
64506478
CodeExecutableElement ex = new CodeExecutableElement(Set.of(FINAL), type(int.class), "getLength");
64516479
CodeTreeBuilder b = ex.createBuilder();
@@ -6499,6 +6527,10 @@ private CodeExecutableElement createGetArguments() {
64996527
return ex;
65006528
}
65016529

6530+
private Map<Boolean, List<InstructionModel>> groupInstructionsByInstrumentation(Collection<InstructionModel> models) {
6531+
return models.stream().collect(Collectors.groupingBy(InstructionModel::isInstrumentation));
6532+
}
6533+
65026534
private Collection<List<InstructionModel>> groupInstructionsByLength(Collection<InstructionModel> models) {
65036535
return models.stream().sorted(Comparator.comparingInt((i) -> i.getInstructionLength())).collect(Collectors.groupingBy((m) -> m.getInstructionLength())).values();
65046536
}
@@ -7699,12 +7731,7 @@ private CodeExecutableElement createFromStableBytecodeIndex() {
76997731

77007732
private record TranslationInstructionGroup(int instructionLength, boolean instrumentation) implements Comparable<TranslationInstructionGroup> {
77017733
TranslationInstructionGroup(InstructionModel instr) {
7702-
this(instr.getInstructionLength(), isInstrumentationInstruction(instr));
7703-
}
7704-
7705-
private static boolean isInstrumentationInstruction(InstructionModel instr) {
7706-
return instr.kind == InstructionKind.TAG_ENTER || instr.kind == InstructionKind.TAG_LEAVE || instr.kind == InstructionKind.TAG_LEAVE_VOID ||
7707-
instr.operation != null && instr.operation.kind == OperationKind.CUSTOM_INSTRUMENTATION;
7734+
this(instr.getInstructionLength(), instr.isInstrumentation());
77087735
}
77097736

77107737
// needs a deterministic ordering after grouping
@@ -11371,10 +11398,6 @@ private static String readConst(String index) {
1137111398
return String.format("ACCESS.objectArrayRead(constants, %s)", index);
1137211399
}
1137311400

11374-
private static String readBranchProfile(String index) {
11375-
return String.format("branchProfiles == null ? 0 : ACCESS.intArrayRead(branchProfiles, %s)", index);
11376-
}
11377-
1137811401
private static CodeTree readTagNode(TypeMirror expectedType, CodeTree index) {
1137911402
CodeTreeBuilder b = CodeTreeBuilder.createBuilder();
1138011403
b.startCall("ACCESS.cast");

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import javax.lang.model.type.TypeMirror;
4848

4949
import com.oracle.truffle.dsl.processor.ProcessorContext;
50+
import com.oracle.truffle.dsl.processor.bytecode.model.OperationModel.OperationKind;
5051
import com.oracle.truffle.dsl.processor.java.ElementUtils;
5152
import com.oracle.truffle.dsl.processor.java.model.CodeTypeElement;
5253
import com.oracle.truffle.dsl.processor.model.NodeData;
@@ -343,11 +344,14 @@ public void pp(PrettyPrinter printer) {
343344
}
344345
}
345346

346-
public boolean isInstrumentationOnly() {
347+
public boolean isInstrumentation() {
347348
switch (kind) {
348349
case TAG_ENTER:
349350
case TAG_LEAVE:
351+
case TAG_LEAVE_VOID:
350352
return true;
353+
case CUSTOM:
354+
return operation.kind == OperationKind.CUSTOM_INSTRUMENTATION;
351355
default:
352356
return false;
353357
}

0 commit comments

Comments
 (0)