Skip to content

Commit

Permalink
Use tableswitch to improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
mmhelloworld committed Dec 11, 2024
1 parent f31c027 commit 12724bd
Show file tree
Hide file tree
Showing 4 changed files with 673 additions and 674 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ public final class Assembler {
public static final int CLOSE_CURLY_BRACE = 125;
public static final int ICONST_MAX = 5;
public static final int BUFFER_SIZE = 1024;
private static final boolean SHOULD_DEBUG;
public static final int JAVA_VERSION = V1_8;
private static final boolean SHOULD_DEBUG;

static {
String shouldDebug = System.getProperty("IDRIS_JVM_DEBUG", System.getenv("IDRIS_JVM_DEBUG"));
Expand Down Expand Up @@ -766,7 +766,7 @@ public String getMethodName() {
}

public void gotoLabel(String labelName) {
Label label = (Label) env.get(labelName);
Label label = getLabel(labelName);
if (label == null) {
throw new NullPointerException(format("Label %s cannot be null. Current method: %s, Environment: %s",
labelName, methodName, env));
Expand Down Expand Up @@ -843,63 +843,63 @@ public void idiv() {
}

public void ifeq(String label) {
mv.visitJumpInsn(IFEQ, (Label) env.get(label));
mv.visitJumpInsn(IFEQ, getLabel(label));
}

public void ifge(String label) {
mv.visitJumpInsn(IFGE, (Label) env.get(label));
mv.visitJumpInsn(IFGE, getLabel(label));
}

public void ifgt(String label) {
mv.visitJumpInsn(IFGT, (Label) env.get(label));
mv.visitJumpInsn(IFGT, getLabel(label));
}

public void ificmpge(String label) {
mv.visitJumpInsn(IF_ICMPGE, (Label) env.get(label));
mv.visitJumpInsn(IF_ICMPGE, getLabel(label));
}

public void ificmpgt(String label) {
mv.visitJumpInsn(IF_ICMPGT, (Label) env.get(label));
mv.visitJumpInsn(IF_ICMPGT, getLabel(label));
}

public void ificmple(String label) {
mv.visitJumpInsn(IF_ICMPLE, (Label) env.get(label));
mv.visitJumpInsn(IF_ICMPLE, getLabel(label));
}

public void ificmplt(String label) {
mv.visitJumpInsn(IF_ICMPLT, (Label) env.get(label));
mv.visitJumpInsn(IF_ICMPLT, getLabel(label));
}

public void ifacmpne(String label) {
mv.visitJumpInsn(IF_ACMPNE, (Label) env.get(label));
mv.visitJumpInsn(IF_ACMPNE, getLabel(label));
}

public void ificmpne(String label) {
mv.visitJumpInsn(IF_ICMPNE, (Label) env.get(label));
mv.visitJumpInsn(IF_ICMPNE, getLabel(label));
}

public void ificmpeq(String label) {
mv.visitJumpInsn(IF_ICMPEQ, (Label) env.get(label));
mv.visitJumpInsn(IF_ICMPEQ, getLabel(label));
}

public void ifle(String label) {
mv.visitJumpInsn(IFLE, (Label) env.get(label));
mv.visitJumpInsn(IFLE, getLabel(label));
}

public void iflt(String label) {
mv.visitJumpInsn(IFLT, (Label) env.get(label));
mv.visitJumpInsn(IFLT, getLabel(label));
}

public void ifne(String label) {
mv.visitJumpInsn(IFNE, (Label) env.get(label));
mv.visitJumpInsn(IFNE, getLabel(label));
}

public void ifnonnull(String label) {
mv.visitJumpInsn(IFNONNULL, (Label) env.get(label));
mv.visitJumpInsn(IFNONNULL, getLabel(label));
}

public void ifnull(String label) {
mv.visitJumpInsn(IFNULL, (Label) env.get(label));
mv.visitJumpInsn(IFNULL, getLabel(label));
}

public void iload(int n) {
Expand Down Expand Up @@ -1086,19 +1086,23 @@ public void lneg() {
mv.visitInsn(LNEG);
}

public void lookupSwitch(String defaultLabel, Object caseLabels, Object cases) {
lookupSwitch(defaultLabel, (List) caseLabels, (List) cases);
public void lookupSwitch(String defaultLabelName, List<String> caseLabelNames, List<Integer> cases) {
int[] casesArr = cases.stream().mapToInt(n -> n).toArray();
mv.visitLookupSwitchInsn(getLabel(defaultLabelName), casesArr, getLabels(caseLabelNames));
}

public void lookupSwitch(String defaultLabel, List<String> caseLabels, List<Integer> cases) {
int[] casesArr = cases.stream().mapToInt(n -> n).toArray();
mv.visitLookupSwitchInsn(
(Label) env.get(defaultLabel),
casesArr,
caseLabels.stream()
.map(s -> (Label) env.get(s))
.toArray(Label[]::new)
);
private Label[] getLabels(List<String> caseLabelNames) {
return caseLabelNames.stream()
.map(this::getLabel)
.toArray(Label[]::new);
}

private Label getLabel(String name) {
return (Label) env.get(name);
}

public void tableSwitch(int min, int max, String defaultLabelName, List<String> caseLabelNames) {
mv.visitTableSwitchInsn(min, max, getLabel(defaultLabelName), getLabels(caseLabelNames));
}

public void lshl() {
Expand Down Expand Up @@ -1188,16 +1192,16 @@ public void sourceInfo(String sourceFileName) {
}

public void lineNumber(int lineNumber, String label) {
mv.visitLineNumber(lineNumber, (Label) env.get(label));
mv.visitLineNumber(lineNumber, getLabel(label));
}

public void localVariable(String name, String typeDescriptor, String signature, String lineNumberStartLabel,
String lineNumberEndLabel, int index) {
Label start = (Label) env.get(lineNumberStartLabel);
Label start = getLabel(lineNumberStartLabel);
requireNonNull(start,
format("Line number start label '%s' for variable %s at index %d must not be null for method %s/%s",
lineNumberStartLabel, name, index, className, methodName));
Label end = (Label) env.get(lineNumberEndLabel);
Label end = getLabel(lineNumberEndLabel);
requireNonNull(end,
format("Line number end label '%s' for variable %s at index %d must not be null for method %s/%s",
lineNumberEndLabel, name, index, className, methodName));
Expand Down
3 changes: 3 additions & 0 deletions libs/base/Java/Lang.idr
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ namespace Long
export
valueOf : Int64 -> Long

%foreign "jvm:hashCode,java/lang/Long"
hashCode : Int64 -> Int

namespace Array
%inline
public export
Expand Down
22 changes: 17 additions & 5 deletions src/Compiler/Jvm/Asm.idr
Original file line number Diff line number Diff line change
Expand Up @@ -1175,9 +1175,12 @@ asmFrame : Assembler -> Int -> Int -> (signatures: JList String) -> Int -> (sign
asmLocalVariable : Assembler -> (name: String) -> (descriptor: String) -> (signature: String) -> (startLabel: String)
-> (endLabel: String) -> (index: Int) -> PrimIO ()

%foreign "jvm:.lookupSwitch"
%foreign "jvm:.lookupSwitch(io/github/mmhelloworld/idrisjvm/assembler/Assembler String java/util/List java/util/List void),io/github/mmhelloworld/idrisjvm/assembler/Assembler"
asmLookupSwitch : Assembler -> (defaultLabel: String) -> (labels: JList String) -> (cases: JList Int) -> PrimIO ()

%foreign "jvm:.tableSwitch(io/github/mmhelloworld/idrisjvm/assembler/Assembler int int String java/util/List void),io/github/mmhelloworld/idrisjvm/assembler/Assembler"
asmTableSwitch : Assembler -> (min: Int) -> (max: Int) -> (defaultLabel: String) -> (labels: JList String) -> PrimIO ()

%foreign "jvm:.maxStackAndLocal"
asmMaxStackAndLocal : Assembler -> Int -> Int -> PrimIO ()

Expand Down Expand Up @@ -1651,7 +1654,7 @@ parameters {auto state: Ref AsmState AsmState}

public export
%inline
lookupSwitch : (defaultLabel: String) -> (labels: List String) -> (cases: List Int) -> Core ()
lookupSwitch : (defaultLabel: String) -> (labels: List1 String) -> (cases: List1 Int) -> Core ()

public export
%inline
Expand Down Expand Up @@ -1741,6 +1744,10 @@ parameters {auto state: Ref AsmState AsmState}
%inline
setState : AsmState -> Core ()

public export
%inline
tableSwitch : (min: Int) -> (max: Int) -> (defaultLabel: String) -> (labels: List1 String) -> Core ()

aaload = do
state <- getState
coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.aaload" [assembler state]
Expand Down Expand Up @@ -2164,12 +2171,12 @@ parameters {auto state: Ref AsmState AsmState}
lneg = do
state <- getState
coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.lneg" [assembler state]

lookupSwitch defaultLabel labels cases = do
state <- get AsmState
coreLift $ do
let jcases = integerValueOf <$> cases
coreLift $
primIO $ asmLookupSwitch
(assembler state) defaultLabel (the (JList String) $ believe_me labels) (the (JList Int) $ believe_me jcases)
(assembler state) defaultLabel (believe_me $ forget labels) (believe_me $ forget cases)

localVariable name descriptor signature startLabel endLabel index = do
state <- get AsmState
Expand Down Expand Up @@ -2235,6 +2242,11 @@ parameters {auto state: Ref AsmState AsmState}
state <- getState
coreLift $ jvmInstance () "io/github/mmhelloworld/idrisjvm/assembler/Assembler.sourceInfo" [assembler state, sourceFileName]

tableSwitch min max defaultLabel labels = do
state <- get AsmState
coreLift $ do
primIO $ asmTableSwitch (assembler state) min max defaultLabel (believe_me $ forget labels)

getState = get AsmState
setState newState = put AsmState newState

Expand Down
Loading

0 comments on commit 12724bd

Please sign in to comment.