You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2022/12/14 01:38:13 UTC

[groovy] branch GROOVY_4_0_X updated: Compute the max stack size and the max number of local variables automatically

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

sunlan pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new 6ebb2ec990 Compute the max stack size and the max number of local variables automatically
6ebb2ec990 is described below

commit 6ebb2ec990c7ae66a87f1f9c11d57eef07093f15
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Dec 14 09:33:23 2022 +0800

    Compute the max stack size and the max number of local variables automatically
    
    (cherry picked from commit d7fa923bed20945074a41c54cce5133cc2ab63a0)
---
 .../groovy/classgen/AsmClassGenerator.java         |  6 +-
 .../groovy/classgen/asm/CallSiteWriter.java        | 74 +++++++++++-----------
 .../groovy/runtime/ProxyGeneratorAdapter.java      | 26 +++-----
 .../java/org/codehaus/groovy/ant/VerifyClass.java  |  2 +-
 4 files changed, 51 insertions(+), 57 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 2999348420..0f2af490a4 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -1509,7 +1509,7 @@ public class AsmClassGenerator extends ClassGenerator {
             mv.visitFieldInsn(PUTSTATIC,controller.getInternalClassName(),staticFieldName,"Ljava/lang/Class;");
             mv.visitLabel(l0);
             mv.visitInsn(ARETURN);
-            mv.visitMaxs(0,0);
+            mv.visitMaxs(0, 0);
             mv.visitEnd();
         }
 
@@ -1531,7 +1531,7 @@ public class AsmClassGenerator extends ClassGenerator {
         mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V", false);
         mv.visitInsn(ATHROW);
         mv.visitTryCatchBlock(l0, l2, l2, "java/lang/ClassNotFoundException"); // br using l2 as the 2nd param seems create the right table entry
-        mv.visitMaxs(3, 2);
+        mv.visitMaxs(0, 0);
     }
 
     @Override
@@ -1951,7 +1951,7 @@ public class AsmClassGenerator extends ClassGenerator {
                     }
                     operandStack.remove(methodBlockSize);
                     mv.visitInsn(RETURN);
-                    mv.visitMaxs(0,0);
+                    mv.visitMaxs(0, 0);
                     mv.visitEnd();
                 }
                 mv = oldMv;
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/CallSiteWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/CallSiteWriter.java
index 5d49885fed..9f8b3fc278 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/CallSiteWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/CallSiteWriter.java
@@ -165,58 +165,58 @@ public class CallSiteWriter {
         mv.visitEnd();
     }
 
-    private void generateCreateCallSiteArray() { 
-        List<String> callSiteInitMethods = new LinkedList<String>(); 
-        int index = 0; 
-        int methodIndex = 0; 
-        final int size = callSites.size(); 
-        final int maxArrayInit = 5000; 
+    private void generateCreateCallSiteArray() {
+        List<String> callSiteInitMethods = new LinkedList<String>();
+        int index = 0;
+        int methodIndex = 0;
+        final int size = callSites.size();
+        final int maxArrayInit = 5000;
         // create array initialization methods
-        while (index < size) { 
-            methodIndex++; 
-            String methodName = "$createCallSiteArray_" + methodIndex; 
-            callSiteInitMethods.add(methodName); 
+        while (index < size) {
+            methodIndex++;
+            String methodName = "$createCallSiteArray_" + methodIndex;
+            callSiteInitMethods.add(methodName);
             MethodVisitor mv = controller.getClassVisitor().visitMethod(MOD_PRIVSS, methodName, "([Ljava/lang/String;)V", null, null);
             controller.setMethodVisitor(mv);
-            mv.visitCode(); 
-            int methodLimit = size; 
+            mv.visitCode();
+            int methodLimit = size;
             // check if the next block is over the max allowed
-            if ((methodLimit - index) > maxArrayInit) { 
-                methodLimit = index + maxArrayInit; 
-            } 
-            for (; index < methodLimit; index++) { 
-                mv.visitVarInsn(ALOAD, 0); 
-                mv.visitLdcInsn(index); 
-                mv.visitLdcInsn(callSites.get(index)); 
-                mv.visitInsn(AASTORE); 
-            } 
-            mv.visitInsn(RETURN); 
-            mv.visitMaxs(2,1); 
-            mv.visitEnd(); 
+            if ((methodLimit - index) > maxArrayInit) {
+                methodLimit = index + maxArrayInit;
+            }
+            for (; index < methodLimit; index++) {
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitLdcInsn(index);
+                mv.visitLdcInsn(callSites.get(index));
+                mv.visitInsn(AASTORE);
+            }
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
         }
         // create base createCallSiteArray method
         MethodVisitor mv = controller.getClassVisitor().visitMethod(MOD_PRIVSS, CREATE_CSA_METHOD, GET_CALLSITEARRAY_DESC, null, null);
         controller.setMethodVisitor(mv);
-        mv.visitCode(); 
-        mv.visitLdcInsn(size); 
-        mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); 
-        mv.visitVarInsn(ASTORE, 0); 
-        for (String methodName : callSiteInitMethods) { 
+        mv.visitCode();
+        mv.visitLdcInsn(size);
+        mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+        mv.visitVarInsn(ASTORE, 0);
+        for (String methodName : callSiteInitMethods) {
             mv.visitVarInsn(ALOAD, 0);
             mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), methodName, "([Ljava/lang/String;)V", false);
-        } 
+        }
 
