Skip to content

Commit 8977568

Browse files
committed
Added performance improvements
1 parent 6b9c517 commit 8977568

2 files changed

Lines changed: 33 additions & 6 deletions

File tree

vm/ByteCodeTranslator/src/com/codename1/tools/translator/JavascriptMethodGenerator.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,18 @@ private static boolean appendStraightLineMethodBody(StringBuilder out, ByteCodeC
284284
for (int i = 0; i < arguments.size(); i++) {
285285
body.append(" let l").append(localIndex).append(" = __cn1Arg").append(i + 1).append(";\n");
286286
ctx.localsInitialized[localIndex] = true;
287+
ctx.localsUsed[localIndex] = true;
287288
localIndex++;
288289
if (arguments.get(i).isDoubleOrLong()) {
289290
localIndex++;
290291
}
291292
}
292293
for (int i = 0; i < method.getMaxLocals(); i++) {
293-
if (!ctx.localsInitialized[i]) {
294+
if (!ctx.localsInitialized[i] && ctx.localsUsed[i]) {
294295
body.append(" let l").append(i).append(" = null;\n");
295296
}
296297
}
297-
for (int i = 0; i < method.getMaxStack(); i++) {
298+
for (int i = 0; i < ctx.getMaxObservedStack(); i++) {
298299
body.append(" let s").append(i).append(" = null;\n");
299300
}
300301
if (method.isSynchronizedMethod()) {
@@ -358,6 +359,7 @@ private static boolean appendStraightLineInstruction(StringBuilder out, Bytecode
358359
}
359360
if (instruction instanceof IInc) {
360361
IInc iinc = (IInc) instruction;
362+
ctx.localsUsed[iinc.getVar()] = true;
361363
out.append(" l").append(iinc.getVar()).append(" = (l").append(iinc.getVar()).append(" || 0) + ")
362364
.append(iinc.getAmount()).append(";\n");
363365
return true;
@@ -600,8 +602,14 @@ private static boolean appendStraightLineBasicInstruction(StringBuilder out, Byt
600602
case Opcodes.SALOAD: {
601603
String idx = ctx.pop();
602604
String arr = ctx.pop();
603-
String valueExpr = "(function(__arr,__idx){ if (!__arr.__array) throw new Error(\"Array expected\"); if (__idx < 0 || __idx >= __arr.length) throw new Error(\"ArrayIndexOutOfBoundsException\"); return __arr[__idx]; })(" + arr + ", " + idx + ")";
604-
out.append(" ").append(ctx.push(valueExpr)).append(";\n");
605+
String arrayTemp = ctx.nextTemp("__arr");
606+
String indexTemp = ctx.nextTemp("__idx");
607+
out.append(" { const ").append(arrayTemp).append(" = ").append(arr)
608+
.append("; const ").append(indexTemp).append(" = ").append(idx)
609+
.append("; if (!").append(arrayTemp).append(".__array) throw new Error(\"Array expected\"); if (")
610+
.append(indexTemp).append(" < 0 || ").append(indexTemp).append(" >= ").append(arrayTemp)
611+
.append(".length) throw new Error(\"ArrayIndexOutOfBoundsException\"); ")
612+
.append(ctx.push(arrayTemp + "[" + indexTemp + "]")).append("; }\n");
605613
return true;
606614
}
607615
case Opcodes.AASTORE:
@@ -662,13 +670,15 @@ private static boolean appendStraightLineVarInstruction(StringBuilder out, VarOp
662670
case Opcodes.FLOAD:
663671
case Opcodes.DLOAD:
664672
case Opcodes.ALOAD:
673+
ctx.localsUsed[instruction.getIndex()] = true;
665674
out.append(" ").append(ctx.push("l" + instruction.getIndex())).append(";\n");
666675
return true;
667676
case Opcodes.ISTORE:
668677
case Opcodes.LSTORE:
669678
case Opcodes.FSTORE:
670679
case Opcodes.DSTORE:
671680
case Opcodes.ASTORE:
681+
ctx.localsUsed[instruction.getIndex()] = true;
672682
out.append(" l").append(instruction.getIndex()).append(" = ").append(ctx.pop()).append(";\n");
673683
return true;
674684
default:
@@ -823,15 +833,24 @@ private static void appendInvocationArgumentExpressions(StringBuilder out, Strin
823833

824834
private static final class StraightLineContext {
825835
private final boolean[] localsInitialized;
836+
private final boolean[] localsUsed;
826837
private int sp;
838+
private int maxObservedStack;
839+
private int nextTempId;
827840

828841
private StraightLineContext(int maxLocals, int maxStack) {
829842
this.localsInitialized = new boolean[Math.max(1, maxLocals)];
843+
this.localsUsed = new boolean[Math.max(1, maxLocals)];
830844
this.sp = 0;
845+
this.maxObservedStack = 0;
846+
this.nextTempId = 0;
831847
}
832848

833849
private String push(String expression) {
834850
String slot = "s" + sp++;
851+
if (sp > maxObservedStack) {
852+
maxObservedStack = sp;
853+
}
835854
return slot + " = " + expression;
836855
}
837856

@@ -850,6 +869,14 @@ private String peek(int depth) {
850869
}
851870
return "s" + index;
852871
}
872+
873+
private int getMaxObservedStack() {
874+
return maxObservedStack;
875+
}
876+
877+
private String nextTemp(String prefix) {
878+
return prefix + (nextTempId++);
879+
}
853880
}
854881

855882
private static void appendTryCatchTable(StringBuilder out, List<Instruction> instructions, Map<Label, Integer> labelToIndex) {

vm/tests/src/test/java/com/codename1/tools/translator/JavascriptTargetIntegrationTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ void simpleStraightLineMethodsLowerToLocalsInsteadOfInterpreterLoop(CompilerHelp
199199

200200
assertTrue(methodBody.contains("let l0 = __cn1Arg1;") && methodBody.contains("let l1 = __cn1Arg2;"),
201201
"Straight-line lowering should use direct local variables for arguments");
202-
assertTrue(methodBody.contains("let s0 = null;") && methodBody.contains("let s1 = null;"),
203-
"Straight-line lowering should use numbered stack temporaries");
202+
assertTrue(!methodBody.contains("stack["),
203+
"Straight-line lowering should avoid stack-array indexing");
204204
assertTrue(!methodBody.contains("const locals = new Array") && !methodBody.contains("const stack = []") && !methodBody.contains("let pc = 0"),
205205
"Straight-line lowering should avoid the interpreter locals/stack/pc loop");
206206
}

0 commit comments

Comments
 (0)