You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by dj...@apache.org on 2006/02/18 18:55:50 UTC
svn commit: r378744 -
/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
Author: djd
Date: Sat Feb 18 09:55:48 2006
New Revision: 378744
URL: http://svn.apache.org/viewcvs?rev=378744&view=rev
Log:
DERBY-176 DERBY-766 Modify pushing a long value in generated code to avoid
using constant pool entries if the long is within the range of a short.
Then use the I2L instruction to convert the int to a long. Also if
the long is within range of an int, then create a integer constant pool
entry and I2L to avoid using two constant pool slots.
Add some clarifying comments over the code length in complete.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java?rev=378744&r1=378743&r2=378744&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java Sat Feb 18 09:55:48 2006
@@ -224,11 +224,14 @@
*/
public void complete() {
+ // myCode.getPC() gives the code length since
+ // the program counter will be positioned after
+ // the last instruction. Note this value can
+ // be changed by the splitMethod call.
- int codeLength = myCode.getPC();
- if (codeLength > CODE_SPLIT_LENGTH)
+ if (myCode.getPC() > CODE_SPLIT_LENGTH)
splitMethod();
-
+
// write exceptions attribute info
writeExceptions();
@@ -491,6 +494,15 @@
}
+ /**
+ * Push an integer value. Uses the special integer opcodes
+ * for the constants -1 to 5, BIPUSH for values that fit in
+ * a byte and SIPUSH for values that fit in a short. Otherwise
+ * uses LDC with a constant pool entry.
+ *
+ * @param value Value to be pushed
+ * @param type Final type of the value.
+ */
private void push(int value, Type type) {
CodeChunk chunk = myCode;
@@ -505,23 +517,40 @@
int cpe = modClass.addConstant(value);
addInstrCPE(VMOpcode.LDC, cpe);
}
- growStack(1, type);
+ growStack(type.width(), type);
}
- public void push(long value){
- CodeChunk chunk = myCode;
-
- if (value == 0 || value == 1) {
- chunk.addInstr((short)(VMOpcode.LCONST_0+(short)value));
- }
- else {
- int cpe = modClass.addConstant(value);
- chunk.addInstrU2(VMOpcode.LDC2_W, cpe);
- }
- growStack(2, Type.LONG);
+ /**
+ * Push a long value onto the stack.
+ * For the values zero and one the LCONST_0 and
+ * LCONST_1 instructions are used.
+ * For values betwee Short.MIN_VALUE and Short.MAX_VALUE
+ * inclusive an byte/short/int value is pushed
+ * using push(int, Type) followed by an I2L instruction.
+ * This saves using a constant pool entry for such values.
+ * All other values use a constant pool entry. For values
+ * in the range of an Integer an integer constant pool
+ * entry is created to allow sharing with integer constants
+ * and to reduce constant pool slot entries.
+ */
+ public void push(long value) {
+ CodeChunk chunk = myCode;
- }
+ if (value == 0L || value == 1L) {
+ short opcode = value == 0L ? VMOpcode.LCONST_0 : VMOpcode.LCONST_1;
+ chunk.addInstr(opcode);
+ } else if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) {
+ // the push(int, Type) method grows the stack for us.
+ push((int) value, Type.LONG);
+ chunk.addInstr(VMOpcode.I2L);
+ return;
+ } else {
+ int cpe = modClass.addConstant(value);
+ chunk.addInstrU2(VMOpcode.LDC2_W, cpe);
+ }
+ growStack(2, Type.LONG);
+ }
public void push(float value) {
CodeChunk chunk = myCode;