This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git


The following commit(s) were added to refs/heads/master by this push:
     new 1fa918c86 OPENJPA-2911 addLoadMethod via ASM
1fa918c86 is described below

commit 1fa918c8611c4f3a774e126d22f90912b0b92d6f
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Mon Jul 24 21:26:15 2023 +0200

    OPENJPA-2911 addLoadMethod via ASM
---
 .../apache/openjpa/enhance/PCDataGenerator.java    | 426 +++++++++++++++------
 .../org/apache/openjpa/util/asm/AsmHelper.java     |   2 +-
 2 files changed, 303 insertions(+), 125 deletions(-)

diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
index d5a32f528..e9f4e2acd 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
@@ -173,11 +173,11 @@ public class PCDataGenerator extends 
DynamicStorageGenerator {
         addGetType(bc, meta);
         addVersionMethods(bc);
         addFieldImplDataMethods(bc, meta);
+        addLoadMethod(bc, meta);
 
         BCClass _bc = new 
Project().loadClass(bc.getClassNode().name.replace("/", "."));
         AsmHelper.readIntoBCClass(bc, _bc);
 
-        addLoadMethod(_bc, meta);
         addLoadWithFieldsMethod(_bc, meta);
         addStoreMethods(_bc, meta);
         addNewEmbedded(_bc);
@@ -628,59 +628,86 @@ public class PCDataGenerator extends 
DynamicStorageGenerator {
         }
     }
 
-    private void addLoadMethod(BCClass bc, ClassMetaData meta) {
-        // public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
-        //         Object context)
-        Code code = addLoadMethod(bc, false);
+    private void addLoadMethod(ClassNodeTracker cnt, ClassMetaData meta) {
+        final ClassNode classNode = cnt.getClassNode();
+
+        // public void load(OpenJPAStateManager sm, FetchConfiguration fetch, 
Object context)
+        MethodNode meth = addLoadMethod(cnt, false);
+        InsnList instructions = meth.instructions;
+
         FieldMetaData[] fmds = meta.getFields();
-        Collection<Instruction> jumps = new LinkedList<>();
-        Collection<Instruction> jumps2;
 
-        int local = code.getNextLocalsIndex();
-        code.constant().setNull();
-        code.astore().setLocal(local);
-        int inter = code.getNextLocalsIndex();
-        code.constant().setNull();
-        code.astore().setLocal(inter);
+        int localVarPos = AsmHelper.getLocalVarPos(meth);
+        instructions.add(new InsnNode(Opcodes.ACONST_NULL));
+        instructions.add(new VarInsnNode(Opcodes.ASTORE, localVarPos));
+        int interVarPos = localVarPos + 1;
+        instructions.add(new InsnNode(Opcodes.ACONST_NULL));
+        instructions.add(new VarInsnNode(Opcodes.ASTORE, interVarPos));
 
         int objectCount = 0;
         boolean intermediate;
+        LabelNode lblEndIf = null;
         for (int i = 0; i < fmds.length; i++) {
-            jumps2 = new LinkedList<>();
+
+            if (lblEndIf != null) {
+                instructions.add(lblEndIf);
+            }
+            lblEndIf = new LabelNode();
+
             intermediate = usesIntermediate(fmds[i]);
-            setTarget(code.aload().setThis(), jumps);
-            // if (loaded.get(i)) or (!loaded.get(i)) depending on inter resp
-            code.getfield().setField("loaded", BitSet.class);
-            code.constant().setValue(i);
-            code.invokevirtual().setMethod(BitSet.class, "get",
-                boolean.class, new Class[]{ int.class });
-            jumps.add(code.ifne());
 
-            if (intermediate)
-                addLoadIntermediate(code, i, objectCount, jumps2, inter);
-            jumps2.add(code.go2());
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+
+            // if (loaded.get(i)) or (!loaded.get(i)) depending on inter resp
+            instructions.add(new FieldInsnNode(Opcodes.GETFIELD, 
classNode.name, "loaded", Type.getDescriptor(BitSet.class)));
+            instructions.add(AsmHelper.getLoadConstantInsn(i));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                
Type.getInternalName(BitSet.class),
+                                                "get",
+                                                
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.INT_TYPE)));
+            instructions.add(new JumpInsnNode(intermediate ? Opcodes.IFNE : 
Opcodes.IFEQ, lblEndIf));
 
             // if (fetch.requiresFetch(fmds[i])!=FetchConfiguration.FETCH_NONE)