-        mv.visitTypeInsn(NEW, CALLSITE_ARRAY_CLASS); 
-        mv.visitInsn(DUP); 
-        controller.getAcg().visitClassExpression(new ClassExpression(controller.getClassNode())); 
+        mv.visitTypeInsn(NEW, CALLSITE_ARRAY_CLASS);
+        mv.visitInsn(DUP);
+        controller.getAcg().visitClassExpression(new ClassExpression(controller.getClassNode()));
 
         mv.visitVarInsn(ALOAD, 0);
 
         mv.visitMethodInsn(INVOKESPECIAL, CALLSITE_ARRAY_CLASS, "<init>", "(Ljava/lang/Class;[Ljava/lang/String;)V", false);
-        mv.visitInsn(ARETURN); 
-        mv.visitMaxs(0,0); 
-        mv.visitEnd(); 
-    } 
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
 
     private int allocateIndex(String name) {
         callSites.add(name);
diff --git a/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
index 5ad0015bf4..cf805f4531 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java
@@ -125,8 +125,8 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
     private static final String DELEGATE_OBJECT_FIELD = "$delegate";
     private static final AtomicLong proxyCounter = new AtomicLong();
 
-    private static List<Method> OBJECT_METHODS = getInheritedMethods(Object.class, new ArrayList<>());
-    private static List<Method> GROOVYOBJECT_METHODS = getInheritedMethods(GroovyObject.class, new ArrayList<>());
+    private static final List<Method> OBJECT_METHODS = getInheritedMethods(Object.class, new ArrayList<>());
+    private static final List<Method> GROOVYOBJECT_METHODS = getInheritedMethods(GroovyObject.class, new ArrayList<>());
     private static final Set<String> GROOVYOBJECT_METHOD_NAMES;
     static {
         Set<String> names = new HashSet<>();
@@ -463,7 +463,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
             mv.visitVarInsn(ALOAD, 0);
             mv.visitFieldInsn(GETFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;");
             mv.visitInsn(ARETURN);
-            mv.visitMaxs(2, 1);
+            mv.visitMaxs(0, 0);
             mv.visitEnd();
         }
 
@@ -481,7 +481,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
             mv.visitInsn(RETURN);
             Label l2 = new Label();
             mv.visitLabel(l2);
-            mv.visitMaxs(2, 2);
+            mv.visitMaxs(0, 0);
             mv.visitEnd();
         }
     }
