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

commit 94d18740199e16e0b41dff324770f6b442142155
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Tue Jun 20 18:00:27 2023 +0200

    !32852 work on staticInitializer via ASM
    
    sadly we cannot yet activate it as it uses LDC ops for classes
    which Serp does not understand as it is pre Java-1.4
---
 .../org/apache/openjpa/enhance/PCEnhancer.java     | 139 +++++++++++----------
 .../org/apache/openjpa/util/asm/AsmHelper.java     |  74 +++++++++++
 .../openjpa/persistence/query/SimpleEntity.java    |  14 +++
 3 files changed, 162 insertions(+), 65 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 057627a5b..b2b4d7677 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
@@ -597,11 +597,12 @@ public class PCEnhancer {
             if (_meta != null) {
                 enhanceClass(pc);
                 addFields(pc);
-                //X TODO finish addStaticInitializer(classNodeTracker);
-                AsmHelper.readIntoBCClass(pc, _pc);
-                addStaticInitializer();
 
-                pc = AsmHelper.toClassNode(_pc);
+                //X For now we cannot take the new version as it uses LDC for 
classes which Serp doesn't understand.
+                //X So we can only enable it in a later step
+                //X addStaticInitializer(pc);
+                addStaticInitializer(); // removeme
+
                 addPCMethods(pc);
 
                 addAccessors();
@@ -857,7 +858,7 @@ public class PCEnhancer {
                 LabelNode caseLabel = new LabelNode();
                 switchNd.labels.add(caseLabel);
                 instructions.add(caseLabel);
-                instructions.add(new 
LdcInsnNode(_attrsToFields.get(fmd.getName())));
+                
instructions.add(AsmHelper.getLoadConstantInsn(_attrsToFields.get(fmd.getName())));
                 instructions.add(new InsnNode(Opcodes.ARETURN));
             }
 
@@ -876,7 +877,7 @@ public class PCEnhancer {
                 instructions.add(caseLabel);
                 switchNd.labels.add(caseLabel);
                 switchNd.keys.add(propFmds.get(i));
-                instructions.add(new 
LdcInsnNode(_attrsToFields.get(fmds[i].getName())));
+                
instructions.add(AsmHelper.getLoadConstantInsn(_attrsToFields.get(fmds[i].getName())));
                 instructions.add(new InsnNode(Opcodes.ARETURN));
             }
         }
@@ -1219,7 +1220,7 @@ public class PCEnhancer {
         InsnList insns = new InsnList();
 
         insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
-        insns.add(new LdcInsnNode(fmd.getIndex()));
+        insns.add(AsmHelper.getLoadConstantInsn(fmd.getIndex()));
         insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                                      
Type.getInternalName(RedefinitionHelper.class),
                                      "accessingField",
@@ -1253,7 +1254,7 @@ public class PCEnhancer {
         InsnList insns = new InsnList();
 
         insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
-        insns.add(new LdcInsnNode(fmd.getIndex()));
+        insns.add(AsmHelper.getLoadConstantInsn(fmd.getIndex()));
 
         Class type = fmd.getDeclaredType();
         // we only have special signatures for primitives and Strings
@@ -1547,7 +1548,7 @@ public class PCEnhancer {
         // pcInheritedFieldCount field isn't initialized!  so instead,
         // return <fields> + <superclass>.pcGetManagedFieldCount ()
         final InsnList instructions = getFieldCountMeth.instructions;
-        instructions.add(new LdcInsnNode(_meta.getDeclaredFields().length));
+        
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getDeclaredFields().length));
         if (_meta.getPCSuperclass() != null) {
             Class superClass = getType(_meta.getPCSuperclassMetaData());
             String superName = getCreateSubclass() ?
@@ -3284,6 +3285,7 @@ public class PCEnhancer {
 
     @Deprecated
     private void addStaticInitializer() {
+        AsmHelper.readIntoBCClass(pc, _pc);
         Code code = getOrCreateClassInitCode(true);
         if (_meta.getPCSuperclass() != null) {
             if (getCreateSubclass()) {
@@ -3368,6 +3370,7 @@ public class PCEnhancer {
 
         code.vreturn();
         code.calculateMaxStack();
+        pc = AsmHelper.toClassNode(_pc);
     }
 
     /**
@@ -3380,91 +3383,97 @@ public class PCEnhancer {
         InsnList instructions = new InsnList();
         if (_meta.getPCSuperclass() != null) {
             if (getCreateSubclass()) {
-                instructions.add(new LdcInsnNode(0));
-                instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, 
classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
+                instructions.add(AsmHelper.getLoadConstantInsn(0));
+                instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, 
classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
             }
             else {
                 // pcInheritedFieldCount = 
<superClass>.pcGetManagedFieldCount()
                 instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, 
classNode.superName,
                                                     PRE + 
"GetManagedFieldCount",
                                                     
Type.getMethodDescriptor(Type.INT_TYPE)));
-                instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, 
classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
+                instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, 
classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
             }
 
             // pcPCSuperclass = <superClass>;
             // this intentionally calls getDescribedType() directly
             // instead of PCEnhancer.getType()
-            instructions.add(new 
LdcInsnNode(Type.getType(_meta.getPCSuperclassMetaData().getDescribedType())));
+            
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getPCSuperclassMetaData().getDescribedType()));
             instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, 
classNode.name, SUPER, Type.getDescriptor(Class.class)));
         }
 
-        // pcFieldNames = new String[] { "<name1>", "<name2>", ... };
         FieldMetaData[] fmds = _meta.getDeclaredFields();
 
-/*
-
         // pcFieldNames = new String[] { "<name1>", "<name2>", ... };
-        FieldMetaData[] fmds = _meta.getDeclaredFields();
-        code.constant().setValue(fmds.length);
-        code.anewarray().setType(String.class);
+        instructions.add(AsmHelper.getLoadConstantInsn(fmds.length));
+        instructions.add(new TypeInsnNode(Opcodes.ANEWARRAY, 
Type.getInternalName(String.class)));
         for (int i = 0; i < fmds.length; i++) {
-            code.dup();
-            code.constant().setValue(i);
-            code.constant().setValue(fmds[i].getName());
-            code.aastore();
+            instructions.add(new InsnNode(Opcodes.DUP));
+            instructions.add(AsmHelper.getLoadConstantInsn(i));
+            instructions.add(AsmHelper.getLoadConstantInsn(fmds[i].getName()));
+            instructions.add(new InsnNode(Opcodes.AASTORE));
         }
-        code.putstatic().setField(PRE + "FieldNames", String[].class);
+        instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, 
PRE + "FieldNames", Type.getDescriptor(String[].class)));
 
         // pcFieldTypes = new Class[] { <type1>.class, <type2>.class, ... };
-        code.constant().setValue(fmds.length);
-        code.anewarray().setType(Class.class);
+        instructions.add(AsmHelper.getLoadConstantInsn(fmds.length));
+        instructions.add(new TypeInsnNode(Opcodes.ANEWARRAY, 
Type.getInternalName(Class.class)));
         for (int i = 0; i < fmds.length; i++) {
-            code.dup();
-            code.constant().setValue(i);
-            code.classconstant().setClass(fmds[i].getDeclaredType());
-            code.aastore();
+            instructions.add(new InsnNode(Opcodes.DUP));
+            instructions.add(AsmHelper.getLoadConstantInsn(i));
+            
instructions.add(AsmHelper.getLoadConstantInsn(fmds[i].getDeclaredType()));
+            instructions.add(new InsnNode(Opcodes.AASTORE));
         }
-        code.putstatic().setField(PRE + "FieldTypes", Class[].class);
+        instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, 
PRE + "FieldTypes", Type.getDescriptor(Class[].class)));
 
         // pcFieldFlags = new byte[] { <flag1>, <flag2>, ... };
-        code.constant().setValue(fmds.length);
-        code.newarray().setType(byte.class);
+        instructions.add(AsmHelper.getLoadConstantInsn(fmds.length));
+        instructions.add(new IntInsnNode(Opcodes.NEWARRAY, Opcodes.T_BYTE));
         for (int i = 0; i < fmds.length; i++) {
-            code.dup();
-            code.constant().setValue(i);
-            code.constant().setValue(getFieldFlag(fmds[i]));
-            code.bastore();
+            instructions.add(new InsnNode(Opcodes.DUP));
+            instructions.add(AsmHelper.getLoadConstantInsn(i));
+            
instructions.add(AsmHelper.getLoadConstantInsn(getFieldFlag(fmds[i])));
+            instructions.add(new InsnNode(Opcodes.BASTORE));
         }
-        code.putstatic().setField(PRE + "FieldFlags", byte[].class);
+        instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, 
PRE + "FieldFlags", Type.getDescriptor(byte[].class)));
 
+/*
         // PCRegistry.register (cls,
         //    pcFieldNames, pcFieldTypes, pcFieldFlags,
         //  pcPCSuperclass, alias, new XXX ());
-        code.classconstant().setClass(_meta.getDescribedType());
-        code.getstatic().setField(PRE + "FieldNames", String[].class);
-        code.getstatic().setField(PRE + "FieldTypes", Class[].class);
-        code.getstatic().setField(PRE + "FieldFlags", byte[].class);
-        code.getstatic().setField(SUPER, Class.class);
+        
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getDescribedType()));
+        instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, 
PRE + "FieldNames", Type.getDescriptor(String[].class)));
+        instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, 
PRE + "FieldTypes", Type.getDescriptor(Class[].class)));
+        instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, 
PRE + "FieldFlags", Type.getDescriptor(byte[].class)));
+        instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, 
SUPER, Type.getDescriptor(Class.class)));
 
-        if (_meta.isMapped() || _meta.isAbstract())
-            code.constant().setValue(_meta.getTypeAlias());
-        else
-            code.constant().setNull();
+        if (_meta.isMapped() || _meta.isAbstract()) {
+            
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getTypeAlias()));
+        }
+        else {
+            instructions.add(new InsnNode(Opcodes.ACONST_NULL));
+        }
 
-        if (_pc.isAbstract())
-            code.constant().setNull();
+        if (_pc.isAbstract()) {
+            instructions.add(new InsnNode(Opcodes.ACONST_NULL));
+        }
         else {
-            code.anew().setType(_pc);
-            code.dup();
-            code.invokespecial().setMethod("<init>", void.class, null);
+            instructions.add(new TypeInsnNode(Opcodes.NEW, classNode.name));
+            instructions.add(new InsnNode(Opcodes.DUP));
+            instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
+                                                classNode.name,
+                                                "<init>",
+                                                
Type.getMethodDescriptor(Type.VOID_TYPE)));
         }
 
-        code.invokestatic().setMethod(HELPERTYPE, "register", void.class,
-            new Class[]{ Class.class, String[].class, Class[].class,
-                byte[].class, Class.class, String.class, PCTYPE });
+        instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
+                                            Type.getInternalName(HELPERTYPE),
+                                            "register",
+                                            
Type.getMethodDescriptor(Type.VOID_TYPE,
+                                                                     
Type.getType(Class.class), Type.getType(String[].class),
+                                                                     
Type.getType(Class[].class), Type.getType(byte[].class),
+                                                                     
Type.getType(Class.class), Type.getType(String.class),
+                                                                     
Type.getType(PersistenceCapable.class))));
 
-        code.vreturn();
-        code.calculateMaxStack();
 */
 
         // now add those instructions to the <clinit> method
@@ -3991,9 +4000,9 @@ public class PCEnhancer {
         }
         else {
             // add static initializer method if non exists
-            MethodNode clinit = new MethodNode(Opcodes.ACC_STATIC | 
Opcodes.ACC_FINAL,
+            MethodNode clinit = new MethodNode(Opcodes.ACC_STATIC,
                                                "<clinit>",
-                                               
Type.getMethodDescriptor(Type.VOID_TYPE),
+                                               "()V",
                                                null, null);
             clinit.instructions.add(new InsnNode(Opcodes.RETURN));
             classNode.methods.add(clinit);
@@ -4483,8 +4492,8 @@ public class PCEnhancer {
             // Reflection.getXXX(this, Reflection.findField(...));
 
             // Reflection.findField(declarer, fieldName, true);
-            instructions.add(new LdcInsnNode(Type.getType(declarer)));
-            instructions.add(new LdcInsnNode(fieldName));
+            instructions.add(AsmHelper.getLoadConstantInsn(declarer));
+            instructions.add(AsmHelper.getLoadConstantInsn(fieldName));
             instructions.add(new InsnNode(Opcodes.ICONST_1)); // true
             instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                                                 
Type.getInternalName(Reflection.class),
@@ -4615,8 +4624,8 @@ public class PCEnhancer {
         if (getRedefine() || getCreateSubclass()) {
             // Reflection.set(this, Reflection.findField(...), value);
             // Reflection.findField(declarer, fieldName, true);
-            instructions.add(new LdcInsnNode(Type.getType(declarer)));
-            instructions.add(new LdcInsnNode(fieldName));
+            instructions.add(AsmHelper.getLoadConstantInsn(declarer));
+            instructions.add(AsmHelper.getLoadConstantInsn(fieldName));
             instructions.add(new InsnNode(Opcodes.ICONST_1)); // true
             instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                                                 
Type.getInternalName(Reflection.class),
@@ -5214,7 +5223,7 @@ public class PCEnhancer {
             instructions.add(new InsnNode(Opcodes.ACONST_NULL));
         }
         else {
-            instructions.add(new LdcInsnNode(value));
+            instructions.add(AsmHelper.getLoadConstantInsn(value));
         }
 
         // if redefining, then we must always reflect (or access the field
@@ -5428,7 +5437,7 @@ public class PCEnhancer {
                                                PRE + 
"GetEnhancementContractVersion",
                                                
Type.getMethodDescriptor(Type.INT_TYPE),
                                                null, null);
-        methodNode.instructions.add(new LdcInsnNode(ENHANCER_VERSION));
+        
methodNode.instructions.add(AsmHelper.getLoadConstantInsn(ENHANCER_VERSION));
         methodNode.instructions.add(new InsnNode(Opcodes.IRETURN));
         cnt.getClassNode().methods.add(methodNode);
     }
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 2a23a01c0..b3783c818 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
@@ -30,6 +30,9 @@ import org.apache.xbean.asm9.Type;
 import org.apache.xbean.asm9.tree.AbstractInsnNode;
 import org.apache.xbean.asm9.tree.ClassNode;
 import org.apache.xbean.asm9.tree.FieldInsnNode;
+import org.apache.xbean.asm9.tree.InsnNode;
+import org.apache.xbean.asm9.tree.IntInsnNode;
+import org.apache.xbean.asm9.tree.LdcInsnNode;
 import org.apache.xbean.asm9.tree.VarInsnNode;
 
 import serp.bytecode.BCClass;
@@ -180,6 +183,77 @@ public final class AsmHelper {
         return Opcodes.ARETURN;
     }
 
+    public static AbstractInsnNode getLoadConstantInsn(Object val) {
+        if (val == null) {
+            return new InsnNode(Opcodes.ACONST_NULL);
+        }
+        if (val instanceof Integer) {
+            final int iVal = ((Integer) val).intValue();
+            switch (iVal) {
+                case 0:
+                    return new InsnNode(Opcodes.ICONST_0);
+                case 1:
+                    return new InsnNode(Opcodes.ICONST_1);
+                case 2:
+                    return new InsnNode(Opcodes.ICONST_2);
+                case 3:
+                    return new InsnNode(Opcodes.ICONST_3);
+                case 4:
+                    return new InsnNode(Opcodes.ICONST_4);
+                case 5:
+                    return new InsnNode(Opcodes.ICONST_5);
+                default:
+                    break;
+            }
+            if (iVal < 0 && iVal >= -128 || iVal >= 6 && iVal < 128) {
+                // use bipush for small numbers
+                return new IntInsnNode(Opcodes.BIPUSH, iVal);
+            }
+            else if (iVal < -128 && iVal >= -32768 || iVal >= 128 && iVal < 
32768) {
+                // use sipush for a bit bigger numbers
+                return new IntInsnNode(Opcodes.SIPUSH, iVal);
+            }
+        }
+
+        if (val instanceof Class) {
+            if (boolean.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Boolean.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (char.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Character.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (int.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Integer.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (long.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Long.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (byte.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Byte.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (short.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Short.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (float.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Float.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            if (double.class.equals(val)) {
+                return new FieldInsnNode(Opcodes.GETSTATIC, 
Type.getInternalName(Double.class), "TYPE",
+                                         Type.getDescriptor(Class.class));
+            }
+            return new LdcInsnNode(Type.getType((Class<?>) val));
+        }
+
+        return new LdcInsnNode(val);
+    }
+
     /**
      * Calclates the proper STORE instruction opcode for the given type
      *
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
index ff5423d56..87f28c265 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
@@ -69,6 +69,20 @@ public class SimpleEntity implements Serializable {
     public static final String NAMED_QUERY_WITH_POSITIONAL_PARAMS = 
"SelectWithPositionalParameter";
     public static final String NAMED_QUERY_WITH_NAMED_PARAMS = 
"SelectWithNamedParameter";
 
+    public static Integer dummy;
+
+    static {
+        dummy = -32766;
+        dummy = -32767;
+        dummy = -32768;
+        dummy = -32769;
+
+        dummy = 32765;
+        dummy = 32766;
+        dummy = 32767;
+        dummy = 32768;
+    }
+
     @Id
     @GeneratedValue
     @Column(name = "ID")

Reply via email to