summaryrefslogtreecommitdiff
path: root/src/fjbg/ch/epfl/lamp
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-09-22 06:09:29 +0000
committerPaul Phillips <paulp@improving.org>2010-09-22 06:09:29 +0000
commit03cd602835e373f47b7c8de55b063a0cc0838eaf (patch)
treeafd6d057f51d34d2bcc08c0eab243cbb4bbd34b4 /src/fjbg/ch/epfl/lamp
parent567968ab8e93e8afcfbb7a7f5a709b80d8ca0827 (diff)
downloadscala-03cd602835e373f47b7c8de55b063a0cc0838eaf.tar.gz
scala-03cd602835e373f47b7c8de55b063a0cc0838eaf.tar.bz2
scala-03cd602835e373f47b7c8de55b063a0cc0838eaf.zip
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.
Diffstat (limited to 'src/fjbg/ch/epfl/lamp')
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java40
1 files changed, 37 insertions, 3 deletions
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()); }