diff options
author | Paul Phillips <paulp@improving.org> | 2010-09-22 06:09:29 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-09-22 06:09:29 +0000 |
commit | 03cd602835e373f47b7c8de55b063a0cc0838eaf (patch) | |
tree | afd6d057f51d34d2bcc08c0eab243cbb4bbd34b4 | |
parent | 567968ab8e93e8afcfbb7a7f5a709b80d8ca0827 (diff) | |
download | scala-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.
-rw-r--r-- | lib/fjbg.jar.desired.sha1 | 2 | ||||
-rw-r--r-- | src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java | 40 |
2 files changed, 38 insertions, 4 deletions
diff --git a/lib/fjbg.jar.desired.sha1 b/lib/fjbg.jar.desired.sha1 index 7e1cb1c13e..862868d030 100644 --- a/lib/fjbg.jar.desired.sha1 +++ b/lib/fjbg.jar.desired.sha1 @@ -1 +1 @@ -b73c0c9115d83849bada9a5c361f77745da22e0d ?fjbg.jar +3997a32211461f0f7de1e4eb37e964cd134ea003 ?fjbg.jar 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()); } |