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;