Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@
import org.objectweb.asm.Type;
import org.objectweb.asm.TypePath;
import org.objectweb.asm.TypeReference;
import org.objectweb.asm.util.TraceMethodVisitor;

import java.io.PrintWriter;
import java.io.Writer;
Expand Down Expand Up @@ -355,7 +354,7 @@
* {@inheritDoc}
*/
@Override
public void visitClass(final ClassNode classNode) {

Check warning on line 357 in src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 104 to 64, Complexity from 20 to 14, Nesting Level from 4 to 2, Number of Variables from 20 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_groovy&issues=AZ9wyLB0qTBLjhhDAyR0&open=AZ9wyLB0qTBLjhhDAyR0&pullRequest=2707
referencedClasses.clear();

WriterControllerFactory factory = classNode.getNodeMetaData(WriterControllerFactory.class);
Expand Down Expand Up @@ -620,7 +619,7 @@
* {@inheritDoc}
*/
@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {

Check warning on line 622 in src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 79 to 64, Complexity from 21 to 14, Nesting Level from 3 to 2, Number of Variables from 19 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_groovy&issues=AZ9wyLB0qTBLjhhDAyR1&open=AZ9wyLB0qTBLjhhDAyR1&pullRequest=2707
Parameter[] parameters = node.getParameters();
Parameter receiver = null; // JSR 308 "this" parameter
if (parameters.length > 0 && parameters[0].isReceiver()) {
Expand All @@ -628,13 +627,12 @@
parameters = Arrays.copyOfRange(parameters, 1, parameters.length);
}

MethodVisitor mv = new PeepholeOptimizingMethodVisitor(
classVisitor.visitMethod(
node.getModifiers() | (isVargs(parameters) ? ACC_VARARGS : 0),
node.getName(),
BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters),
BytecodeHelper.getGenericsMethodSignature(node),
buildExceptions(node.getExceptions())));
MethodVisitor mv = classVisitor.visitMethod(
node.getModifiers() | (isVargs(parameters) ? ACC_VARARGS : 0),
node.getName(),
BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters),
BytecodeHelper.getGenericsMethodSignature(node),
buildExceptions(node.getExceptions()));

