Skip to content

Commit 31eb3d9

Browse files
committed
GROOVY-11630: optimize void groovy method return in expression statement
1 parent 840e57a commit 31eb3d9

8 files changed

Lines changed: 38 additions & 13 deletions

File tree

src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,14 @@ public class AsmClassGenerator extends ClassGenerator {
264264

265265
private final Map<String,ClassNode> referencedClasses = new HashMap<>();
266266

267+
/**
268+
* Add marker in the bytecode to show source-bytecode relationship.
269+
*/
270+
public static final boolean ASM_DEBUG = false;
267271
public static final boolean CREATE_DEBUG_INFO = true;
268272
public static final boolean CREATE_LINE_NUMBER_INFO = true;
269-
public static final boolean ASM_DEBUG = false; // add marker in the bytecode to show source-bytecode relationship
270-
public static final String MINIMUM_BYTECODE_VERSION = "_MINIMUM_BYTECODE_VERSION";
273+
public static final String ELIDE_EXPRESSION_VALUE = "_EXPR_VALUE_UNUSED";
274+
public static final String MINIMUM_BYTECODE_VERSION = "_MINIMUM_BYTECODE_VERSION";
271275

272276
private WriterController controller;
273277
private ASTNode currentASTNode;

src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ protected void assignToArray(final Expression parent, final Expression receiver,
376376
controller.getInvocationWriter().makeCall(parent, receiver, constX("putAt"), args(index, rhsValueLoader), InvocationWriter.invokeMethod, safe, false, false);
377377
controller.getOperandStack().pop(); // method return value
378378

379-
if (!Boolean.TRUE.equals(parent.getNodeMetaData("GROOVY-11288")))
379+
if (!Boolean.TRUE.equals(parent.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE)))
380380
rhsValueLoader.visit(controller.getAcg()); // assignment expression value
381381
}
382382

@@ -401,7 +401,7 @@ public void evaluateEqual(final BinaryExpression expression, final boolean defin
401401
Expression rightExpression = expression.getRightExpression();
402402
boolean singleAssignment = !(leftExpression instanceof TupleExpression);
403403
boolean directAssignment = defineVariable && singleAssignment; //def x=y
404-
boolean returnRightValue = !Boolean.TRUE.equals(expression.getNodeMetaData("GROOVY-11288"));
404+
boolean returnRightValue = !Boolean.TRUE.equals(expression.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE));
405405

406406
// TODO: LHS has not been visited -- it could be a variable in a closure and type chooser is not aware.
407407
ClassNode lhsType = controller.getTypeChooser().resolveType(leftExpression, controller.getClassNode());

