openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jrba...@apache.org
Subject svn commit: r1300381 - /openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
Date Tue, 13 Mar 2012 22:11:40 GMT
Author: jrbauer
Date: Tue Mar 13 22:11:39 2012
New Revision: 1300381

URL: http://svn.apache.org/viewvc?rev=1300381&view=rev
Log:
OPENJPA-2120 add optimization to methods that use a field manager

Modified:
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java?rev=1300381&r1=1300380&r2=1300381&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
(original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
Tue Mar 13 22:11:39 2012
@@ -2023,13 +2023,30 @@ public class PCEnhancer { 
         boolean reflect;
         // If optimizeIdCopy is enabled and not a field manager method, try to
         // optimize the copyTo by using a public constructor instead of reflection
-        if (_optimizeIdCopy && !fieldManager) {
+        if (_optimizeIdCopy) {
             ArrayList<Integer> pkfields = optimizeIdCopy(oidType, fmds);
             if (pkfields != null) {
                 // search for a constructor on the IdClass that can be used
                 // to construct the IdClass
                 int parmOrder[] = getIdClassConstructorParmOrder(oidType, pkfields, fmds);
                 if (parmOrder != null) {
+                    // If using a field manager, values must be loaded into locals so they
can be properly ordered
+                    // as constructor parameters.
+                    int[] localIndexes = new int[fmds.length];
+                    if (fieldManager) {
+                        for (int k = 0; k < fmds.length; k++) {
+                            if (!fmds[k].isPrimaryKey())
+                                continue;
+                            code.aload().setParam(0);
+                            code.constant().setValue(k);
+                            code.iload().setLocal(inherited);
+                            code.iadd();
+                            code.invokeinterface().setMethod(getFieldSupplierMethod(fmds[k].getObjectIdFieldType()));
+                            localIndexes[k] = code.getNextLocalsIndex();
+                            storeLocalValue(code, localIndexes[k], fmds[k].getObjectIdFieldTypeCode());
+                        }
+                    }
+                    
                     // found a matching constructor.  parm array is constructor parm order
                     code.anew().setType(oidType);
                     code.dup();
@@ -2038,8 +2055,25 @@ public class PCEnhancer { 
                     for (int i = 0; i < clsArgs.length; i++) {
                         int parmIndex = parmOrder[i];
                         clsArgs[i] = fmds[parmIndex].getObjectIdFieldType();
-                        loadManagedInstance(code, false);
-                        addGetManagedValueCode(code, fmds[parmIndex]);
+                        if (!fieldManager) {
+                            loadManagedInstance(code, false);
+                            addGetManagedValueCode(code, fmds[parmIndex]);
+                        } else {
+                            // Load constructor parameters in appropriate order
+                            loadLocalValue(code, localIndexes[parmIndex], fmds[parmIndex].getObjectIdFieldTypeCode());
+                            if (fmds[parmIndex].getObjectIdFieldTypeCode() == JavaTypes.OBJECT
&&
+                                !fmds[parmIndex].getDeclaredType().isEnum()) {
+                                code.checkcast().setType(ObjectId.class);
+                                code.invokevirtual().setMethod(ObjectId.class, "getId", 
+                                    Object.class, null);                    
+                            }
+                            // if the type of this field meta data is
+                            // non-primitive and non-string, be sure to cast
+                            // to the appropriate type.
+                            if (!clsArgs[i].isPrimitive()
+                                && !clsArgs[i].getName().equals(String.class.getName()))
+                                code.checkcast().setType(clsArgs[i]);
+                        }
                     }
                     // invoke the public constructor to create a new local id
                     code.invokespecial().setMethod(oidType, "<init>", void.class, clsArgs);
@@ -2047,7 +2081,7 @@ public class PCEnhancer { 
                     code.astore().setLocal(ret);
 
                     // swap out the app id with the new one
-                    code.aload().setLocal(1);
+                    code.aload().setLocal( fieldManager ? 2 : 1);
                     code.checkcast().setType(ObjectId.class);
                     code.aload().setLocal(ret);
                     code.invokestatic().setMethod(ApplicationIds.class, 
@@ -2145,6 +2179,60 @@ public class PCEnhancer { 
     }
 
     /**
+     * Adds the appropriate load method for the given type and local
+     * index.
+     */
+    private void loadLocalValue(Code code, int locidx, int typeCode) {
+        switch (typeCode) {
+            case JavaTypes.CHAR:
+            case JavaTypes.BYTE:
+            case JavaTypes.SHORT:
+            case JavaTypes.INT:
+                code.iload().setLocal(locidx);
+                break;
+            case JavaTypes.DOUBLE:
+                code.dload().setLocal(locidx);
+                break;
+            case JavaTypes.FLOAT:
+                code.fload().setLocal(locidx);
+                break;
+            case JavaTypes.LONG:
+                code.lload().setLocal(locidx);
+                break;
+            default:
+                code.aload().setLocal(locidx);
+                break;
+        }
+    }
+
+    /**
+     * Adds the appropriate store method for the given type and local
+     * index.
+     */
+    private void storeLocalValue(Code code, int locidx, int typeCode) {
+        switch (typeCode) {
+            case JavaTypes.CHAR:
+            case JavaTypes.BYTE:
+            case JavaTypes.SHORT:
+            case JavaTypes.INT:
+                code.istore().setLocal(locidx);
+                break;
+            case JavaTypes.DOUBLE:
+                code.dstore().setLocal(locidx);
+                break;
+            case JavaTypes.FLOAT:
+                code.fstore().setLocal(locidx);
+                break;
+            case JavaTypes.LONG:
+                code.lstore().setLocal(locidx);
+                break;
+            default:
+                code.astore().setLocal(locidx);
+                break;
+        }
+    }
+
+    /**
      * Add code to extract the id of the given primary key relation field for
      * setting into an objectid instance.
      */



Mime
View raw message