diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index e1aa33deca3..6004e2a0529 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -79,14 +79,23 @@ public class InterceptionInstrumenter { List enterData = new ArrayList(); List exitData = new ArrayList(); + List errorData = new ArrayList(); List dumpMethods = new ArrayList(); for (Method method : interceptorClass.getMethods()) { String name = method.getName(); + MethodData methodData = getMethodData(fieldData, method); if (name.startsWith("enter")) { - enterData.add(getMethodData(fieldData, method)); + enterData.add(methodData); } 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")) { Class[] parameterTypes = method.getParameterTypes(); @@ -109,6 +118,7 @@ public class InterceptionInstrumenter { annotation.allowMultipleMatches(), enterData, exitData, + errorData, annotation.logInterceptions()); for (Method dumpMethod : dumpMethods) { @@ -278,6 +288,7 @@ public class InterceptionInstrumenter { final List exitData = new ArrayList(); final List enterData = new ArrayList(); + final List errorData = new ArrayList(); org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); @@ -298,6 +309,14 @@ public class InterceptionInstrumenter { } 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; @@ -352,11 +371,14 @@ public class InterceptionInstrumenter { case FRETURN: case DRETURN: case ARETURN: - case ATHROW: 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 - boolean beforeThrowInConstructor = opcode == ATHROW && isConstructor; - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, beforeThrowInConstructor); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); } break; } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java index c67c39fa8c5..bb1efea3b36 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -23,6 +23,8 @@ interface MethodInstrumenter { List getExitData(); + List getErrorData(); + List getEnterData(); boolean allowsMultipleMatches(); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java index 7f3ddb51093..beeba444424 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -27,6 +27,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { private final boolean allowMultipleMatches; private final List enterData; private final List exitData; + private final List errorData; private final boolean logApplications; public MethodInstrumenterImpl( @@ -36,7 +37,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { boolean allowMultipleMatches, List enterData, List exitData, - boolean logApplications + List errorData, boolean logApplications ) { this.debugName = debugName; this.classPattern = classPattern; @@ -45,6 +46,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { this.allowMultipleMatches = allowMultipleMatches; this.enterData = enterData; this.exitData = exitData; + this.errorData = errorData; this.logApplications = logApplications; } @@ -75,6 +77,11 @@ class MethodInstrumenterImpl implements MethodInstrumenter { return exitData; } + @Override + public List getErrorData() { + return errorData; + } + @Override public String toString() { return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]";