From c09b1d3b0c064d53497f6490da7e191950f98204 Mon Sep 17 00:00:00 2001 From: michaeloffner Date: Mon, 9 Dec 2024 10:38:39 +0100 Subject: [PATCH] LDEV-5185 - add again caching for function members --- .../transformer/dynamic/DynamicInvoker.java | 35 ++-- .../dynamic/meta/dynamic/ClazzDynamic.java | 161 +++--------------- loader/build.xml | 2 +- loader/pom.xml | 2 +- 4 files changed, 50 insertions(+), 150 deletions(-) diff --git a/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java b/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java index 70e8a72ceb..b647beb8ae 100644 --- a/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java +++ b/core/src/main/java/lucee/transformer/dynamic/DynamicInvoker.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -30,6 +31,7 @@ import org.objectweb.asm.Type; import lucee.aprint; +import lucee.print; import lucee.commons.digest.HashUtil; import lucee.commons.io.SystemUtil; import lucee.commons.io.log.Log; @@ -253,6 +255,8 @@ public Pair createInstance(Class clazz, Key methodNam mv.visitVarInsn(Opcodes.ALOAD, 1); // Load the first method argument (instance) if (!fm.getDeclaringProviderClassWithSameAccess().equals(Object.class)) { // Only cast if clazz is not java.lang.Object mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(fm.getDeclaringProviderClassWithSameAccess())); + print.e("-->" + fm.getDeclaringProviderClassNameWithSameAccess()); + print.e("-->" + fm.getDeclaringProviderClassName()); } } } @@ -285,6 +289,7 @@ public Pair createInstance(Class clazz, Key methodNam if (argType.isPrimitive()) { Type type = Type.getType(argType); Class wrapperType = Reflector.toReferenceClass(argType); + mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(wrapperType)); // Cast to wrapper type mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(wrapperType), ASMUtil.getClassName(type) + "Value", "()" + ASMUtil.getDescriptor(type), false); // Unbox @@ -431,6 +436,12 @@ public static void main(String[] args) throws Exception { ResourceUtil.deleteContent(classes, null); DynamicInvoker e = new DynamicInvoker(classes); + HashMap map = new HashMap<>(); + map.put("aaa", "sss"); + Iterator it = map.keySet().iterator(); + // aprint.e(e.invokeInstanceMethod(it, "next", new Object[] {}, false)); + aprint.e(e.invokeInstanceMethod(it, "hasNext", new Object[] {}, false)); + if (false) { FileInputStream fis = new java.io.FileInputStream("/Users/mic/Tmp3/test.prop"); InputStreamReader fir = new java.io.InputStreamReader(fis, "UTF-8"); @@ -466,7 +477,7 @@ public static void main(String[] args) throws Exception { } - if (true) return; + // if (true) return; StringBuilder sb = new StringBuilder("Susi"); Test t = new Test(); @@ -508,7 +519,7 @@ public static void main(String[] args) throws Exception { // instance (double->int):String { Object reflection = t.test(134); - Object dynamic = e.invokeInstanceMethod(t, "test", new Object[] { 134D }, false); + Object dynamic = e.invokeInstanceMethod(t, "test", new Object[] { 134D }, true); if (!reflection.equals(dynamic)) { aprint.e("direct:"); aprint.e(reflection); @@ -520,7 +531,7 @@ public static void main(String[] args) throws Exception { // instance (double->int):String { Object reflection = t.test(134); - Object dynamic = e.invokeInstanceMethod(t, "test", new Object[] { 134D }, false); + Object dynamic = e.invokeInstanceMethod(t, "test", new Object[] { 134D }, true); if (!reflection.equals(dynamic)) { aprint.e("direct:"); aprint.e(reflection); @@ -530,23 +541,23 @@ public static void main(String[] args) throws Exception { } aprint.e(t.complete("", 1, null)); - aprint.e(e.invokeInstanceMethod(t, "complete", new Object[] { "", i, null }, false)); - aprint.e(e.invokeInstanceMethod(t, "complete", new Object[] { "", bd, null }, false)); + aprint.e(e.invokeInstanceMethod(t, "complete", new Object[] { "", i, null }, true)); + aprint.e(e.invokeInstanceMethod(t, "complete", new Object[] { "", bd, null }, true)); aprint.e(t.testb(true, true)); - aprint.e(e.invokeInstanceMethod(t, "testb", new Object[] { null, true }, false)); + aprint.e(e.invokeInstanceMethod(t, "testb", new Object[] { null, true }, true)); aprint.e(t.testStr(1, "string", 1L)); - aprint.e(e.invokeInstanceMethod(t, "testStr", new Object[] { "1", 1, Double.valueOf(1D) }, false)); + aprint.e(e.invokeInstanceMethod(t, "testStr", new Object[] { "1", 1, Double.valueOf(1D) }, true)); - aprint.e(e.invokeInstanceMethod(t, "test", new Object[] { "1" }, false)); - aprint.e(e.invokeInstanceMethod(t, "test", new Object[] { 1D }, false)); + aprint.e(e.invokeInstanceMethod(t, "test", new Object[] { "1" }, true)); + aprint.e(e.invokeInstanceMethod(t, "test", new Object[] { 1D }, true)); - aprint.e(e.invokeInstanceMethod(new SystemOut(), "setOut", new Object[] { null }, false)); + aprint.e(e.invokeInstanceMethod(new SystemOut(), "setOut", new Object[] { null }, true)); System.setProperty("a.b.c", "- value -"); aprint.e(e.invokeInstanceMethod(sb, "toSTring", new Object[] {}, false)); - aprint.e(e.invokeStaticMethod(SystemUtil.class, "getSystemPropOrEnvVar", new Object[] { "a.b.c", "default-value" }, false)); - aprint.e(e.invokeStaticMethod(ListUtil.class, "arrayToList", new Object[] { new String[] { "a", "b" }, "," }, false)); + aprint.e(e.invokeStaticMethod(SystemUtil.class, "getSystemPropOrEnvVar", new Object[] { "a.b.c", "default-value" }, true)); + aprint.e(e.invokeStaticMethod(ListUtil.class, "arrayToList", new Object[] { new String[] { "a", "b" }, "," }, true)); } diff --git a/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java b/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java index 48f3a7c583..e1382000fd 100644 --- a/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java +++ b/core/src/main/java/lucee/transformer/dynamic/meta/dynamic/ClazzDynamic.java @@ -27,7 +27,6 @@ import lucee.commons.digest.HashUtil; import lucee.commons.io.IOUtil; -import lucee.commons.io.SystemUtil; import lucee.commons.io.log.Log; import lucee.commons.io.res.Resource; import lucee.commons.lang.ExceptionUtil; @@ -187,10 +186,8 @@ public static String generateClassLoderId(Class clazz) { private ClazzDynamic(Class clazz, String clid, Log log) throws IOException { this.clazz = clazz; this.clid = clid; - LinkedHashMap members = new LinkedHashMap<>(); - _getFunctionMembers(clazz, members, log); - // _getFunctionMembers(final Class clazz, Map members, Log log) throws - // IOException { + Map members = _getFunctionMembers(clazz, null, log); + LinkedList tmpMethods = new LinkedList<>(); LinkedList tmpDeclaredMethods = new LinkedList<>(); LinkedList tmpConstructors = new LinkedList<>(); @@ -366,7 +363,19 @@ public List getDeclaredConstructors(int argumentLength) throws IOEx return list; } - private static void _getFunctionMembers(final Class clazz, Map members, Log log) throws IOException { + private static Map _getFunctionMembers(final Class clazz, Map membersInput, Log log) throws IOException { + + if (membersInput == null) membersInput = new LinkedHashMap<>(); + final Map members = membersInput; + + Map existing = membersCollection.get(clazz); + if (existing != null) { + for (Entry e: existing.entrySet()) { + members.put(e.getKey(), e.getValue()); + } + return members; + + } final String classPath = clazz.getName().replace('.', '/') + ".class"; final ClassLoader cl = getClassLoader(clazz); @@ -458,9 +467,8 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str Type tmpType = tmpClass != null ? Type.getType(tmpClass) : null; Type rtnType = rtnClass != null ? Type.getType(rtnClass) : null; - if (Clazz.compareAccess(fmParent, fmCurrent) >= 0) - ((FunctionMemberDynamic) fmCurrent).setDeclaringProviderClassWithSameAccess(tmpClass, tmpType, rtnClass, rtnType); - ((FunctionMemberDynamic) fmCurrent).setDeclaringProviderClass(tmpClass, tmpType, rtnClass, rtnType); + if (Clazz.compareAccess(fmParent, fmCurrent) >= 0) fmCurrent.setDeclaringProviderClassWithSameAccess(tmpClass, tmpType, rtnClass, rtnType); + fmCurrent.setDeclaringProviderClass(tmpClass, tmpType, rtnClass, rtnType); /* * if (name.equals("nextElement")) { print.e(fm.getDeclaringProviderClassName()); @@ -475,139 +483,20 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str }; // Start visiting the class classReader.accept(visitor, 0); - } - - private static Map> membersCollection = new IdentityHashMap<>(); - - private static LinkedHashMap _getFunctionMembersOld(final Class clazz, Log log) throws IOException { - - LinkedHashMap members = membersCollection.get(clazz); - if (members == null) { - synchronized (SystemUtil.createToken("ClazzDynamic", clazz.getName())) { - members = membersCollection.get(clazz); - if (members == null) { - LinkedHashMap tmpMembers = new LinkedHashMap<>(); - // Map members, - final String classPath = clazz.getName().replace('.', '/') + ".class"; - final ClassLoader cl = getClassLoader(clazz); - final RefInteger classAccess = new RefIntegerImpl(); - ClassReader classReader; - try { - // print.e("new:" + clazz); - classReader = new ClassReader(cl.getResourceAsStream(classPath)); - } - catch (IOException ioe) { - if ("Class not found".equals(ioe.getMessage())) { - IOException tmp = new IOException("unable to load class path [" + classPath + "]"); - ExceptionUtil.initCauseEL(tmp, ioe); - ioe = tmp; - } - throw ioe; - } - - // Create a ClassVisitor to visit the methods - ClassVisitor visitor = new ClassVisitor(Opcodes.ASM9) { - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - classAccess.setValue(access); - if (interfaces != null && interfaces.length > 0) { - for (String interf: interfaces) { - try { - add(tmpMembers, _getFunctionMembersOld(cl.loadClass(ASMUtil.getClassName(Type.getObjectType(interf))), log)); - } - catch (Exception e) { - if (log != null) log.error("dynamic", e); - } - } - } - if (superName != null) { - try { - add(tmpMembers, _getFunctionMembersOld(cl.loadClass(ASMUtil.getClassName(Type.getObjectType(superName))), log)); - } - catch (IllegalArgumentException iae) { - String v = ASMUtil.getJavaVersionFromException(iae, null); - if (v != null) { - throw new RuntimeException("The class [" + superName + "] was compiled with Java version [" + v + "], " - + "which is not supported by the current version of ASM. The highest supported version is [" - + ASMUtil.toStringVersionFromBytceodeVersion(ASMUtil.getMaxVersion(), "unknown") + "]. "); - - } - throw iae; - } - catch (RuntimeException re) { - throw re; - } - catch (Exception e) { - if (log != null) log.error("dynamic", e); - } - } - - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - FunctionMember fmCurrent = FunctionMemberDynamic.createInstance(clazz, name, access, descriptor, exceptions, classAccess.toInt()); - String id = Clazz.id(fmCurrent); - FunctionMember parent = tmpMembers.get(id); - if (parent instanceof FunctionMemberDynamic) { - FunctionMemberDynamic fmParent = (FunctionMemberDynamic) parent; - // java.lang.Appendable - - Class tmpClass = fmParent.getDeclaringProviderClass(true); - if (tmpClass != null) { - Class rtnClass = null; - if (fmParent instanceof Method) { - - Class tmpRtn = fmParent.getDeclaringProviderRtnClass(true); - rtnClass = tmpRtn; - } - - /* - * if (name.equals("toLocalDateTime")) { print.e("xxxxxxxxxxxxxxx"); print.e(clazz + ":" + name + - * ":" + descriptor); // print.e(Clazz.getAccessModifier(fmCurrent)); // - * print.e(Clazz.getAccessModifier(fmParent)); print.e("curr: " + - * Clazz.getAccessModifierAsString(fmCurrent)); print.e("parr: " + - * Clazz.getAccessModifierAsString(fmParent)); print.e("DeclaringClassName: " + - * fmCurrent.getDeclaringClassName()); print.e("getDeclaringProviderClassName: " + - * fmCurrent.getDeclaringProviderClassNameWithSameAccess()); // print.e("-----------------" + - * Clazz.compareAccess(fmd, fm)); } - */ - - Type tmpType = tmpClass != null ? Type.getType(tmpClass) : null; - Type rtnType = rtnClass != null ? Type.getType(rtnClass) : null; - - if (Clazz.compareAccess(fmParent, fmCurrent) >= 0) - ((FunctionMemberDynamic) fmCurrent).setDeclaringProviderClassWithSameAccess(tmpClass, tmpType, rtnClass, rtnType); - ((FunctionMemberDynamic) fmCurrent).setDeclaringProviderClass(tmpClass, tmpType, rtnClass, rtnType); - - /* - * if (name.equals("nextElement")) { print.e(fm.getDeclaringProviderClassName()); - * print.e(fm.getDeclaringProviderClassNameWithSameAccess()); } - */ - } - } - tmpMembers.put(id, fmCurrent); - - return super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - // Start visiting the class - classReader.accept(visitor, 0); - membersCollection.put(clazz, members = tmpMembers); - } - } - } + membersCollection.put(clazz, cloneIt(members)); return members; } - private static void add(LinkedHashMap members, LinkedHashMap rtn) { - for (Entry e: rtn.entrySet()) { - members.put(e.getKey(), e.getValue()); + private static Map cloneIt(Map members) { + Map cloned = new LinkedHashMap<>(); + for (Entry e: members.entrySet()) { + cloned.put(e.getKey(), e.getValue()); } + return cloned; } + private static Map> membersCollection = new IdentityHashMap<>(); + public static void serialize(Serializable o, OutputStream os) throws IOException { ObjectOutputStream oos = null; try { diff --git a/loader/build.xml b/loader/build.xml index 99e78e2e53..7a62f99a87 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index a206827e7d..063a2e0884 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.2.0.190-SNAPSHOT + 6.2.0.191-SNAPSHOT jar Lucee Loader Build