db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmars...@apache.org
Subject svn commit: r590827 - in /db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode: BCMethod.java CodeChunk.java GClass.java
Date Wed, 31 Oct 2007 21:03:37 GMT
Author: kmarsden
Date: Wed Oct 31 14:03:35 2007
New Revision: 590827

URL: http://svn.apache.org/viewvc?rev=590827&view=rev
Log:
DERBY-766 (partial) 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.

Add check to ensure a generated method is no split if it contains a return
instruction in the middle.

merge from trunk 378744,426825


Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/CodeChunk.java
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/GClass.java

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java?rev=590827&r1=590826&r2=590827&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
(original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
Wed Oct 31 14:03:35 2007
@@ -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;

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/CodeChunk.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/CodeChunk.java?rev=590827&r1=590826&r2=590827&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/CodeChunk.java
(original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/CodeChunk.java
Wed Oct 31 14:03:35 2007
@@ -974,6 +974,7 @@
     private String getTypeDescriptor(ClassHolder ch, int pc) {
         int cpi = getU2(pc);
 
+
         // Field reference or method reference
         CONSTANT_Index_info cii = (CONSTANT_Index_info) ch.getEntry(cpi);
 
@@ -1327,9 +1328,24 @@
             // than the VM can handle. Save one for
             // return instruction.
             if (splitLength > BCMethod.CODE_SPLIT_LENGTH - 1) {
+                splitLength = -1;
+            }
+            else if (CodeChunk.isReturn(opcode))
+            {
+                // Don't handle a return in the middle of
+                // an instruction stream. Don't think this
+                // is generated, but be safe.           
+                splitLength = -1;
+            }
+            
+            // if splitLenth was set to -1 above then there
+            // is no possible split at this instruction.
+            if (splitLength == -1)
+            {
+                // no earlier split at all
                 if (possibleSplitLength == -1)
                     return -1;
-
+ 
                 // Decide if the earlier possible split is
                 // worth it. 100 is an arbitary number,
                 // a real low limit would be the number of
@@ -1510,5 +1526,26 @@
         mb.maxStack = replaceChunk.findMaxStack(ch, 0, replaceChunk.getPC());
 
         return postSplit_pc;
+    }
+    
+    /**
+     * See if the opcode is a return instruction.
+     * @param opcode opcode to be checked
+     * @return true for is a return instruction, false otherwise.
+     */
+    private static boolean isReturn(short opcode)
+    {
+        switch (opcode)
+        {
+        case VMOpcode.RETURN:
+        case VMOpcode.ARETURN:
+        case VMOpcode.IRETURN:
+        case VMOpcode.FRETURN:
+        case VMOpcode.DRETURN:
+        case VMOpcode.LRETURN:
+            return true;
+         default:
+            return false;
+        }        
     }
 }

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/GClass.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/GClass.java?rev=590827&r1=590826&r2=590827&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/GClass.java
(original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/bytecode/GClass.java
Wed Oct 31 14:03:35 2007
@@ -93,7 +93,7 @@
 		}
 	}
 
-	public final void validateType(String typeName1)
+	final void validateType(String typeName1)
 	{
 	    if (SanityManager.DEBUG)
 	    {
@@ -101,6 +101,8 @@
 
             String typeName = typeName1.trim();
 
+            if ("void".equals(typeName)) return;
+
 	        // first remove all array-ness
 	        while (typeName.endsWith("[]")) typeName = typeName.substring(0,typeName.length()-2);
 
@@ -115,7 +117,6 @@
 	        if ("int".equals(typeName)) return;
 	        if ("long".equals(typeName)) return;
 	        if ("short".equals(typeName)) return;
-	        if ("void".equals(typeName)) return;
 
 	        // then see if it can be found
 	        // REVISIT: this will fail if ASSERT is on and the



Mime
View raw message