mirror of
https://github.com/apache/openjpa.git
synced 2025-02-21 01:15:30 +00:00
OPENJPA-2120 add optimization to methods that use a field manager
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1300380 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ca7918e88c
commit
f4e1d195bb
@ -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,
|
||||
@ -2144,6 +2178,60 @@ public class PCEnhancer {
|
||||
code.calculateMaxLocals();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user