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

emilles pushed a commit to branch GROOVY-11360
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 31eb3d942cde7d5425b9ef86fd3afe1f849ca5bb
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Mon Apr 21 10:37:34 2025 -0500

    GROOVY-11630: optimize void groovy method return in expression statement
---
 .../codehaus/groovy/classgen/AsmClassGenerator.java   |  8 ++++++--
 .../groovy/classgen/asm/BinaryExpressionHelper.java   |  4 ++--
 .../asm/BinaryExpressionMultiTypeDispatcher.java      |  2 +-
 .../groovy/classgen/asm/InvocationWriter.java         |  2 +-
 .../codehaus/groovy/classgen/asm/StatementWriter.java |  8 +++-----
 .../classgen/asm/sc/StaticInvocationWriter.java       |  5 ++++-
 ...taticTypesBinaryExpressionMultiTypeDispatcher.java |  3 ++-
 .../classgen/asm/sc/StaticCompilationTest.groovy      | 19 +++++++++++++++++++
 8 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java 
b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 10564ecfcc..3dfb93b596 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -264,10 +264,14 @@ public class AsmClassGenerator extends ClassGenerator {
 
     private final Map<String,ClassNode> referencedClasses = new HashMap<>();
 
+    /**
+     * Add marker in the bytecode to show source-bytecode relationship.
+     */
+    public static final boolean ASM_DEBUG = false;
     public static final boolean CREATE_DEBUG_INFO = true;
     public static final boolean CREATE_LINE_NUMBER_INFO = true;
-    public static final boolean ASM_DEBUG = false; // add marker in the 
bytecode to show source-bytecode relationship
-    public static final String MINIMUM_BYTECODE_VERSION = 
"_MINIMUM_BYTECODE_VERSION";
+    public static final String  ELIDE_EXPRESSION_VALUE = "_EXPR_VALUE_UNUSED";
+    public static final String  MINIMUM_BYTECODE_VERSION = 
"_MINIMUM_BYTECODE_VERSION";
 
     private WriterController controller;
     private ASTNode currentASTNode;
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
index 341938b2fd..041f257d37 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
@@ -376,7 +376,7 @@ public class BinaryExpressionHelper {
         controller.getInvocationWriter().makeCall(parent, receiver, 
constX("putAt"), args(index, rhsValueLoader), InvocationWriter.invokeMethod, 
safe, false, false);
         controller.getOperandStack().pop(); // method return value
 
-        if (!Boolean.TRUE.equals(parent.getNodeMetaData("GROOVY-11288")))
+        if 
(!Boolean.TRUE.equals(parent.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE)))
             rhsValueLoader.visit(controller.getAcg()); // assignment 
expression value
     }
 
@@ -401,7 +401,7 @@ public class BinaryExpressionHelper {
         Expression rightExpression = expression.getRightExpression();
         boolean singleAssignment = !(leftExpression instanceof 
TupleExpression);
         boolean directAssignment = defineVariable && singleAssignment; //def 
x=y
-        boolean returnRightValue = 
!Boolean.TRUE.equals(expression.getNodeMetaData("GROOVY-11288"));
+        boolean returnRightValue = 
!Boolean.TRUE.equals(expression.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE));
 
         // TODO: LHS has not been visited -- it could be a variable in a 
closure and type chooser is not aware.
         ClassNode lhsType = 
controller.getTypeChooser().resolveType(leftExpression, 
controller.getClassNode());
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionMultiTypeDispatcher.java
 
b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionMultiTypeDispatcher.java
index e57392abe5..f7a9c3906f 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionMultiTypeDispatcher.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionMultiTypeDispatcher.java
@@ -380,7 +380,7 @@ public class BinaryExpressionMultiTypeDispatcher extends 
BinaryExpressionHelper
             // update operand stack
             operandStack.remove(3);
 
