From 03cd602835e373f47b7c8de55b063a0cc0838eaf Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 22 Sep 2010 06:09:29 +0000 Subject: Found the following inefficiencies in fjbg: ldc being used instead of bipush or sipush. The cheaper instructions were only being used when the argument was typed as byte or short, but an Int in the byte or short range can as easily use them. This also saves an entry in the constant pool. iconst_n not being used except on Ints. Same issue in reverse: pushing short 3 on the stack is cheaper with iconst_3 than with sipush. Example: class A { def f1: Int = 100 // was ldc #X, now bipush 100 def f2: Int = 5000 // was ldc #X, now sipush 5000 def f3: Byte = 2 // was bipush 2, now iconst_2 def f4: Short = 2 // was sipush 2, now iconst_2 } Review by dragos. --- src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java | 40 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'src/fjbg/ch/epfl/lamp') diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java b/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java index f0f61630e6..69b522b622 100644 --- a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java +++ b/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java @@ -112,10 +112,37 @@ public class JExtendedCode extends JCode { public void emitPUSH(boolean value) { emitPUSH(value ? 1 : 0); } public void emitPUSH(Boolean value) { emitPUSH(value.booleanValue()); } - public void emitPUSH(byte value) { emitBIPUSH(value); } + public void emitPUSH(byte value) { + switch (value) { + case -1: emitICONST_M1(); break; + case 0: emitICONST_0(); break; + case 1: emitICONST_1(); break; + case 2: emitICONST_2(); break; + case 3: emitICONST_3(); break; + case 4: emitICONST_4(); break; + case 5: emitICONST_5(); break; + default: + emitBIPUSH(value); + } + } public void emitPUSH(Byte value) { emitPUSH(value.byteValue()); } - public void emitPUSH(short value) { emitSIPUSH(value); } + public void emitPUSH(short value) { + switch (value) { + case -1: emitICONST_M1(); break; + case 0: emitICONST_0(); break; + case 1: emitICONST_1(); break; + case 2: emitICONST_2(); break; + case 3: emitICONST_3(); break; + case 4: emitICONST_4(); break; + case 5: emitICONST_5(); break; + default: + if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) + emitBIPUSH((byte)value); + else + emitSIPUSH(value); + } + } public void emitPUSH(Short value) { emitPUSH(value.shortValue()); } // TODO check that we do the right thing here @@ -131,7 +158,14 @@ public class JExtendedCode extends JCode { case 3: emitICONST_3(); break; case 4: emitICONST_4(); break; case 5: emitICONST_5(); break; - default: emitPUSH_index(pool.addInteger(value)); break; + default: + if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) + emitBIPUSH((byte)value); + else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) + emitSIPUSH((short)value); + else + emitPUSH_index(pool.addInteger(value)); + break; } } public void emitPUSH(Integer value) { emitPUSH(value.intValue()); } -- cgit v1.2.3