groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject groovy git commit: Make bytecode generation loggable
Date Wed, 21 Jun 2017 00:09:35 GMT
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X 177c77edb -> 4f5e1aec2


Make bytecode generation loggable

(cherry picked from commit ab5defa)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/4f5e1aec
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/4f5e1aec
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/4f5e1aec

Branch: refs/heads/GROOVY_2_5_X
Commit: 4f5e1aec2a2aa0b3cad0681f134b68d9fe3e7c6c
Parents: 177c77e
Author: sunlan <sunlan@apache.org>
Authored: Wed Jun 21 00:23:12 2017 +0800
Committer: sunlan <sunlan@apache.org>
Committed: Wed Jun 21 08:09:29 2017 +0800

----------------------------------------------------------------------
 .../groovy/classgen/AsmClassGenerator.java      |   5 +-
 .../groovy/classgen/asm/WriterController.java   |  64 +--
 .../classgen/asm/util/LoggableClassVisitor.java |  14 +
 .../classgen/asm/util/LoggableTextifier.java    | 419 +++++++++++++++++++
 4 files changed, 475 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4f5e1aec/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 849bf6f..68be508 100644
--- a/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -95,7 +95,7 @@ import java.util.Map;
  */
 public class AsmClassGenerator extends ClassGenerator {
 
-    private final ClassVisitor cv;
+    private ClassVisitor cv;
     private final GeneratorContext context;
     private final String sourceFile;
 
@@ -165,7 +165,7 @@ public class AsmClassGenerator extends ClassGenerator {
     //-------------------------------------------------------------------------
     public void visitClass(ClassNode classNode) {
         referencedClasses.clear();
-        WriterControllerFactory factory = (WriterControllerFactory) classNode.getNodeMetaData(WriterControllerFactory.class);
+        WriterControllerFactory factory = classNode.getNodeMetaData(WriterControllerFactory.class);
         WriterController normalController = new WriterController();
         if (factory!=null) {
             this.controller = factory.makeController(normalController);
@@ -173,6 +173,7 @@ public class AsmClassGenerator extends ClassGenerator {
             this.controller = normalController;
         }
         this.controller.init(this, context, cv, classNode);
+        this.cv = this.controller.getClassVisitor();
 
         if (controller.shouldOptimizeForInt() || factory!=null) {
             OptimizingStatementWriter.setNodeMeta(controller.getTypeChooser(),classNode);

http://git-wip-us.apache.org/repos/asf/groovy/blob/4f5e1aec/src/main/org/codehaus/groovy/classgen/asm/WriterController.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/WriterController.java b/src/main/org/codehaus/groovy/classgen/asm/WriterController.java
index e8c5b61..ef8ee4e 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/WriterController.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/WriterController.java
@@ -33,6 +33,7 @@ import org.codehaus.groovy.classgen.GeneratorContext;
 import org.codehaus.groovy.classgen.asm.indy.IndyBinHelper;
 import org.codehaus.groovy.classgen.asm.indy.IndyCallSiteWriter;
 import org.codehaus.groovy.classgen.asm.indy.InvokeDynamicWriter;
+import org.codehaus.groovy.classgen.asm.util.LoggableClassVisitor;
 import org.codehaus.groovy.control.CompilerConfiguration;
 import org.codehaus.groovy.control.SourceUnit;
 import org.objectweb.asm.ClassVisitor;
@@ -40,7 +41,11 @@ import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 
 public class WriterController {
-
+    private static final String GROOVY_LOG_CLASSGEN = "groovy.log.classgen";
+    private static final boolean LOG_CLASSGEN;
+    static {
+        LOG_CLASSGEN = Boolean.valueOf(System.getProperty(GROOVY_LOG_CLASSGEN));
+    }
     private AsmClassGenerator acg;
     private MethodVisitor methodVisitor;
     private CompileStack compileStack;
@@ -100,7 +105,7 @@ public class WriterController {
             this.invocationWriter = new InvocationWriter(this);
             this.binaryExpHelper = new BinaryExpressionHelper(this);
         }
-        
+
         this.unaryExpressionHelper = new UnaryExpressionHelper(this);
         if (optimizeForInt) {
             this.fastPathBinaryExpHelper = new BinaryExpressionMultiTypeDispatcher(this);
@@ -119,7 +124,7 @@ public class WriterController {
         this.sourceUnit = acg.getSourceUnit();
         this.context = gcon;
         this.compileStack = new CompileStack(this);
-        this.cv = cv;
+        this.cv = this.createClassVisitor(cv);
         if (optimizeForInt) {
             this.statementWriter = new OptimizingStatementWriter(this);
         } else {
@@ -128,6 +133,15 @@ public class WriterController {
         this.typeChooser = new StatementMetaTypeChooser();
     }
 
+    private ClassVisitor createClassVisitor(ClassVisitor cv) {
+        if (!LOG_CLASSGEN) {
+            return cv;
+        }
+        if (cv instanceof LoggableClassVisitor) {
+            return cv;
+        }
+        return new LoggableClassVisitor(cv);
+    }
     private static int chooseBytecodeVersion(final boolean invokedynamic, final String targetBytecode)
{
         if (invokedynamic) {
             if (CompilerConfiguration.JDK8.equals(targetBytecode)) {
@@ -189,7 +203,7 @@ public class WriterController {
     public ClosureWriter getClosureWriter() {
         return closureWriter;
     }
-    
+
     public ClassVisitor getCv() {
         return cv;
     }
@@ -229,25 +243,25 @@ public class WriterController {
     public String getInternalBaseClassName() {
         return internalBaseClassName;
     }
-    
+
     public MethodNode getMethodNode() {
         return methodNode;
     }
-    
+
     public void setMethodNode(MethodNode mn) {
         methodNode = mn;
         constructorNode = null;
     }
-    
+
     public ConstructorNode getConstructorNode(){
         return constructorNode;
     }
-    
+
     public void setConstructorNode(ConstructorNode cn) {
         constructorNode = cn;
         methodNode = null;
     }
-    
+
     public boolean isNotClinit() {
         return methodNode == null || !methodNode.getName().equals("<clinit>");
     }
@@ -268,12 +282,12 @@ public class WriterController {
     public boolean isInClosure() {
         return classNode.getOuterClass() != null
                 && classNode.getSuperClass() == ClassHelper.CLOSURE_TYPE;
-    }    
-    
+    }
+
     public boolean isInClosureConstructor() {
         return constructorNode != null
-        && classNode.getOuterClass() != null
-        && classNode.getSuperClass() == ClassHelper.CLOSURE_TYPE;
+                && classNode.getOuterClass() != null
+                && classNode.getSuperClass() == ClassHelper.CLOSURE_TYPE;
     }
 
     public boolean isNotExplicitThisInClosure(boolean implicitThis) {
@@ -314,7 +328,7 @@ public class WriterController {
             return classNode.isScript() && methodNode != null && methodNode.getName().equals("run");
         }
     }
-    
+
     public String getClassName() {
         String className;
         if (!classNode.isInterface() || interfaceClassLoadingClass == null) {
@@ -324,7 +338,7 @@ public class WriterController {
         }
         return className;
     }
-    
+
     public ClassNode getOutermostClass() {
         if (outermostClass == null) {
             outermostClass = classNode;
@@ -342,15 +356,15 @@ public class WriterController {
     public void setInterfaceClassLoadingClass(InterfaceHelperClassNode ihc) {
         interfaceClassLoadingClass = ihc;
     }
-    
+
     public InterfaceHelperClassNode getInterfaceClassLoadingClass() {
         return interfaceClassLoadingClass;
     }
-    
+
     public boolean shouldOptimizeForInt() {
         return optimizeForInt;
     }
-    
+
     public StatementWriter getStatementWriter() {
         return statementWriter;
     }
@@ -368,22 +382,22 @@ public class WriterController {
     public boolean isFastPath() {
         return fastPath;
     }
-    
+
     public int getBytecodeVersion() {
         return bytecodeVersion;
     }
-    
+
     public int getLineNumber() {
         return lineNumber;
     }
-    
+
     public void setLineNumber(int n) {
-    	lineNumber = n;
+        lineNumber = n;
     }
 
-	public void resetLineNumber() {
-		setLineNumber(-1);
-	}
+    public void resetLineNumber() {
+        setLineNumber(-1);
+    }
 
     public int getNextHelperMethodIndex() {
         return helperMethodIndex++;

http://git-wip-us.apache.org/repos/asf/groovy/blob/4f5e1aec/src/main/org/codehaus/groovy/classgen/asm/util/LoggableClassVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/util/LoggableClassVisitor.java b/src/main/org/codehaus/groovy/classgen/asm/util/LoggableClassVisitor.java
new file mode 100644
index 0000000..f5a0220
--- /dev/null
+++ b/src/main/org/codehaus/groovy/classgen/asm/util/LoggableClassVisitor.java
@@ -0,0 +1,14 @@
+package org.codehaus.groovy.classgen.asm.util;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.util.TraceClassVisitor;
+
+/**
+ * A ClassVisitor proxy, which can log bytecode generation
+ */
+public class LoggableClassVisitor extends ClassVisitor {
+    public LoggableClassVisitor(final ClassVisitor cv) {
+        super(Opcodes.ASM6, new TraceClassVisitor(cv, new LoggableTextifier(), null));
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/4f5e1aec/src/main/org/codehaus/groovy/classgen/asm/util/LoggableTextifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/util/LoggableTextifier.java b/src/main/org/codehaus/groovy/classgen/asm/util/LoggableTextifier.java
new file mode 100644
index 0000000..46db3d5
--- /dev/null
+++ b/src/main/org/codehaus/groovy/classgen/asm/util/LoggableTextifier.java
@@ -0,0 +1,419 @@
+package org.codehaus.groovy.classgen.asm.util;
+
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.util.Printer;
+import org.objectweb.asm.util.Textifier;
+
+import java.util.List;
+
+/**
+ * Logging bytecode generation, which can make debugging easy
+ */
+public class LoggableTextifier extends Textifier {
+//    private static final Logger LOGGER = Logger.getLogger(LoggableTextifier.class.getName());
+    private int loggedLineCnt = 0;
+
+    public LoggableTextifier() {
+        super(Opcodes.ASM6);
+    }
+
+    @Override
+    protected Textifier createTextifier() {
+        return new LoggableTextifier();
+    }
+
+    protected void log() {
+        int textSize = text.size();
+
+        for (int i = loggedLineCnt; i < textSize; i++) {
+            Object bc = text.get(i);
+
+            if (bc instanceof List && 0 == ((List) bc).size()) {
+                continue;
+            }
+
+            System.out.print(bc);
+        }
+
+        loggedLineCnt = textSize;
+    }
+
+
+    @Override
+    public void visit(int version, int access, String name, String signature, String superName,
String[] interfaces) {
+        super.visit(version, access, name, signature, superName, interfaces);
+        log();
+    }
+
+    @Override
+    public void visitSource(String file, String debug) {
+        super.visitSource(file, debug);
+        log();
+    }
+
+    @Override
+    public Printer visitModule() {
+        Printer p = super.visitModule();
+        log();
+        return p;
+    }
+
+    @Override
+    public void visitOuterClass(String owner, String name, String desc) {
+        super.visitOuterClass(owner, name, desc);
+        log();
+    }
+
+    @Override
+    public Textifier visitClassAnnotation(String desc, boolean visible) {
+        Textifier t = super.visitClassAnnotation(desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitClassTypeAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
+        Textifier t = super.visitClassTypeAnnotation(typeRef, typePath, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitClassAttribute(Attribute attr) {
+        super.visitClassAttribute(attr);
+        log();
+    }
+
+    @Override
+    public void visitInnerClass(String name, String outerName, String innerName, int access)
{
+        super.visitInnerClass(name, outerName, innerName, access);
+        log();
+    }
+
+    @Override
+    public Textifier visitField(int access, String name, String desc, String signature, Object
value) {
+        Textifier t = super.visitField(access, name, desc, signature, value);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitMethod(int access, String name, String desc, String signature,
String[] exceptions) {
+        Textifier t = super.visitMethod(access, name, desc, signature, exceptions);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitClassEnd() {
+        super.visitClassEnd();
+        log();
+    }
+
+    @Override
+    public void visitRequire(String require, int access) {
+        super.visitRequire(require, access);
+        log();
+    }
+
+    @Override
+    public void visitExport(String export, String... tos) {
+        super.visitExport(export, tos);
+        log();
+    }
+
+    @Override
+    public void visitUse(String use) {
+        super.visitUse(use);
+        log();
+    }
+
+    @Override
+    public void visitProvide(String provide, String with) {
+        super.visitProvide(provide, with);
+        log();
+    }
+
+    @Override
+    public void visitModuleEnd() {
+        super.visitModuleEnd();
+        log();
+    }
+
+    @Override
+    public void visit(String name, Object value) {
+        super.visit(name, value);
+        log();
+    }
+
+    @Override
+    public void visitEnum(String name, String desc, String value) {
+        super.visitEnum(name, desc, value);
+        log();
+    }
+
+    @Override
+    public Textifier visitAnnotation(String name, String desc) {
+        Textifier t = super.visitAnnotation(name, desc);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitArray(String name) {
+        Textifier t = super.visitArray(name);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitAnnotationEnd() {
+        super.visitAnnotationEnd();
+        log();
+    }
+
+    @Override
+    public Textifier visitFieldAnnotation(String desc, boolean visible) {
+        Textifier t = super.visitFieldAnnotation(desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitFieldTypeAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
+        Textifier t = super.visitFieldTypeAnnotation(typeRef, typePath, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitFieldAttribute(Attribute attr) {
+        super.visitFieldAttribute(attr);
+        log();
+    }
+
+    @Override
+    public void visitFieldEnd() {
+        super.visitFieldEnd();
+        log();
+    }
+
+    @Override
+    public void visitParameter(String name, int access) {
+        super.visitParameter(name, access);
+        log();
+    }
+
+    @Override
+    public Textifier visitAnnotationDefault() {
+        Textifier t = super.visitAnnotationDefault();
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitMethodAnnotation(String desc, boolean visible) {
+        Textifier t = super.visitMethodAnnotation(desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitMethodTypeAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
+        Textifier t = super.visitMethodTypeAnnotation(typeRef, typePath, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitParameterAnnotation(int parameter, String desc, boolean visible)
{
+        Textifier t = super.visitParameterAnnotation(parameter, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitMethodAttribute(Attribute attr) {
+        super.visitMethodAttribute(attr);
+        log();
+    }
+
+    @Override
+    public void visitCode() {
+        super.visitCode();
+        log();
+    }
+
+    @Override
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack)
{
+        super.visitFrame(type, nLocal, local, nStack, stack);
+        log();
+    }
+
+    @Override
+    public void visitInsn(int opcode) {
+        super.visitInsn(opcode);
+        log();
+    }
+
+    @Override
+    public void visitIntInsn(int opcode, int operand) {
+        super.visitIntInsn(opcode, operand);
+        log();
+    }
+
+    @Override
+    public void visitVarInsn(int opcode, int var) {
+        super.visitVarInsn(opcode, var);
+        log();
+    }
+
+    @Override
+    public void visitTypeInsn(int opcode, String type) {
+        super.visitTypeInsn(opcode, type);
+        log();
+    }
+
+    @Override
+    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+        super.visitFieldInsn(opcode, owner, name, desc);
+        log();
+    }
+
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+        super.visitMethodInsn(opcode, owner, name, desc);
+        log();
+    }
+
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean
itf) {
+        super.visitMethodInsn(opcode, owner, name, desc, itf);
+        log();
+    }
+
+    @Override
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)
{
+        super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+        log();
+    }
+
+    @Override
+    public void visitJumpInsn(int opcode, Label label) {
+        super.visitJumpInsn(opcode, label);
+        log();
+    }
+
+    @Override
+    public void visitLabel(Label label) {
+        super.visitLabel(label);
+        log();
+    }
+
+    @Override
+    public void visitLdcInsn(Object cst) {
+        super.visitLdcInsn(cst);
+        log();
+    }
+
+    @Override
+    public void visitIincInsn(int var, int increment) {
+        super.visitIincInsn(var, increment);
+        log();
+    }
+
+    @Override
+    public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+        super.visitTableSwitchInsn(min, max, dflt, labels);
+        log();
+    }
+
+    @Override
+    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+        super.visitLookupSwitchInsn(dflt, keys, labels);
+        log();
+    }
+
+    @Override
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+        super.visitMultiANewArrayInsn(desc, dims);
+        log();
+    }
+
+    @Override
+    public Textifier visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean
visible) {
+        Textifier t = super.visitInsnAnnotation(typeRef, typePath, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+        super.visitTryCatchBlock(start, end, handler, type);
+        log();
+    }
+
+    @Override
+    public Textifier visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
+        Textifier t = super.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitLocalVariable(String name, String desc, String signature, Label start,
Label end, int index) {
+        super.visitLocalVariable(name, desc, signature, start, end, index);
+        log();
+    }
+
+    @Override
+    public Textifier visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[]
start, Label[] end, int[] index, String desc, boolean visible) {
+        Textifier t = super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index,
desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitLineNumber(int line, Label start) {
+        super.visitLineNumber(line, start);
+        log();
+    }
+
+    @Override
+    public void visitMaxs(int maxStack, int maxLocals) {
+        super.visitMaxs(maxStack, maxLocals);
+        log();
+    }
+
+    @Override
+    public void visitMethodEnd() {
+        super.visitMethodEnd();
+        log();
+    }
+
+    @Override
+    public Textifier visitAnnotation(String desc, boolean visible) {
+        Textifier t = super.visitAnnotation(desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public Textifier visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean
visible) {
+        Textifier t = super.visitTypeAnnotation(typeRef, typePath, desc, visible);
+        log();
+        return t;
+    }
+
+    @Override
+    public void visitAttribute(Attribute attr) {
+        super.visitAttribute(attr);
+        log();
+    }
+
+}


Mime
View raw message