controller.setMethodVisitor(mv);
controller.resetLineNumber();
Expand Down Expand Up @@ -687,11 +685,13 @@
mv.visitMaxs(0, 0);
} catch (Throwable t) {
Writer writer = null;
if (mv instanceof TraceMethodVisitor tmv) {
writer = new StringBuilderWriter();
PrintWriter p = new PrintWriter(writer);
tmv.p.print(p);
p.flush();
// Method visitors are wrapped by PeepholeOptimizingClassVisitor; unwrap to
// reach a TraceMethodVisitor when classgen logging is enabled.
StringBuilderWriter buffer = new StringBuilderWriter();
PrintWriter printer = new PrintWriter(buffer);
if (PeepholeOptimizingMethodVisitor.printTraceBytecode(mv, printer)) {
printer.flush();
writer = buffer;
}
StringBuilder message = new StringBuilder(64);
message.append("ASM reporting processing error for ");
Expand Down Expand Up @@ -1982,7 +1982,7 @@
* {@inheritDoc}
*/
@Override
public void visitArrayExpression(final ArrayExpression expression) {

Check warning on line 1985 in src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 106 to 64, Complexity from 19 to 14, Nesting Level from 3 to 2, Number of Variables from 14 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_groovy&issues=AZ9wyLB0qTBLjhhDAyR2&open=AZ9wyLB0qTBLjhhDAyR2&pullRequest=2707
MethodVisitor mv = controller.getMethodVisitor();
CompileStack compileStack = controller.getCompileStack();
OperandStack operandStack = controller.getOperandStack();
Expand Down Expand Up @@ -2340,12 +2340,11 @@
while (index<size) {
String methodName = "$createListEntry_" + controller.getNextHelperMethodIndex();
methods.add(methodName);
mv = new PeepholeOptimizingMethodVisitor(
controller.getClassVisitor().visitMethod(
ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC,
methodName,
"([Ljava/lang/Object;)V",
null, null));
mv = controller.getClassVisitor().visitMethod(
ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC,
methodName,
"([Ljava/lang/Object;)V",
null, null);
controller.setMethodVisitor(mv);
mv.visitCode();
int methodBlockSize = Math.min(size-index, maxInit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ private void generateCreateCallSiteArray() {
methodIndex++;
String methodName = "$createCallSiteArray_" + methodIndex;
callSiteInitMethods.add(methodName);
MethodVisitor mv = new PeepholeOptimizingMethodVisitor(
controller.getClassVisitor().visitMethod(MOD_PRIVSS, methodName, "([Ljava/lang/String;)V", null, null));
MethodVisitor mv = controller.getClassVisitor().visitMethod(MOD_PRIVSS, methodName, "([Ljava/lang/String;)V", null, null);
controller.setMethodVisitor(mv);
mv.visitCode();
int methodLimit = size;
Expand All @@ -208,8 +207,7 @@ private void generateCreateCallSiteArray() {
mv.visitEnd();
}
// create base createCallSiteArray method
MethodVisitor mv = new PeepholeOptimizingMethodVisitor(
controller.getClassVisitor().visitMethod(MOD_PRIVSS, CREATE_CSA_METHOD, GET_CALLSITEARRAY_DESC, null, null));
MethodVisitor mv = controller.getClassVisitor().visitMethod(MOD_PRIVSS, CREATE_CSA_METHOD, GET_CALLSITEARRAY_DESC, null, null);
controller.setMethodVisitor(mv);
mv.visitCode();
mv.visitLdcInsn(size);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.codehaus.groovy.classgen.asm;

import org.codehaus.groovy.control.CompilerConfiguration;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;

/**
* Class-level installation point for Groovy's single-pass bytecode peephole layer.
* <p>
* Wraps each {@link MethodVisitor} returned by the delegate's
* {@link #visitMethod(int, String, String, String, String[])} with
* {@link PeepholeOptimizingMethodVisitor}, so <em>every</em> method body receives
* the same stack-local compaction — user methods, constructors, static initializers,
* and synthetic helpers alike (MOP bridges, call-site array initializers,
* {@code class$}/{@code $get$} resolvers, large-list init chunks, and so on).
* <p>
* Centralizing the wrap here avoids ad-hoc
* {@code new PeepholeOptimizingMethodVisitor(...)} at individual emission sites and
* keeps compaction in lockstep with {@link OperandStack}, which emits integer and
* other primitive constants via {@code visitLdcInsn} and relies on the peephole
* visitor to narrow them to {@code ICONST_*}, {@code BIPUSH}, {@code SIPUSH}, etc.
* <p>
* Installed once by {@link WriterController} when the class visitor chain is built
* (optionally outside a {@code LoggableClassVisitor} / {@code TraceClassVisitor}
* pair used for classgen logging). Field and attribute visits are left unchanged;
* only method bodies are optimized.
*
* @see PeepholeOptimizingMethodVisitor
* @see WriterController
* @since 6.0.0
*/
public final class PeepholeOptimizingClassVisitor extends ClassVisitor {

/**
* Creates a visitor that peephole-optimizes every method written to
* {@code classVisitor}.
*
* @param classVisitor the next visitor in the class-generation chain
* (typically a {@link org.objectweb.asm.ClassWriter}, optionally
* preceded by logging / tracing adapters)
*/
public PeepholeOptimizingClassVisitor(final ClassVisitor classVisitor) {
super(CompilerConfiguration.ASM_API_VERSION, classVisitor);
}

/**
* {@inheritDoc}
* <p>
* When the delegate returns a non-{@code null} visitor, the result is a
* {@link PeepholeOptimizingMethodVisitor} (or the same instance if the
* delegate already wrapped the method). A {@code null} from the delegate is
* propagated unchanged so methods can still be skipped per the ASM contract.
*/
@Override
public MethodVisitor visitMethod(final int access, final String name, final String descriptor, final String signature, final String[] exceptions) {
return PeepholeOptimizingMethodVisitor.wrap(super.visitMethod(access, name, descriptor, signature, exceptions));
}
}
Loading
Loading