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 f1993f14628580737bfa0f4b46238d2c72ccee43 Author: Mark Struberg <strub...@apache.org> AuthorDate: Mon Jul 24 11:28:37 2023 +0200 OPENJPA-2911 timeout via ASM --- .../datacache/DataCachePCDataGenerator.java | 118 +++++++-------------- 1 file changed, 41 insertions(+), 77 deletions(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataGenerator.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataGenerator.java index 3dd0ae3f2..0f881fe83 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataGenerator.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataGenerator.java @@ -27,7 +27,6 @@ import org.apache.openjpa.enhance.PCDataGenerator; import org.apache.openjpa.kernel.AbstractPCData; import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.kernel.StoreContext; -import org.apache.openjpa.lib.util.StringUtil; import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.JavaTypes; @@ -38,6 +37,7 @@ import org.apache.xbean.asm9.Opcodes; import org.apache.xbean.asm9.Type; import org.apache.xbean.asm9.tree.ClassNode; import org.apache.xbean.asm9.tree.FieldInsnNode; +import org.apache.xbean.asm9.tree.FieldNode; import org.apache.xbean.asm9.tree.InsnList; import org.apache.xbean.asm9.tree.InsnNode; import org.apache.xbean.asm9.tree.JumpInsnNode; @@ -47,14 +47,6 @@ import org.apache.xbean.asm9.tree.MethodNode; import org.apache.xbean.asm9.tree.TypeInsnNode; import org.apache.xbean.asm9.tree.VarInsnNode; -import serp.bytecode.BCClass; -import serp.bytecode.BCField; -import serp.bytecode.BCMethod; -import serp.bytecode.Code; -import serp.bytecode.Instruction; -import serp.bytecode.JumpInstruction; -import serp.bytecode.Project; - /** * A {@link PCDataGenerator} instance which generates properly * synchronized instances suitable for use in the cache. In addition, @@ -97,14 +89,16 @@ public class DataCachePCDataGenerator extends PCDataGenerator { enhanceToNestedData(cnt); replaceNewEmbeddedPCData(cnt); addSynchronization(cnt); + addTimeout(cnt); //X TODO REMOVE +/* BCClass _bc = new Project().loadClass(cnt.getClassNode().name.replace("/", ".")); AsmHelper.readIntoBCClass(cnt, _bc); - addTimeout(_bc); cnt.setClassNode(AsmHelper.toClassNode(cnt.getProject(), _bc).getClassNode()); +*/ } private void enhanceToData(ClassNodeTracker cnt) { @@ -246,80 +240,50 @@ public class DataCachePCDataGenerator extends PCDataGenerator { instructions.add(new InsnNode(Opcodes.ARETURN)); } - /** - * Add a bean field of the given name and type. - */ - @Deprecated - private BCField addBeanField(BCClass bc, String name, Class type) { - if (name == null) - throw new IllegalArgumentException("name == null"); - - // private <type> <name> - BCField field = bc.declareField(name, type); - field.setAccessFlags(getFieldAccess()); - name = StringUtil.capitalize(name); - - // getter - String prefix = (type == boolean.class) ? "is" : "get"; - BCMethod method = bc.declareMethod(prefix + name, type, null); - method.makePublic(); - Code code = method.getCode(true); - code.aload().setThis(); - code.getfield().setField(field); - code.xreturn().setType(type); - code.calculateMaxStack(); - code.calculateMaxLocals(); - - // setter - method = bc.declareMethod("set" + name, void.class, - new Class[]{ type }); - method.makePublic(); - code = method.getCode(true); - code.aload().setThis(); - code.xload().setParam(0).setType(type); - code.putfield().setField(field); - code.vreturn(); - code.calculateMaxStack(); - code.calculateMaxLocals(); - return field; - } + private void addTimeout(ClassNodeTracker cnt) { + cnt.declareInterface(DataCachePCData.class); + cnt.declareInterface(Timed.class); + + FieldNode field = addBeanField(cnt, "timeout", long.class); - private void addTimeout(BCClass bc) { - bc.declareInterface(DataCachePCData.class); - bc.declareInterface(Timed.class); + + ClassNode classNode = cnt.getClassNode(); // public boolean isTimedOut (); - BCField field = addBeanField(bc, "timeout", long.class); - BCMethod meth = bc.declareMethod("isTimedOut", boolean.class, null); - Code code = meth.getCode(true); - - // if (timeout == -1) ... - code.aload().setThis(); - code.getfield().setField(field); - code.constant().setValue(-1L); - code.lcmp(); - JumpInstruction ifneg = code.ifeq(); - - // if (timeout >= System.currentTimeMillis ()) - code.aload().setThis(); - code.getfield().setField(field); - code.invokestatic().setMethod(System.class, "currentTimeMillis", - long.class, null); - code.lcmp(); - JumpInstruction ifnexp = code.ifge(); + MethodNode meth = new MethodNode(Opcodes.ACC_PUBLIC, + "isTimedOut", + Type.getMethodDescriptor(Type.BOOLEAN_TYPE), + null, null); + classNode.methods.add(meth); + final InsnList instructions = meth.instructions; + + // if (timeout != -1 ... + instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this + instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, field.name, field.desc)); + instructions.add(AsmHelper.getLoadConstantInsn(-1L)); + instructions.add(new InsnNode(Opcodes.LCMP)); + + LabelNode lblEndIf = new LabelNode(); + instructions.add(new JumpInsnNode(Opcodes.IFEQ, lblEndIf)); + + // ... && timeout < System.currentTimeMillis ()) + instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this + instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, field.name, field.desc)); + instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, + Type.getInternalName(System.class), + "currentTimeMillis", + Type.getMethodDescriptor(Type.LONG_TYPE))); + instructions.add(new InsnNode(Opcodes.LCMP)); + instructions.add(new JumpInsnNode(Opcodes.IFGE, lblEndIf)); // return true; - code.constant().setValue(1); + instructions.add(new InsnNode(Opcodes.ICONST_1)); + instructions.add(new InsnNode(Opcodes.IRETURN)); // ... else return false; - JumpInstruction go2 = code.go2(); - Instruction flse = code.constant().setValue(0); - ifneg.setTarget(flse); - ifnexp.setTarget(flse); - go2.setTarget(code.ireturn()); - - code.calculateMaxStack(); - code.calculateMaxLocals(); + instructions.add(lblEndIf); + instructions.add(new InsnNode(Opcodes.ICONST_0)); + instructions.add(new InsnNode(Opcodes.IRETURN)); } private void addSynchronization(ClassNodeTracker cnt) {