-            setTarget(code.aload().setParam(1), jumps);
-            code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getMetaData", ClassMetaData.class, null);
-            code.constant().setValue(fmds[i].getIndex());
-            code.invokevirtual().setMethod(ClassMetaData.class,
-                "getField", FieldMetaData.class, new Class[]{int.class});
-            code.invokeinterface().setMethod (FetchConfiguration.class,
-                "requiresFetch", int.class, new Class[]{FieldMetaData.class});
-            code.constant().setValue(FetchConfiguration.FETCH_NONE);
-            jumps2.add(code.ificmpeq());
-            addLoad(bc, code, fmds[i], objectCount, local, false);
 
-            jumps = jumps2;
-            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
+            if (intermediate) {
+                addLoadIntermediate(classNode, instructions, i, objectCount, 
interVarPos);
+
+                LabelNode lblElse = lblEndIf;
+                lblEndIf = new LabelNode();
+                instructions.add(new JumpInsnNode(Opcodes.GOTO, lblEndIf));
+                instructions.add(lblElse);
+            }
+
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); // 2nd param 
FetchConfiguration
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param 
OpenJPAStateManager
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                                
Type.getInternalName(OpenJPAStateManager.class),
+                                                "getMetaData",
+                                                
Type.getMethodDescriptor(Type.getType(ClassMetaData.class))));
+            
instructions.add(AsmHelper.getLoadConstantInsn(fmds[i].getIndex()));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                
Type.getInternalName(ClassMetaData.class),
+                                                "getField",
+                                                
Type.getMethodDescriptor(Type.getType(FieldMetaData.class), Type.INT_TYPE)));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                                
Type.getInternalName(FetchConfiguration.class),
+                                                "requiresFetch",
+                                                
Type.getMethodDescriptor(Type.INT_TYPE, Type.getType(FieldMetaData.class))));
+            
instructions.add(AsmHelper.getLoadConstantInsn(FetchConfiguration.FETCH_NONE));
+            instructions.add(new JumpInsnNode(Opcodes.IF_ICMPEQ, lblEndIf));
+            addLoad(classNode, instructions, fmds[i], objectCount, 
localVarPos, false);
+
+
+            if (replaceType(fmds[i]) >= JavaTypes.OBJECT) {
                 objectCount++;
+            }
         }
-        setTarget(code.vreturn(), jumps);
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
+
+        if (lblEndIf != null) {
+            instructions.add(lblEndIf);
+        }
+
+        instructions.add(new InsnNode(Opcodes.RETURN));
     }
 
     private void addLoadWithFieldsMethod(BCClass bc, ClassMetaData meta) {
@@ -754,114 +781,148 @@ public class PCDataGenerator extends 
DynamicStorageGenerator {
     /**
      * Declare and start the base load method.
      */
-    private Code addLoadMethod(BCClass bc, boolean fields) {
-        Class<?>[] args = null;
-        if (fields)
-            args = new Class[]{ OpenJPAStateManager.class, BitSet.class,
-                FetchConfiguration.class, Object.class };
-        else
-            args = new Class[]{ OpenJPAStateManager.class,
-                FetchConfiguration.class, Object.class };
-        BCMethod load = bc.declareMethod("load", void.class, args);
-        Code code = load.getCode(true);
+    private MethodNode addLoadMethod(ClassNodeTracker cnt, boolean fields) {
+        String mDesc;
+        if (fields) {
+            mDesc = Type.getMethodDescriptor(Type.VOID_TYPE,
+                                             
Type.getType(OpenJPAStateManager.class),
+                                             Type.getType(BitSet.class),
+                                             
Type.getType(FetchConfiguration.class),
+                                             AsmHelper.TYPE_OBJECT);
+        }
+        else {
+            mDesc = Type.getMethodDescriptor(Type.VOID_TYPE,
+                                             
Type.getType(OpenJPAStateManager.class),
+                                             
Type.getType(FetchConfiguration.class),
+                                             AsmHelper.TYPE_OBJECT);
+        }
+        MethodNode meth = new MethodNode(Opcodes.ACC_PUBLIC,
+                                         "load",
+                                         mDesc,
+                                         null, null);
+        cnt.getClassNode().methods.add(meth);
 
-        //loadVersion(sm);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokevirtual().setMethod("loadVersion", void.class,
-            new Class[]{ OpenJPAStateManager.class });
+        // loadVersion(sm);
+        meth.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+        meth.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 
OpenJPAStateManager
+        meth.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                 cnt.getClassNode().name,
+                                                 "loadVersion",
+                                                 
Type.getMethodDescriptor(Type.VOID_TYPE, 
Type.getType(OpenJPAStateManager.class))));
 
         //loadImplData(sm);
-        code.aload().setThis();
-        code.aload().setParam(0);
-        code.invokevirtual().setMethod("loadImplData", void.class,
-            new Class[]{ OpenJPAStateManager.class });
-        return code;
+        meth.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+        meth.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 
OpenJPAStateManager
+        meth.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                 cnt.getClassNode().name,
+                                                 "loadImplData",
+                                                 
Type.getMethodDescriptor(Type.VOID_TYPE, 
Type.getType(OpenJPAStateManager.class))));
+        return meth;
     }
 
     /**
      * Add the field load.
      */
