org.glassfish.pfl.tf.tools.enhancer.SimpleMethodTracer.java Source code

Java tutorial

Introduction

Here is the source code for org.glassfish.pfl.tf.tools.enhancer.SimpleMethodTracer.java

Source

package org.glassfish.pfl.tf.tools.enhancer;

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright (c) 1997-2010,2017 Oracle and/or its affiliates. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * 
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 * 
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 * 
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

import org.glassfish.pfl.tf.spi.Util;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author ken
 */
public class SimpleMethodTracer implements MethodVisitor {
    final MethodVisitor mv;
    final Util util;
    final Set<Label> visitedLables = new HashSet<Label>();

    private void msg(String str) {
        util.info(2, "---" + str);
    }

    public SimpleMethodTracer(MethodVisitor mv, Util util) {
        this.mv = mv;
        this.util = util;
    }

    public AnnotationVisitor visitAnnotationDefault() {
        msg("visitAnnotationDefault");
        return mv.visitAnnotationDefault();
    }

    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
        msg("visitAnnotation(desc=" + desc + ",visible=" + visible + ")");
        return mv.visitAnnotation(desc, visible);
    }

    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
        msg("visitParameterAnnotation(parameter=" + parameter + ".desc=" + desc + ",visible=" + visible + ")");
        return mv.visitParameterAnnotation(parameter, desc, visible);
    }

    public void visitAttribute(Attribute attr) {
        msg("visitAttribute(attr=" + attr + ")");
        mv.visitAttribute(attr);
    }

    public void visitCode() {
        msg("visitCode");
        mv.visitCode();
    }

    private String getFrameType(int type) {
        switch (type) {
        case Opcodes.F_APPEND:
            return "APPEND";
        case Opcodes.F_CHOP:
            return "CHOP";
        case Opcodes.F_FULL:
            return "FULL";
        case Opcodes.F_NEW:
            return "NEW";
        case Opcodes.F_SAME:
            return "SAME";
        case Opcodes.F_SAME1:
            return "SAME1";
        }
        return "BAD_FRAME_TYPE";
    }

    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
        msg("visitFrame(type=" + getFrameType(type) + ",nLocal=" + nLocal + ",local=" + Arrays.asList(local)
                + ",nStack=" + nStack + ",stack=" + Arrays.asList(stack) + ")");

        mv.visitFrame(type, nLocal, local, nStack, stack);
    }

    public void visitInsn(int opcode) {
        msg("visitInsn(opcode=" + Util.opcodeToString(opcode) + ")");
        mv.visitInsn(opcode);
    }

    public void visitIntInsn(int opcode, int operand) {
        msg("visitIntInsn(opcode=" + Util.opcodeToString(opcode) + ",operand=" + operand + ")");
        mv.visitIntInsn(opcode, operand);
    }

    public void visitVarInsn(int opcode, int var) {
        msg("visitVarInsn(opcode=" + Util.opcodeToString(opcode) + ",var=" + var + ")");
        mv.visitVarInsn(opcode, var);
    }

    public void visitTypeInsn(int opcode, String type) {
        msg("visitTypeInsn(opcode=" + Util.opcodeToString(opcode) + ",type=" + type + ")");
        mv.visitTypeInsn(opcode, type);
    }

    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
        msg("visitFieldInsn(opcode=" + Util.opcodeToString(opcode) + ",owner=" + owner + ",name=" + name + ",desc="
                + desc + ")");
        mv.visitFieldInsn(opcode, owner, name, desc);
    }

    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
        msg("visitMethodInsn(opcode=" + Util.opcodeToString(opcode) + ",owner=" + owner + ",name=" + name + ",desc="
                + desc + ")");
        mv.visitMethodInsn(opcode, owner, name, desc);
    }

    public void visitJumpInsn(int opcode, Label label) {
        msg("visitJumpInsn(opcode=" + Util.opcodeToString(opcode) + ",label=" + label + ")");
        mv.visitJumpInsn(opcode, label);
    }

    public void visitLabel(Label label) {
        msg("visitLabel(label=" + label + ")");
        visitedLables.add(label);
        mv.visitLabel(label);
    }

    public void visitLdcInsn(Object cst) {
        msg("visitLdcInsn(cst=" + cst + ")");
        mv.visitLdcInsn(cst);
    }

    public void visitIincInsn(int var, int increment) {
        msg("visitIincInsn(var=" + var + ",increment=" + increment + ")");
        mv.visitIincInsn(var, increment);
    }

    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
        msg("visitTableSwitchInsn");
        mv.visitTableSwitchInsn(min, max, dflt, labels);
    }

    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
        msg("visitLookupSwitchInsn");
        mv.visitLookupSwitchInsn(dflt, keys, labels);
    }

    public void visitMultiANewArrayInsn(String desc, int dims) {
        msg("visitMultiANewArrayInsn(desc=" + desc + ",dims=" + dims + ")");
        mv.visitMultiANewArrayInsn(desc, dims);
    }

    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {

        /* Ignore these rules: it seems that ASM doesn't really follow them,
         * and this causes what appears to be a spurious failure.
         *
        if (visitedLables.contains(start)) {
        throw new RuntimeException(
            "visiting try-catch block: start label has already been visited" ) ;
        }
            
        if (visitedLables.contains(end)) {
        throw new RuntimeException(
            "visiting try-catch block: end label has already been visited" ) ;
        }
            
        if (visitedLables.contains(handler)) {
        throw new RuntimeException(
            "visiting try-catch block: handler label has already been visited" ) ;
        }
        */

        msg("visitTryCatchBlock(start=" + start + ",end=" + end + ",handler=" + handler + ",type=" + type + ")");
        mv.visitTryCatchBlock(start, end, handler, type);
    }

    public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {

        if (!visitedLables.contains(start)) {
            throw new RuntimeException("visitLocalVariable: start label has not been visited");
        }

        if (!visitedLables.contains(end)) {
            throw new RuntimeException("visitLocalVariable: end label has not been visited");
        }

        msg("visitLocalVariable(name=" + name + ",desc=" + desc + ",signature=" + signature + ",start=" + start
                + ",end=" + end + ",index=" + index + ")");
        mv.visitLocalVariable(name, desc, signature, start, end, index);
    }

    public void visitLineNumber(int line, Label start) {
        msg("visitLineNumber(line=" + line + ",start=" + start + ")");
        mv.visitLineNumber(line, start);
    }

    public void visitMaxs(int maxStack, int maxLocals) {
        msg("visitMaxs(maxStack=" + maxStack + ",maxLocals=" + maxLocals + ")");
        mv.visitMaxs(maxStack, maxLocals);
    }

    public void visitEnd() {
        msg("visitEnd");
        mv.visitEnd();
    }
}