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 7700fdfd4 OPENJPA-2911 DetachedState as ASM
7700fdfd4 is described below

commit 7700fdfd45d0f1995d7e4592d5a8c6c713c05faa
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Wed Jul 12 11:05:04 2023 +0200

    OPENJPA-2911 DetachedState as ASM
---
 .../org/apache/openjpa/enhance/PCEnhancer.java     | 85 +++++++++++-----------
 1 file changed, 43 insertions(+), 42 deletions(-)

diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
index 483f05aa3..2ff67b469 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
@@ -1687,7 +1687,7 @@ public class PCEnhancer {
                     // pcVersionInit = true;
                     instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // 
this
                     instructions.add(new InsnNode(Opcodes.ICONST_1));
-                    putfield(instructions, getType(_meta), VERSION_INIT_STR, 
boolean.class);
+                    putfield(classNode, instructions, getType(_meta), 
VERSION_INIT_STR, boolean.class);
                 }
 
                 instructions.add(new InsnNode(Opcodes.RETURN));
@@ -4633,13 +4633,10 @@ public class PCEnhancer {
         // accessor methods
         if (_meta.getPCSuperclass() == null || getCreateSubclass() || 
parentDetachable != _meta.isDetachable()) {
             addIsDetachedMethod(classNode);
-            AsmHelper.readIntoBCClass(pc, _pc);
-
             addDetachedStateMethods(_meta.usesDetachedState() != 
Boolean.FALSE);
         }
-        else {
-            AsmHelper.readIntoBCClass(pc, _pc);
-        }
+
+        AsmHelper.readIntoBCClass(pc, _pc);
 
         // if we detach on serialize, we also need to implement the
         // externalizable interface to write just the state for the fields
@@ -4662,54 +4659,55 @@ public class PCEnhancer {
     private void addDetachedStateMethods(boolean impl) {
         Field detachField = _meta.getDetachedStateField();
         String name = null;
-        String declarer = null;
+        Class<?> declarer = null;
+        final ClassNode classNode = pc.getClassNode();
+
+
         if (impl && detachField == null) {
             name = PRE + "DetachedState";
-            declarer = _pc.getName();
-            BCField field = _pc.declareField(name, Object.class);
-            field.makePrivate();
-            field.setTransient(true);
+            FieldNode field = new FieldNode(Opcodes.ACC_PRIVATE | 
Opcodes.ACC_TRANSIENT,
+                                            name,
+                                            TYPE_OBJECT.getDescriptor(),
+                                            null, null);
+            classNode.fields.add(field);
         }
         else if (impl) {
             name = detachField.getName();
-            declarer = detachField.getDeclaringClass().getName();
+            declarer = detachField.getDeclaringClass();
         }
 
         // public Object pcGetDetachedState ()
-        BCMethod method = _pc.declareMethod(PRE + "GetDetachedState",
-                                            Object.class, null);
-        method.setStatic(false);
-        method.makePublic();
-        int access = method.getAccessFlags();
+        MethodNode getDetachedStateMeth = new MethodNode(Opcodes.ACC_PUBLIC,
+                                                         PRE + 
"GetDetachedState",
+                                                         
Type.getMethodDescriptor(TYPE_OBJECT),
+                                                         null, null);
+        classNode.methods.add(getDetachedStateMeth);
 
-        Code code = method.getCode(true);
         if (impl) {
             // return pcDetachedState;
-            loadManagedInstance(code, false);
-            getfield(code, _managedType.getProject().loadClass(declarer),
-                     name);
+            getDetachedStateMeth.instructions.add(new 
VarInsnNode(Opcodes.ALOAD, 0)); // this
+            getfield(classNode, getDetachedStateMeth.instructions, declarer, 
name, Object.class);
         }
-        else
-            code.constant().setNull();
-        code.areturn();
-        code.calculateMaxLocals();
-        code.calculateMaxStack();
+        else {
+            getDetachedStateMeth.instructions.add(new 
InsnNode(Opcodes.ACONST_NULL));
+        }
+        getDetachedStateMeth.instructions.add(new InsnNode(Opcodes.ARETURN));
+
 
         // public void pcSetDetachedState (Object state)
-        method = _pc.declareMethod(PRE + "SetDetachedState",
-                                   void.class, new Class[]{Object.class});
-        method.setAccessFlags(access);
-        code = method.getCode(true);
+        MethodNode setDetachedStateMeth = new MethodNode(Opcodes.ACC_PUBLIC,
+                                                         PRE + 
"SetDetachedState",
+                                                         
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT),
+                                                         null, null);
+        classNode.methods.add(setDetachedStateMeth);
+
         if (impl) {
             // pcDetachedState = state;
-            loadManagedInstance(code, false);
-            code.aload().setParam(0);
-            putfield(code, _managedType.getProject().loadClass(declarer),
-                     name, Object.class);
+            setDetachedStateMeth.instructions.add(new 
VarInsnNode(Opcodes.ALOAD, 0)); // this
+            setDetachedStateMeth.instructions.add(new 
VarInsnNode(Opcodes.ALOAD, 1)); // 1st parameter
+            putfield(classNode, setDetachedStateMeth.instructions, declarer, 
name, Object.class);
         }
-        code.vreturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
+        setDetachedStateMeth.instructions.add(new InsnNode(Opcodes.RETURN));
     }
 
     /**
@@ -4859,9 +4857,11 @@ public class PCEnhancer {
      * When this method is invoked, the value to load must
      * already be on the top of the stack,
      * and the instance to load into must be second.
-     * @param declarer internal class name (org/bla/..) which contains the 
field
+     *
+     * @param classNode
+     * @param declarer  internal class name (org/bla/..) which contains the 
field
      */
-    private void putfield(InsnList instructions, Class declarer, String 
attrName, Class fieldType) {
+    private void putfield(ClassNode classNode, InsnList instructions, Class 
declarer, String attrName, Class fieldType) {
         String fieldName = toBackingFieldName(attrName);
 
         if (getRedefine() || getCreateSubclass()) {
@@ -4889,7 +4889,8 @@ public class PCEnhancer {
 
         }
         else {
-            instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, 
Type.getInternalName(declarer), fieldName, Type.getDescriptor(fieldType)));
+            String owner = declarer != null ? Type.getInternalName(declarer) : 
classNode.name;
+            instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, owner, 
fieldName, Type.getDescriptor(fieldType)));
         }
     }
 
@@ -5486,7 +5487,7 @@ public class PCEnhancer {
         // just do a subclass approach instead. But this is not a good option,
         // since it would sacrifice lazy loading and efficient dirty tracking.
         if (getRedefine() || isFieldAccess(fmd)) {
-            putfield(instructions, fmd.getDeclaringType(), fmd.getName(), 
fmd.getDeclaredType());
+            putfield(classNode, instructions, fmd.getDeclaringType(), 
fmd.getName(), fmd.getDeclaredType());
         }
         else if (getCreateSubclass()) {
             // property access, and we're not redefining. invoke the
@@ -5520,7 +5521,7 @@ public class PCEnhancer {
         // just do a subclass approach instead. But this is not a good option,
         // since it would sacrifice lazy loading and efficient dirty tracking.
         if (getRedefine() || isFieldAccess(fmd)) {
-            putfield(instructions, getType(_meta), fmd.getName(), 
fmd.getDeclaredType());
+            putfield(classNode, instructions, getType(_meta), fmd.getName(), 
fmd.getDeclaredType());
         }
         else if (getCreateSubclass()) {
             // property access, and we're not redefining. invoke the

Reply via email to