-    private Instruction addLoad(BCClass bc, Code code, FieldMetaData fmd,
-        int objectCount, int local, boolean fields) {
+    private void addLoad(ClassNode classNode, InsnList instructions, 
FieldMetaData fmd,
+                         int objectCount, int localVarPos, boolean fields) {
         int index = fmd.getIndex();
         int typeCode = replaceType(fmd);
-        Instruction first;
         if (typeCode < JavaTypes.OBJECT) {
             // sm.store<type>(i, field<i>)
             Class<?> type = forType(fmd.getTypeCode());
-            first = code.aload().setParam(0);
-            code.constant().setValue(index);
-            code.aload().setThis();
-            code.getfield().setField(getFieldName(index), type);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "store" + StringUtil.capitalize(type.getName()),
-                void.class, new Class[]{ int.class, type });
-        } else {
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
+            instructions.add(AsmHelper.getLoadConstantInsn(index));
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+            instructions.add(new FieldInsnNode(Opcodes.GETFIELD, 
classNode.name, getFieldName(index), Type.getDescriptor(type)));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                                
Type.getInternalName(OpenJPAStateManager.class),
+                                                "store" + 
StringUtil.capitalize(type.getName()),
+                                                
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.getType(type))));
+        }
+        else {
             // fmd = sm.getMetaData().getField(i);
             int offset = fields ? 1 : 0;
-            first = code.aload().setParam(0);
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "getMetaData", ClassMetaData.class, null);
-            code.constant().setValue(fmd.getIndex());
-            code.invokevirtual().setMethod(ClassMetaData.class, "getField",
-                FieldMetaData.class, new Class[]{ int.class });
-            code.astore().setLocal(local);
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                                
Type.getInternalName(OpenJPAStateManager.class),
+                                                "getMetaData",
+                                                
Type.getMethodDescriptor(Type.getType(ClassMetaData.class))));
+            instructions.add(AsmHelper.getLoadConstantInsn(index));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                
Type.getInternalName(ClassMetaData.class),
+                                                "getField",
+                                                
Type.getMethodDescriptor(Type.getType(FieldMetaData.class), Type.INT_TYPE)));
+            instructions.add(new VarInsnNode(Opcodes.ASTORE, localVarPos));
+
             // sm.storeField(i, toField(sm, fmd, objects[objectCount],
             //         fetch, context);
-            code.aload().setParam(0);
-            code.constant().setValue(index);
-            code.aload().setThis();
-            code.aload().setParam(0);
-            code.aload().setLocal(local);
-            code.aload().setThis();
-            code.getfield().setField("objects", Object[].class);
-            code.constant().setValue(objectCount);
-            code.aaload();
-            code.aload().setParam(1 + offset);
-            code.aload().setParam(2 + offset);
-            code.invokevirtual().setMethod(bc.getName(), "toField",
-                Object.class.getName(), toStrings(new Class[]{
-                OpenJPAStateManager.class, FieldMetaData.class,
-                Object.class, FetchConfiguration.class, Object.class }));
-            code.invokeinterface().setMethod(OpenJPAStateManager.class,
-                "storeField", void.class,
-                new Class[]{ int.class, Object.class });
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
+            instructions.add(AsmHelper.getLoadConstantInsn(index));
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, localVarPos));
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+            instructions.add(new FieldInsnNode(Opcodes.GETFIELD, 
classNode.name, "objects", Type.getDescriptor(Object[].class)));
+            instructions.add(AsmHelper.getLoadConstantInsn(objectCount));
+            instructions.add(new InsnNode(Opcodes.AALOAD));
+
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 2+offset));
+            instructions.add(new VarInsnNode(Opcodes.ALOAD, 3+offset));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                classNode.name,
+                                                "toField",
+                                                
Type.getMethodDescriptor(AsmHelper.TYPE_OBJECT,
+                                                                         
Type.getType(OpenJPAStateManager.class),
+                                                                         
Type.getType(FieldMetaData.class),
+                                                                         
AsmHelper.TYPE_OBJECT,
+                                                                         
Type.getType(FetchConfiguration.class),
+                                                                         
AsmHelper.TYPE_OBJECT)));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                                
Type.getInternalName(OpenJPAStateManager.class),
+                                                "storeField",
+                                                
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, 
AsmHelper.TYPE_OBJECT)));
         }
