8339401: Optimize ClassFile load and store instructions
Reviewed-by: liach, redestad
This commit is contained in:
parent
8ea6adc623
commit
b94c3debf5
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user