-            if (!Boolean.TRUE.equals(orig.getNodeMetaData("GROOVY-11288")))
+            if 
(!Boolean.TRUE.equals(orig.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE)))
                 rhsValueLoader.visit(asmGenerator); // re-load result value
         } else {
             super.assignToArray(orig, receiver, index, rhsValueLoader, safe);
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
index 32d1981085..8e576c4e2e 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
@@ -238,7 +238,7 @@ public class InvocationWriter {
         operandStack.remove(operandStack.getStackLength() - startDepth); // 
receiver plus argument(s)
 
         if (isPrimitiveVoid(returnType)) {
-            if (currentCall != null && 
currentCall.getNodeMetaData("GROOVY-11286") != null) {
+            if (currentCall != null && 
currentCall.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE) != null) {
                 return true; // do not load value
             }
             returnType = ClassHelper.OBJECT_TYPE;
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
index eb9f08000a..0749aad049 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
@@ -48,6 +48,7 @@ import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
 import org.codehaus.groovy.ast.stmt.ThrowStatement;
 import org.codehaus.groovy.ast.stmt.TryCatchStatement;
 import org.codehaus.groovy.ast.stmt.WhileStatement;
+import org.codehaus.groovy.classgen.AsmClassGenerator;
 import org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
@@ -632,11 +633,8 @@ public class StatementWriter {
         controller.getAcg().onLineNumber(statement, "visitExpressionStatement: 
" + expression.getClass().getName());
         writeStatementLabel(statement);
 
-        // TODO: replace with better metadata
-        if (expression instanceof MethodCall)
-            expression.putNodeMetaData("GROOVY-11286", Boolean.TRUE);
-        if (expression instanceof BinaryExpression)
-            expression.putNodeMetaData("GROOVY-11288", Boolean.TRUE);
+        if (expression instanceof MethodCall || expression instanceof 
BinaryExpression)
+            
expression.putNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE, 
Boolean.TRUE);
 
         var operandStack = controller.getOperandStack();
         int mark = operandStack.getStackLength();
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index 7d0929ada6..68cbee26d4 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -288,6 +288,9 @@ public class StaticInvocationWriter extends 
InvocationWriter {
             controller.getOperandStack().remove(argumentList.size());
 
             if (isPrimitiveVoid(returnType)) {
+                if (currentCall != null && 
currentCall.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE) != null) {
+                    return true; // do not load value
+                }
                 returnType = ClassHelper.OBJECT_TYPE;
                 mv.visitInsn(ACONST_NULL);
             }
@@ -490,7 +493,7 @@ public class StaticInvocationWriter extends 
InvocationWriter {
             Label allDone = new Label();
             MethodVisitor mv = controller.getMethodVisitor();
             OperandStack operandStack = controller.getOperandStack();
-            boolean produceResultList = origin.getNodeMetaData("GROOVY-11286") 
== null;
+            boolean produceResultList = 
origin.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE) == null;
 
             // if (receiver == null)
             tmpReceiver.visit(controller.getAcg());
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
index eadb847bbe..0bf878ed4f 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
@@ -64,6 +64,7 @@ import static 
org.codehaus.groovy.ast.tools.GeneralUtils.isOrImplements;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+import static 
org.codehaus.groovy.classgen.AsmClassGenerator.ELIDE_EXPRESSION_VALUE;
 import static 
org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PRIVATE_FIELDS_MUTATORS;
 import static 
org.codehaus.groovy.transform.sc.StaticCompilationVisitor.ARRAYLIST_ADD_METHOD;
 import static 
org.codehaus.groovy.transform.sc.StaticCompilationVisitor.ARRAYLIST_CLASSNODE;
@@ -342,7 +343,7 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher 
extends BinaryExpres
             call.visit(controller.getAcg());
             controller.getOperandStack().pop(); // method return value
 
-            if 
(!Boolean.TRUE.equals(enclosing.getNodeMetaData("GROOVY-11288")))
+            if 
(!Boolean.TRUE.equals(enclosing.getNodeMetaData(ELIDE_EXPRESSION_VALUE)))
                 rhsValueLoader.visit(controller.getAcg()); // assignment 
expression value
         }
     }
diff --git 
a/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
 
b/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
index 453bd0490d..9ce34e2c50 100644
--- 
a/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
+++ 
b/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
@@ -430,6 +430,25 @@ final class StaticCompilationTest extends 
AbstractBytecodeTestCase {
             ])
     }
 
+    // GROOVY-11630
+    void testVoidMethod5() {
+        assert compile(method: 'm', '''@groovy.transform.CompileStatic
+            void m() {
+                def list = [1,2,3]
+                list.shuffle()
+            }
+        ''').hasStrictSequence([
+                'L1',
+                'LINENUMBER 4 L1',
+                'ALOAD 1',
+                'INVOKESTATIC 
org/codehaus/groovy/runtime/DefaultGroovyMethods.shuffle (Ljava/util/List;)V',
+                // drop: ACONST_NULL, POP
+                'L2',
+                'LINENUMBER 5 L2',
+                'RETURN'
+            ])
+    }
+
     void testIntLeftShift() {
         assert compile(method: 'm', '''@groovy.transform.CompileStatic
             void m() {

Reply via email to