-        return first;
     }
 
     /**
      * Load intermediate data if possible.
      */
-    private Instruction addLoadIntermediate(Code code, int index,
-        int objectCount, Collection<Instruction> jumps2, int inter) {
+    private void addLoadIntermediate(ClassNode classNode, InsnList 
instructions, int index, int objectCount, int interVarPos) {
         // {
-        //         Object inter = objects[objectCount];
-        Instruction first = code.aload().setThis();
-        code.getfield().setField("objects", Object[].class);
-        code.constant().setValue(objectCount);
-        code.aaload();
-        code.astore().setLocal(inter);
-        //         if (inter != null && !sm.getLoaded().get(index))
-        code.aload().setLocal(inter);
-        jumps2.add(code.ifnull());
-        code.aload().setParam(0);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "getLoaded", BitSet.class, null);
-        code.constant().setValue(index);
-        code.invokevirtual().setMethod(BitSet.class, "get",
-            boolean.class, new Class[]{ int.class });
-        jumps2.add(code.ifne());
+        //    Object inter = objects[objectCount];
+        instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+        instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, 
"objects", Type.getDescriptor(Object[].class)));
+        instructions.add(AsmHelper.getLoadConstantInsn(objectCount));
+        instructions.add(new InsnNode(Opcodes.AALOAD));
+        instructions.add(new VarInsnNode(Opcodes.ASTORE, interVarPos));
+
+        //    if (inter != null && !sm.getLoaded().get(index))
+        LabelNode lblEndIf = new LabelNode();
+        instructions.add(new VarInsnNode(Opcodes.ALOAD, interVarPos));
+        instructions.add(new JumpInsnNode(Opcodes.IFNULL, lblEndIf));
+        instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
+        instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                            
Type.getInternalName(OpenJPAStateManager.class),
+                                            "getLoaded",
+                                            
Type.getMethodDescriptor(Type.getType(BitSet.class))));
+        instructions.add(AsmHelper.getLoadConstantInsn(index));
+        instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                            Type.getInternalName(BitSet.class),
+                                            "get",
+                                            
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.INT_TYPE)));
+        instructions.add(new JumpInsnNode(Opcodes.IFNE, lblEndIf));
+
         //            sm.setIntermediate(index, inter);
