Skip to content

Commit ff74ca5

Browse files
committed
[GR-71495] Ristretto add basic support for branch profiles.
PullRequest: graal/22771
2 parents 5975f9f + cbff6cd commit ff74ca5

File tree

12 files changed

+641
-96
lines changed

12 files changed

+641
-96
lines changed

substratevm/src/com.oracle.svm.interpreter.metadata/OWNERS.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ files = "*"
33
all = [
44
55
6+
67
]

substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/Bytecodes.java

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@
3131
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.FALL_THROUGH;
3232
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.FIELD_READ;
3333
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.FIELD_WRITE;
34+
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.IF_BRANCH_PROFILED;
3435
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.INVOKE;
3536
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.LOAD;
3637
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.STOP;
3738
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.STORE;
3839
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.TRAP;
40+
import static com.oracle.svm.interpreter.metadata.Bytecodes.Flags.TYPE_PROFILED;
3941

4042
import java.lang.reflect.Field;
4143
import java.lang.reflect.Modifier;
@@ -325,6 +327,14 @@ static class Flags {
325327
* Denotes the 4 INVOKE* instructions.
326328
*/
327329
static final int INVOKE = 0x00001000;
330+
/**
331+
* Denotes all binary branches that are subject to branch profiling.
332+
*/
333+
static final int IF_BRANCH_PROFILED = 0x00002000;
334+
/**
335+
* Denotes all instructions that are subject to type profiling.
336+
*/
337+
static final int TYPE_PROFILED = 0x00004000;
328338
}
329339