@@ -552,7 +552,6 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
         } else if (Modifier.isAbstract(access) && !GROOVYOBJECT_METHOD_NAMES.contains(name) && !isImplemented(superClass, name, desc)) {
             MethodVisitor mv = super.visitMethod(access & ~ACC_ABSTRACT, name, desc, signature, exceptions);
             mv.visitCode();
-            Type[] args = Type.getArgumentTypes(desc);
             if (emptyBody) {
                 Type returnType = Type.getReturnType(desc);
                 if (returnType == Type.VOID_TYPE) {
@@ -576,7 +575,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
                             mv.visitInsn(ACONST_NULL);
                     }
                     mv.visitInsn(getReturnInsn(returnType));
-                    mv.visitMaxs(2, registerLen(args) + 1);
+                    mv.visitMaxs(0, 0);
                 }
             } else {
                 // for compatibility with the legacy proxy generator, we should throw an UnsupportedOperationException
@@ -585,7 +584,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
                 mv.visitInsn(DUP);
                 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "()V", false);
                 mv.visitInsn(ATHROW);
-                mv.visitMaxs(2, registerLen(args) + 1);
+                mv.visitMaxs(0, 0);
             }
             mv.visitEnd();
         }
@@ -599,7 +598,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
         mv.visitIntInsn(ALOAD, 0);
         mv.visitFieldInsn(GETFIELD, proxyName, DELEGATE_OBJECT_FIELD, BytecodeHelper.getTypeDescription(delegateClass));
         mv.visitInsn(ARETURN);
-        mv.visitMaxs(1, 1);
+        mv.visitMaxs(0, 0);
         mv.visitEnd();
         return null;
     }
@@ -645,8 +644,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
         }
         mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", desc, false);
         mv.visitInsn(RETURN);
-        int max = idx + 1 + (generateDelegateField ? 1 : 0);
-        mv.visitMaxs(max, max);
+        mv.visitMaxs(0, 0);
         mv.visitEnd();
         return null;
     }
@@ -703,7 +701,7 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
         }
         mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
         unwrapResult(mv, desc);
-        mv.visitMaxs(size, registerLen(args) + 1);
+        mv.visitMaxs(0, 0);
 
         return mv;
     }
@@ -713,14 +711,12 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
 //        TraceMethodVisitor tmv = new TraceMethodVisitor(mv);
 //        mv = tmv;
         mv.visitCode();
-        int stackSize = 0;
         // method body should be:
         //  this.$delegate$closure$methodName.call(new Object[] { method arguments })
         Type[] args = Type.getArgumentTypes(desc);
         int arrayStore = args.length + 1;
         BytecodeHelper.pushConstant(mv, args.length);
         mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); // stack size = 1
-        stackSize = 1;
         int idx = 1;
         for (int i = 0; i < args.length; i++) {
             Type arg = args[i];
@@ -729,7 +725,6 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
             // primitive types must be boxed
             boxPrimitiveType(mv, idx, arg);
             idx += registerLen(arg);
-            stackSize = Math.max(4, 3 + registerLen(arg));
             mv.visitInsn(AASTORE); // store value into array
         }
         mv.visitVarInsn(ASTORE, arrayStore); // store array
@@ -753,10 +748,9 @@ public class ProxyGeneratorAdapter extends ClassVisitor {
         mv.visitVarInsn(ALOAD, arrayStore);
         mv.visitMethodInsn(INVOKESTATIC, BytecodeHelper.getClassInternalName(this.getClass()), "ensureClosure", "(Ljava/lang/Object;)Lgroovy/lang/Closure;", false);
         mv.visitVarInsn(ALOAD, arrayIndex); // load argument array
-        stackSize++;
         mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Closure", "call", "([Ljava/lang/Object;)Ljava/lang/Object;", false); // call closure
         unwrapResult(mv, desc);
-        mv.visitMaxs(stackSize, arrayStore + 1);
+        mv.visitMaxs(0, 0);
         mv.visitEnd();
 //        System.out.println("tmv.getText() = " + tmv.getText());
         return null;
diff --git a/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/VerifyClass.java b/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/VerifyClass.java
index 63fbca926d..9bf81a1187 100644
--- a/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/VerifyClass.java
+++ b/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/VerifyClass.java
@@ -138,7 +138,7 @@ public class VerifyClass extends MatchingTask {
                         mv.visitLabel(null);
                     }
                 }
-                mv.visitMaxs(method.maxStack, method.maxLocals);
+                mv.visitMaxs(0, 0);
             }
         }
         return !failed;