8339401: Optimize ClassFile load and store instructions

Reviewed-by: liach, redestad
This commit is contained in:
Shaojin Wen 2024-09-03 12:05:02 +00:00 committed by Claes Redestad
parent 8ea6adc623
commit b94c3debf5
2 changed files with 178 additions and 72 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -56,83 +57,125 @@ public class BytecodeHelpers {
public static Opcode loadOpcode(TypeKind tk, int slot) {
return switch (tk) {
case INT, SHORT, BYTE, CHAR, BOOLEAN -> switch (slot) {
case 0 -> Opcode.ILOAD_0;
case 1 -> Opcode.ILOAD_1;
case 2 -> Opcode.ILOAD_2;
case 3 -> Opcode.ILOAD_3;
default -> (slot < 256) ? Opcode.ILOAD : Opcode.ILOAD_W;
};
case LONG -> switch (slot) {
case 0 -> Opcode.LLOAD_0;
case 1 -> Opcode.LLOAD_1;
case 2 -> Opcode.LLOAD_2;
case 3 -> Opcode.LLOAD_3;
default -> (slot < 256) ? Opcode.LLOAD : Opcode.LLOAD_W;
};
case DOUBLE -> switch (slot) {
case 0 -> Opcode.DLOAD_0;
case 1 -> Opcode.DLOAD_1;
case 2 -> Opcode.DLOAD_2;
case 3 -> Opcode.DLOAD_3;
default -> (slot < 256) ? Opcode.DLOAD : Opcode.DLOAD_W;
};
case FLOAT -> switch (slot) {
case 0 -> Opcode.FLOAD_0;
case 1 -> Opcode.FLOAD_1;
case 2 -> Opcode.FLOAD_2;
case 3 -> Opcode.FLOAD_3;
default -> (slot < 256) ? Opcode.FLOAD : Opcode.FLOAD_W;
};
case REFERENCE -> switch (slot) {
case 0 -> Opcode.ALOAD_0;
case 1 -> Opcode.ALOAD_1;
case 2 -> Opcode.ALOAD_2;
case 3 -> Opcode.ALOAD_3;
default -> (slot < 256) ? Opcode.ALOAD : Opcode.ALOAD_W;
};
case VOID -> throw new IllegalArgumentException("void");
case INT, SHORT, BYTE, CHAR, BOOLEAN
-> iload(slot);
case LONG -> lload(slot);
case DOUBLE -> dload(slot);
case FLOAT -> fload(slot);
case REFERENCE -> aload(slot);
case VOID -> throw new IllegalArgumentException("void");
};
}
public static Opcode aload(int slot) {
return switch (slot) {
case 0 -> Opcode.ALOAD_0;
case 1 -> Opcode.ALOAD_1;
case 2 -> Opcode.ALOAD_2;
case 3 -> Opcode.ALOAD_3;
default -> (slot < 256) ? Opcode.ALOAD : Opcode.ALOAD_W;
};
}
public static Opcode fload(int slot) {
return switch (slot) {
case 0 -> Opcode.FLOAD_0;
case 1 -> Opcode.FLOAD_1;
case 2 -> Opcode.FLOAD_2;
case 3 -> Opcode.FLOAD_3;
default -> (slot < 256) ? Opcode.FLOAD : Opcode.FLOAD_W;
};
}
public static Opcode dload(int slot) {
return switch (slot) {
case 0 -> Opcode.DLOAD_0;
case 1 -> Opcode.DLOAD_1;
case 2 -> Opcode.DLOAD_2;
case 3 -> Opcode.DLOAD_3;
default -> (slot < 256) ? Opcode.DLOAD : Opcode.DLOAD_W;
};
}
public static Opcode lload(int slot) {
return switch (slot) {
case 0 -> Opcode.LLOAD_0;
case 1 -> Opcode.LLOAD_1;
case 2 -> Opcode.LLOAD_2;
case 3 -> Opcode.LLOAD_3;
default -> (slot < 256) ? Opcode.LLOAD : Opcode.LLOAD_W;
};
}
public static Opcode iload(int slot) {
return switch (slot) {
case 0 -> Opcode.ILOAD_0;
case 1 -> Opcode.ILOAD_1;
case 2 -> Opcode.ILOAD_2;
case 3 -> Opcode.ILOAD_3;
default -> (slot < 256) ? Opcode.ILOAD : Opcode.ILOAD_W;
};
}
public static Opcode storeOpcode(TypeKind tk, int slot) {
return switch (tk) {
case INT, SHORT, BYTE, CHAR, BOOLEAN -> switch (slot) {
case 0 -> Opcode.ISTORE_0;
case 1 -> Opcode.ISTORE_1;
case 2 -> Opcode.ISTORE_2;
case 3 -> Opcode.ISTORE_3;
default -> (slot < 256) ? Opcode.ISTORE : Opcode.ISTORE_W;
};
case LONG -> switch (slot) {
case 0 -> Opcode.LSTORE_0;
case 1 -> Opcode.LSTORE_1;
case 2 -> Opcode.LSTORE_2;
case 3 -> Opcode.LSTORE_3;
default -> (slot < 256) ? Opcode.LSTORE : Opcode.LSTORE_W;
};
case DOUBLE -> switch (slot) {
case 0 -> Opcode.DSTORE_0;
case 1 -> Opcode.DSTORE_1;
case 2 -> Opcode.DSTORE_2;
case 3 -> Opcode.DSTORE_3;
default -> (slot < 256) ? Opcode.DSTORE : Opcode.DSTORE_W;
};
case FLOAT -> switch (slot) {
case 0 -> Opcode.FSTORE_0;
case 1 -> Opcode.FSTORE_1;
case 2 -> Opcode.FSTORE_2;
case 3 -> Opcode.FSTORE_3;
default -> (slot < 256) ? Opcode.FSTORE : Opcode.FSTORE_W;
};
case REFERENCE -> switch (slot) {
case 0 -> Opcode.ASTORE_0;
case 1 -> Opcode.ASTORE_1;
case 2 -> Opcode.ASTORE_2;
case 3 -> Opcode.ASTORE_3;
default -> (slot < 256) ? Opcode.ASTORE : Opcode.ASTORE_W;
};
case VOID -> throw new IllegalArgumentException("void");
case INT, SHORT, BYTE, CHAR, BOOLEAN
-> istore(slot);
case LONG -> lstore(slot);
case DOUBLE -> dstore(slot);
case FLOAT -> fstore(slot);
case REFERENCE -> astore(slot);
case VOID -> throw new IllegalArgumentException("void");
};
}
public static Opcode astore(int slot) {
return switch (slot) {
case 0 -> Opcode.ASTORE_0;
case 1 -> Opcode.ASTORE_1;
case 2 -> Opcode.ASTORE_2;
case 3 -> Opcode.ASTORE_3;
default -> (slot < 256) ? Opcode.ASTORE : Opcode.ASTORE_W;
};
}
public static Opcode fstore(int slot) {
return switch (slot) {
case 0 -> Opcode.FSTORE_0;
case 1 -> Opcode.FSTORE_1;
case 2 -> Opcode.FSTORE_2;
case 3 -> Opcode.FSTORE_3;
default -> (slot < 256) ? Opcode.FSTORE : Opcode.FSTORE_W;
};
}
public static Opcode dstore(int slot) {
return switch (slot) {
case 0 -> Opcode.DSTORE_0;
case 1 -> Opcode.DSTORE_1;
case 2 -> Opcode.DSTORE_2;
case 3 -> Opcode.DSTORE_3;
default -> (slot < 256) ? Opcode.DSTORE : Opcode.DSTORE_W;
};
}
public static Opcode lstore(int slot) {
return switch (slot) {
case 0 -> Opcode.LSTORE_0;
case 1 -> Opcode.LSTORE_1;
case 2 -> Opcode.LSTORE_2;
case 3 -> Opcode.LSTORE_3;
default -> (slot < 256) ? Opcode.LSTORE : Opcode.LSTORE_W;
};
}
public static Opcode istore(int slot) {
return switch (slot) {
case 0 -> Opcode.ISTORE_0;
case 1 -> Opcode.ISTORE_1;
case 2 -> Opcode.ISTORE_2;
case 3 -> Opcode.ISTORE_3;
default -> (slot < 256) ? Opcode.ISTORE : Opcode.ISTORE_W;
};
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -63,6 +64,8 @@ import java.util.function.Function;
import static java.lang.classfile.Opcode.*;
import static jdk.internal.classfile.impl.BytecodeHelpers.*;
public final class DirectCodeBuilder
extends AbstractDirectBuilder<CodeModel>
implements TerminalCodeBuilder {
@ -855,6 +858,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder aload(int slot) {
writeLocalVar(BytecodeHelpers.aload(slot), slot);
return this;
}
@Override
public CodeBuilder anewarray(ClassEntry entry) {
writeNewReferenceArray(entry);
@ -867,6 +876,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder astore(int slot) {
writeLocalVar(BytecodeHelpers.astore(slot), slot);
return this;
}
@Override
public CodeBuilder athrow() {
writeBytecode(ATHROW);
@ -940,6 +955,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder dload(int slot) {
writeLocalVar(BytecodeHelpers.dload(slot), slot);
return this;
}
@Override
public CodeBuilder dmul() {
writeBytecode(DMUL);
@ -958,6 +979,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder dstore(int slot) {
writeLocalVar(BytecodeHelpers.dstore(slot), slot);
return this;
}
@Override
public CodeBuilder dsub() {
writeBytecode(DSUB);
@ -1060,6 +1087,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder fload(int slot) {
writeLocalVar(BytecodeHelpers.fload(slot), slot);
return this;
}
@Override
public CodeBuilder fmul() {
writeBytecode(FMUL);
@ -1078,6 +1111,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder fstore(int slot) {
writeLocalVar(BytecodeHelpers.fstore(slot), slot);
return this;
}
@Override
public CodeBuilder fsub() {
writeBytecode(FSUB);
@ -1186,6 +1225,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder iload(int slot) {
writeLocalVar(BytecodeHelpers.iload(slot), slot);
return this;
}
@Override
public CodeBuilder imul() {
writeBytecode(IMUL);
@ -1270,6 +1315,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder istore(int slot) {
writeLocalVar(BytecodeHelpers.istore(slot), slot);
return this;
}
@Override
public CodeBuilder isub() {
writeBytecode(ISUB);
@ -1354,6 +1405,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder lload(int slot) {
writeLocalVar(BytecodeHelpers.lload(slot), slot);
return this;
}
@Override
public CodeBuilder lmul() {
writeBytecode(LMUL);
@ -1390,6 +1447,12 @@ public final class DirectCodeBuilder
return this;
}
@Override
public CodeBuilder lstore(int slot) {
writeLocalVar(BytecodeHelpers.lstore(slot), slot);
return this;
}
@Override
public CodeBuilder lsub() {
writeBytecode(LSUB);