330340
// Performs a sanity check that none of the flags overlap.
@@ -423,7 +433,7 @@ static class Flags {
423433
def(LALOAD , "laload" , "b" , 0, TRAP);
424434
def(FALOAD , "faload" , "b" , -1, TRAP);
425435
def(DALOAD , "daload" , "b" , 0, TRAP);
426-
def(AALOAD , "aaload" , "b" , -1, TRAP);
436+
def(AALOAD , "aaload" , "b" , -1, TRAP | TYPE_PROFILED);
427437
def(BALOAD , "baload" , "b" , -1, TRAP);
428438
def(CALOAD , "caload" , "b" , -1, TRAP);
429439
def(SALOAD , "saload" , "b" , -1, TRAP);
@@ -456,7 +466,7 @@ static class Flags {
456466
def(LASTORE , "lastore" , "b" , -4, TRAP);
457467
def(FASTORE , "fastore" , "b" , -3, TRAP);
458468
def(DASTORE , "dastore" , "b" , -4, TRAP);
459-
def(AASTORE , "aastore" , "b" , -3, TRAP);
469+
def(AASTORE , "aastore" , "b" , -3, TRAP | TYPE_PROFILED);
460470
def(BASTORE , "bastore" , "b" , -3, TRAP);
461471
def(CASTORE , "castore" , "b" , -3, TRAP);
462472
def(SASTORE , "sastore" , "b" , -3, TRAP);
@@ -526,20 +536,20 @@ static class Flags {
526536
def(FCMPG , "fcmpg" , "b" , -1);
527537
def(DCMPL , "dcmpl" , "b" , -3);
528538
def(DCMPG , "dcmpg" , "b" , -3);
529-
def(IFEQ , "ifeq" , "boo" , -1, FALL_THROUGH | BRANCH);
530-
def(IFNE , "ifne" , "boo" , -1, FALL_THROUGH | BRANCH);
531-
def(IFLT , "iflt" , "boo" , -1, FALL_THROUGH | BRANCH);
532-
def(IFGE , "ifge" , "boo" , -1, FALL_THROUGH | BRANCH);
533-
def(IFGT , "ifgt" , "boo" , -1, FALL_THROUGH | BRANCH);
534-
def(IFLE , "ifle" , "boo" , -1, FALL_THROUGH | BRANCH);
535-
def(IF_ICMPEQ , "if_icmpeq" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
536-
def(IF_ICMPNE , "if_icmpne" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
537-
def(IF_ICMPLT , "if_icmplt" , "boo" , -2, FALL_THROUGH | BRANCH);
538-
def(IF_ICMPGE , "if_icmpge" , "boo" , -2, FALL_THROUGH | BRANCH);
539-
def(IF_ICMPGT , "if_icmpgt" , "boo" , -2, FALL_THROUGH | BRANCH);
540-
def(IF_ICMPLE , "if_icmple" , "boo" , -2, FALL_THROUGH | BRANCH);
541-
def(IF_ACMPEQ , "if_acmpeq" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
542-
def(IF_ACMPNE , "if_acmpne" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
539+
def(IFEQ , "ifeq" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
540+
def(IFNE , "ifne" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
541+
def(IFLT , "iflt" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
542+
def(IFGE , "ifge" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
543+
def(IFGT , "ifgt" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
544+
def(IFLE , "ifle" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
545+
def(IF_ICMPEQ , "if_icmpeq" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
546+
def(IF_ICMPNE , "if_icmpne" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
547+
def(IF_ICMPLT , "if_icmplt" , "boo" , -2, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
548+
def(IF_ICMPGE , "if_icmpge" , "boo" , -2, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
549+
def(IF_ICMPGT , "if_icmpgt" , "boo" , -2, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
550+
def(IF_ICMPLE , "if_icmple" , "boo" , -2, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
551+
def(IF_ACMPEQ , "if_acmpeq" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
552+
def(IF_ACMPNE , "if_acmpne" , "boo" , -2, COMMUTATIVE | FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
543553
def(GOTO , "goto" , "boo" , 0, STOP | BRANCH);
544554
def(JSR , "jsr" , "boo" , 0, STOP | BRANCH);
545555
def(RET , "ret" , "bi" , 0, STOP);
@@ -555,24 +565,24 @@ static class Flags {
555565
def(PUTSTATIC , "putstatic" , "bjj" , -1, TRAP | FIELD_WRITE);
556566
def(GETFIELD , "getfield" , "bjj" , 0, TRAP | FIELD_READ);
557567
def(PUTFIELD , "putfield" , "bjj" , -2, TRAP | FIELD_WRITE);
558-
def(INVOKEVIRTUAL , "invokevirtual" , "bjj" , -1, TRAP | INVOKE);
559-
def(INVOKESPECIAL , "invokespecial" , "bjj" , -1, TRAP | INVOKE);
560-
def(INVOKESTATIC , "invokestatic" , "bjj" , 0, TRAP | INVOKE);
561-
def(INVOKEINTERFACE , "invokeinterface" , "bjja_", -1, TRAP | INVOKE);
562-
def(INVOKEDYNAMIC , "invokedynamic" , "bjjjj", 0, TRAP | INVOKE);
568+
def(INVOKEVIRTUAL , "invokevirtual" , "bjj" , -1, TRAP | INVOKE | TYPE_PROFILED);
569+
def(INVOKESPECIAL , "invokespecial" , "bjj" , -1, TRAP | INVOKE | TYPE_PROFILED);
570+
def(INVOKESTATIC , "invokestatic" , "bjj" , 0, TRAP | INVOKE | TYPE_PROFILED);
571+
def(INVOKEINTERFACE , "invokeinterface" , "bjja_", -1, TRAP | INVOKE | TYPE_PROFILED);
572+
def(INVOKEDYNAMIC , "invokedynamic" , "bjjjj", 0, TRAP | INVOKE | TYPE_PROFILED);
563573
def(NEW , "new" , "bii" , 1, TRAP);
564574
def(NEWARRAY , "newarray" , "bc" , 0, TRAP);
565575
def(ANEWARRAY , "anewarray" , "bii" , 0, TRAP);
566576
def(ARRAYLENGTH , "arraylength" , "b" , 0, TRAP);
567577
def(ATHROW , "athrow" , "b" , -1, TRAP | STOP);
568-
def(CHECKCAST , "checkcast" , "bii" , 0, TRAP);
569-
def(INSTANCEOF , "instanceof" , "bii" , 0, TRAP);
578+
def(CHECKCAST , "checkcast" , "bii" , 0, TRAP | TYPE_PROFILED);
579+
def(INSTANCEOF , "instanceof" , "bii" , 0, TRAP | TYPE_PROFILED);
570580
def(MONITORENTER , "monitorenter" , "b" , -1, TRAP);
571581
def(MONITOREXIT , "monitorexit" , "b" , -1, TRAP);
572582
def(WIDE , "wide" , "" , 0);
573583
def(MULTIANEWARRAY , "multianewarray" , "biic" , 1, TRAP);
574-
def(IFNULL , "ifnull" , "boo" , -1, FALL_THROUGH | BRANCH);
575-
def(IFNONNULL , "ifnonnull" , "boo" , -1, FALL_THROUGH | BRANCH);
584+
def(IFNULL , "ifnull" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
585+
def(IFNONNULL , "ifnonnull" , "boo" , -1, FALL_THROUGH | BRANCH | IF_BRANCH_PROFILED);
576586
def(GOTO_W , "goto_w" , "boooo", 0, STOP | BRANCH);
577587
def(JSR_W , "jsr_w" , "boooo", 0, STOP | BRANCH);
578588
def(BREAKPOINT , "breakpoint" , "b" , 0, TRAP);
@@ -648,6 +658,31 @@ public static boolean isBranch(int opcode) {
648658
return (flagsArray[opcode & 0xff] & BRANCH) != 0;
649659
}
650660

661+
/**
662+
* Determines if a given opcode is an instruction that is subject to binary branch profiling in
663+
* the interpreter. Binary branches are instructions that have 2 successors - the taken and not
664+
* taken successor.
665+
*
666+
* Note that {@link #GOTO} and {@link #JSR} are not considered a profiled if branch
667+
*
668+
* @param opcode an opcode to test
669+
* @return {@code true} iff {@code opcode} is a binary branch instruction that is profiled
670+
*/
671+
public static boolean isProfiledIfBranch(int opcode) {
672+
return (flagsArray[opcode & 0xff] & IF_BRANCH_PROFILED) != 0;
673+
}
674+
675+
/**
676+
* Determines if a given opcode is an instruction that is subject to type profiling. This covers
677+
* all instructions that deal with objects of a dynamic type.
678+
*
679+
* @param opcode an opcode to test
680+
* @return {@code true} iff {@code opcode} is a type profiled branch instruction
681+
*/
682+
public static boolean isTypeProfiled(int opcode) {
683+
return (flagsArray[opcode & 0xff] & TYPE_PROFILED) != 0;
684+
}
685+
651686
/**
652687
* Determines if a given opcode denotes a conditional branch.
653688
*

0 commit comments

Comments
 (0)