blob: 11f2a273c93c607c2e0f2e0787d2acb11f55d6e1 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.bytecode;
import static org.objectweb.asm.Opcodes.ASM7;
import static org.objectweb.asm.Opcodes.ATHROW;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.IRETURN;
import static org.objectweb.asm.Opcodes.RETURN;
import static org.chromium.bytecode.TypeUtils.STRING;
import static org.chromium.bytecode.TypeUtils.VOID;
import org.objectweb.asm.MethodVisitor;
/**
* MethodVisitor that wraps all code in TraceEvent.begin and TraceEvent.end calls. TraceEvent.end
* calls are added on all returns and thrown exceptions.
*
* Example:
* <pre>
* {@code
* int methodToTrace(String foo){
*
* //Line added by rewriter:
* TraceEvent.begin("ClassName.methodToTrace");
*
* if(foo == null){
* //Line added by rewriter:
* TraceEvent.end("ClassName.methodToTrace");
*
* throw new Exception();
* }
* else if(foo.equals("Two")){
* //Line added by rewriter:
* TraceEvent.end("ClassName.methodToTrace");
*
* return 2;
* }
*
* //Line added by rewriter:
* TraceEvent.end("ClassName.methodToTrace");
*
* return 0;
* }
* }
* </pre>
*
*/
class TraceEventAdderMethodAdapter extends MethodVisitor {
private static final String TRACE_EVENT_DESCRIPTOR = "org/chromium/base/TraceEvent";
private static final String TRACE_EVENT_SIGNATURE = TypeUtils.getMethodDescriptor(VOID, STRING);
private final String mEventName;
public TraceEventAdderMethodAdapter(
MethodVisitor methodVisitor, String shortClassName, String methodName) {
super(ASM7, methodVisitor);
mEventName = shortClassName + "." + methodName;
}
@Override
public void visitCode() {
super.visitCode();
mv.visitLdcInsn(mEventName);
mv.visitMethodInsn(
INVOKESTATIC, TRACE_EVENT_DESCRIPTOR, "begin", TRACE_EVENT_SIGNATURE, false);
}
@Override
public void visitInsn(int opcode) {
if ((opcode >= IRETURN && opcode <= RETURN) || opcode == ATHROW) {
mv.visitLdcInsn(mEventName);
mv.visitMethodInsn(
INVOKESTATIC, TRACE_EVENT_DESCRIPTOR, "end", TRACE_EVENT_SIGNATURE, false);
}
mv.visitInsn(opcode);
}
}