Support error*() methods

This commit is contained in:
Andrey Breslav
2013-05-12 19:20:28 +03:00
parent 4d8dcb5ea8
commit fe0ec5aafb
3 changed files with 37 additions and 6 deletions
@@ -79,14 +79,23 @@ public class InterceptionInstrumenter {
List<MethodData> enterData = new ArrayList<MethodData>(); List<MethodData> enterData = new ArrayList<MethodData>();
List<MethodData> exitData = new ArrayList<MethodData>(); List<MethodData> exitData = new ArrayList<MethodData>();
List<MethodData> errorData = new ArrayList<MethodData>();
List<Method> dumpMethods = new ArrayList<Method>(); List<Method> dumpMethods = new ArrayList<Method>();
for (Method method : interceptorClass.getMethods()) { for (Method method : interceptorClass.getMethods()) {
String name = method.getName(); String name = method.getName();
MethodData methodData = getMethodData(fieldData, method);
if (name.startsWith("enter")) { if (name.startsWith("enter")) {
enterData.add(getMethodData(fieldData, method)); enterData.add(methodData);
} }
else if (name.startsWith("exit")) { else if (name.startsWith("exit")) {
exitData.add(getMethodData(fieldData, method)); exitData.add(methodData);
}
else if (name.startsWith("error")) {
errorData.add(methodData);
}
else if (name.startsWith("anyExit")) {
exitData.add(methodData);
errorData.add(methodData);
} }
else if (name.startsWith("dump")) { else if (name.startsWith("dump")) {
Class<?>[] parameterTypes = method.getParameterTypes(); Class<?>[] parameterTypes = method.getParameterTypes();
@@ -109,6 +118,7 @@ public class InterceptionInstrumenter {
annotation.allowMultipleMatches(), annotation.allowMultipleMatches(),
enterData, enterData,
exitData, exitData,
errorData,
annotation.logInterceptions()); annotation.logInterceptions());
for (Method dumpMethod : dumpMethods) { for (Method dumpMethod : dumpMethods) {
@@ -278,6 +288,7 @@ public class InterceptionInstrumenter {
final List<MethodData> exitData = new ArrayList<MethodData>(); final List<MethodData> exitData = new ArrayList<MethodData>();
final List<MethodData> enterData = new ArrayList<MethodData>(); final List<MethodData> enterData = new ArrayList<MethodData>();
final List<MethodData> errorData = new ArrayList<MethodData>();
org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc);
@@ -298,6 +309,14 @@ public class InterceptionInstrumenter {
} }
exitData.add(methodData); exitData.add(methodData);
} }
for (MethodData methodData : instrumenter.getErrorData()) {
int depth = stackDepth(methodData, methodBeingInstrumented);
if (maxStackDepth < depth) {
maxStackDepth = depth;
}
errorData.add(methodData);
}
} }
if (enterData.isEmpty() && exitData.isEmpty()) return mv; if (enterData.isEmpty() && exitData.isEmpty()) return mv;
@@ -352,11 +371,14 @@ public class InterceptionInstrumenter {
case FRETURN: case FRETURN:
case DRETURN: case DRETURN:
case ARETURN: case ARETURN:
case ATHROW:
for (MethodData methodData : exitData) { for (MethodData methodData : exitData) {
invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false);
}
break;
case ATHROW:
for (MethodData methodData : errorData) {
// A constructor may throw before calling super(), 'this' is not available in this case // A constructor may throw before calling super(), 'this' is not available in this case
boolean beforeThrowInConstructor = opcode == ATHROW && isConstructor; invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor);
invokeMethod(access, name, desc, getInstructionAdapter(), methodData, beforeThrowInConstructor);
} }
break; break;
} }
@@ -23,6 +23,8 @@ interface MethodInstrumenter {
List<MethodData> getExitData(); List<MethodData> getExitData();
List<MethodData> getErrorData();
List<MethodData> getEnterData(); List<MethodData> getEnterData();
boolean allowsMultipleMatches(); boolean allowsMultipleMatches();
@@ -27,6 +27,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter {
private final boolean allowMultipleMatches; private final boolean allowMultipleMatches;
private final List<MethodData> enterData; private final List<MethodData> enterData;
private final List<MethodData> exitData; private final List<MethodData> exitData;
private final List<MethodData> errorData;
private final boolean logApplications; private final boolean logApplications;
public MethodInstrumenterImpl( public MethodInstrumenterImpl(
@@ -36,7 +37,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter {
boolean allowMultipleMatches, boolean allowMultipleMatches,
List<MethodData> enterData, List<MethodData> enterData,
List<MethodData> exitData, List<MethodData> exitData,
boolean logApplications List<MethodData> errorData, boolean logApplications
) { ) {
this.debugName = debugName; this.debugName = debugName;
this.classPattern = classPattern; this.classPattern = classPattern;
@@ -45,6 +46,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter {
this.allowMultipleMatches = allowMultipleMatches; this.allowMultipleMatches = allowMultipleMatches;
this.enterData = enterData; this.enterData = enterData;
this.exitData = exitData; this.exitData = exitData;
this.errorData = errorData;
this.logApplications = logApplications; this.logApplications = logApplications;
} }
@@ -75,6 +77,11 @@ class MethodInstrumenterImpl implements MethodInstrumenter {
return exitData; return exitData;
} }
@Override
public List<MethodData> getErrorData() {
return errorData;
}
@Override @Override
public String toString() { public String toString() {
return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]";