src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionMultiTypeDispatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ protected void assignToArray(final Expression orig, final Expression receiver, f
380380
// update operand stack
381381
operandStack.remove(3);
382382

383-
if (!Boolean.TRUE.equals(orig.getNodeMetaData("GROOVY-11288")))
383+
if (!Boolean.TRUE.equals(orig.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE)))
384384
rhsValueLoader.visit(asmGenerator); // re-load result value
385385
} else {
386386
super.assignToArray(orig, receiver, index, rhsValueLoader, safe);

src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ protected boolean writeDirectMethodCall(final MethodNode target, final boolean i
238238
operandStack.remove(operandStack.getStackLength() - startDepth); // receiver plus argument(s)
239239

240240
if (isPrimitiveVoid(returnType)) {
241-
if (currentCall != null && currentCall.getNodeMetaData("GROOVY-11286") != null) {
241+
if (currentCall != null && currentCall.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE) != null) {
242242
return true; // do not load value
243243
}
244244
returnType = ClassHelper.OBJECT_TYPE;

src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.codehaus.groovy.ast.stmt.ThrowStatement;
4949
import org.codehaus.groovy.ast.stmt.TryCatchStatement;
5050
import org.codehaus.groovy.ast.stmt.WhileStatement;
51+
import org.codehaus.groovy.classgen.AsmClassGenerator;
5152
import org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder;
5253
import org.objectweb.asm.Label;
5354
import org.objectweb.asm.MethodVisitor;
@@ -632,11 +633,8 @@ public void writeExpressionStatement(final ExpressionStatement statement) {
632633
controller.getAcg().onLineNumber(statement, "visitExpressionStatement: " + expression.getClass().getName());
633634
writeStatementLabel(statement);
634635

635-
// TODO: replace with better metadata
636-
if (expression instanceof MethodCall)
637-
expression.putNodeMetaData("GROOVY-11286", Boolean.TRUE);
638-
if (expression instanceof BinaryExpression)
639-
expression.putNodeMetaData("GROOVY-11288", Boolean.TRUE);
636+
if (expression instanceof MethodCall || expression instanceof BinaryExpression)
637+
expression.putNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE, Boolean.TRUE);
640638

641639
var operandStack = controller.getOperandStack();
642640
int mark = operandStack.getStackLength();

src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ protected boolean writeDirectMethodCall(final MethodNode target, final boolean i
288288
controller.getOperandStack().remove(argumentList.size());
289289

290290
if (isPrimitiveVoid(returnType)) {
291+
if (currentCall != null && currentCall.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE) != null) {
292+
return true; // do not load value
293+
}
291294
returnType = ClassHelper.OBJECT_TYPE;
292295
mv.visitInsn(ACONST_NULL);
293296
}
@@ -490,7 +493,7 @@ public void makeCall(final Expression origin, final Expression receiver, final E
490493
Label allDone = new Label();
491494
MethodVisitor mv = controller.getMethodVisitor();
492495
OperandStack operandStack = controller.getOperandStack();
493-
boolean produceResultList = origin.getNodeMetaData("GROOVY-11286") == null;
496+
boolean produceResultList = origin.getNodeMetaData(AsmClassGenerator.ELIDE_EXPRESSION_VALUE) == null;
494497

495498
// if (receiver == null)
496499
tmpReceiver.visit(controller.getAcg());

src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
6565
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
6666
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
67+
import static org.codehaus.groovy.classgen.AsmClassGenerator.ELIDE_EXPRESSION_VALUE;
6768
import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PRIVATE_FIELDS_MUTATORS;
6869
import static org.codehaus.groovy.transform.sc.StaticCompilationVisitor.ARRAYLIST_ADD_METHOD;
6970
import static org.codehaus.groovy.transform.sc.StaticCompilationVisitor.ARRAYLIST_CLASSNODE;
@@ -342,7 +343,7 @@ protected void assignToArray(final Expression enclosing, final Expression receiv
342343
call.visit(controller.getAcg());
343344
controller.getOperandStack().pop(); // method return value
344345

345-
if (!Boolean.TRUE.equals(enclosing.getNodeMetaData("GROOVY-11288")))
346+
if (!Boolean.TRUE.equals(enclosing.getNodeMetaData(ELIDE_EXPRESSION_VALUE)))
346347
rhsValueLoader.visit(controller.getAcg()); // assignment expression value
347348
}
348349
}

src/test/groovy/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,25 @@ final class StaticCompilationTest extends AbstractBytecodeTestCase {
430430
])
431431
}
432432

433+
// GROOVY-11630
434+
void testVoidMethod5() {
435+
assert compile(method: 'm', '''@groovy.transform.CompileStatic
436+
void m() {
437+
def list = [1,2,3]
438+
list.shuffle()
439+
}
440+
''').hasStrictSequence([
441+
'L1',
442+
'LINENUMBER 4 L1',
443+
'ALOAD 1',
444+
'INVOKESTATIC org/codehaus/groovy/runtime/DefaultGroovyMethods.shuffle (Ljava/util/List;)V',
445+
// drop: ACONST_NULL, POP
446+
'L2',
447+
'LINENUMBER 5 L2',
448+
'RETURN'
449+
])
450+
}
451+
433452
void testIntLeftShift() {
434453
assert compile(method: 'm', '''@groovy.transform.CompileStatic
435454
void m() {

0 commit comments

Comments
 (0)