-        //    }  // end else
-        code.aload().setParam(0);
-        code.constant().setValue(index);
-        code.aload().setLocal(inter);
-        code.invokeinterface().setMethod(OpenJPAStateManager.class,
-            "setIntermediate", void.class,
-            new Class[]{ int.class, Object.class });
-        return first;
+        instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st Param
+        instructions.add(AsmHelper.getLoadConstantInsn(index));
+        instructions.add(new VarInsnNode(Opcodes.ALOAD, interVarPos));
+        instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
+                                            
Type.getInternalName(OpenJPAStateManager.class),
+                                            "setIntermediate",
+                                            
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, 
AsmHelper.TYPE_OBJECT)));
+
+        //    }  // end if - done with lblEndIf
+        instructions.add(lblEndIf);
     }
 
     private void addStoreMethods(BCClass bc, ClassMetaData meta) {
@@ -1149,6 +1210,123 @@ public class PCDataGenerator extends 
DynamicStorageGenerator {
         return strings;
     }
 
+    /**
+     * Declare and start the base load method.
+     */
+    @Deprecated
+    private Code addLoadMethod(BCClass bc, boolean fields) {
+        Class<?>[] args = null;
+        if (fields)
+            args = new Class[]{ OpenJPAStateManager.class, BitSet.class,
+                    FetchConfiguration.class, Object.class };
+        else
+            args = new Class[]{ OpenJPAStateManager.class,
+                    FetchConfiguration.class, Object.class };
+        BCMethod load = bc.declareMethod("load", void.class, args);
+        Code code = load.getCode(true);
+
+        //loadVersion(sm);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokevirtual().setMethod("loadVersion", void.class,
+                                       new Class[]{ OpenJPAStateManager.class 
});
+
+        //loadImplData(sm);
+        code.aload().setThis();
+        code.aload().setParam(0);
+        code.invokevirtual().setMethod("loadImplData", void.class,
+                                       new Class[]{ OpenJPAStateManager.class 
});
+        return code;
+    }
+
+
+    /**
+     * Add the field load.
+     */
+    private Instruction addLoad(BCClass bc, Code code, FieldMetaData fmd,
+                                int objectCount, int local, boolean fields) {
+        int index = fmd.getIndex();
+        int typeCode = replaceType(fmd);
+        Instruction first;
+        if (typeCode < JavaTypes.OBJECT) {
+            // sm.store<type>(i, field<i>)
+            Class<?> type = forType(fmd.getTypeCode());
+            first = code.aload().setParam(0);
+            code.constant().setValue(index);
+            code.aload().setThis();
+            code.getfield().setField(getFieldName(index), type);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                                             "store" + 
StringUtil.capitalize(type.getName()),
+                                             void.class, new Class[]{ 
int.class, type });
+        } else {
+            // fmd = sm.getMetaData().getField(i);
+            int offset = fields ? 1 : 0;
+            first = code.aload().setParam(0);
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                                             "getMetaData", 
ClassMetaData.class, null);
+            code.constant().setValue(fmd.getIndex());
+            code.invokevirtual().setMethod(ClassMetaData.class, "getField",
+                                           FieldMetaData.class, new Class[]{ 
int.class });
+            code.astore().setLocal(local);
+            // sm.storeField(i, toField(sm, fmd, objects[objectCount],
+            //                 fetch, context);
+            code.aload().setParam(0);
+            code.constant().setValue(index);
+            code.aload().setThis();
+            code.aload().setParam(0);
+            code.aload().setLocal(local);
+            code.aload().setThis();
+            code.getfield().setField("objects", Object[].class);
+            code.constant().setValue(objectCount);
+            code.aaload();
+            code.aload().setParam(1 + offset);
+            code.aload().setParam(2 + offset);
+            code.invokevirtual().setMethod(bc.getName(), "toField",
+                                           Object.class.getName(), 
toStrings(new Class[]{
+                            OpenJPAStateManager.class, FieldMetaData.class,
+                            Object.class, FetchConfiguration.class, 
Object.class }));
+            code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                                             "storeField", void.class,
+                                             new Class[]{ int.class, 
Object.class });
+        }
+        return first;
+    }
+
+    /**
+     * Load intermediate data if possible.
+     */
+    @Deprecated
+    private Instruction addLoadIntermediate(Code code, int index,
+                                            int objectCount, 
Collection<Instruction> jumps2, int inter) {
+        // {
+        //             Object inter = objects[objectCount];
+        Instruction first = code.aload().setThis();
+        code.getfield().setField("objects", Object[].class);
+        code.constant().setValue(objectCount);
+        code.aaload();
+        code.astore().setLocal(inter);
+        //             if (inter != null && !sm.getLoaded().get(index))
+        code.aload().setLocal(inter);
+        jumps2.add(code.ifnull());
+        code.aload().setParam(0);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                                         "getLoaded", BitSet.class, null);
+        code.constant().setValue(index);
+        code.invokevirtual().setMethod(BitSet.class, "get",
+                                       boolean.class, new Class[]{ int.class 
});
+        jumps2.add(code.ifne());
+        //                     sm.setIntermediate(index, inter);
+        //     }  // end else
+        code.aload().setParam(0);
+        code.constant().setValue(index);
+        code.aload().setLocal(inter);
+        code.invokeinterface().setMethod(OpenJPAStateManager.class,
+                                         "setIntermediate", void.class,
+                                         new Class[]{ int.class, Object.class 
});
+        return first;
+    }
+
+
     /**
      * Dynamic {@link PCData}s generated will implement this interface
      * to simplify initialization.
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java
index 121d3627d..532fa09d6 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java
@@ -728,7 +728,7 @@ public final class AsmHelper {
         // stack position 0 is this pointer for non-static methods
         // In other words: for a static method the first free stack location 
is 1,
         // for non-static it is 2
-        int pos = ((meth.access & Opcodes.ACC_STATIC) > 0) ? 1 : 2;
+        int pos = ((meth.access & Opcodes.ACC_STATIC) > 0) ? 0 : 1;
 
         // and now add the size of the parameters
         for (Type paramType : paramTypes) {

Reply via email to