diff --git a/compiler/preloader/instrumentation/ReadMe.md b/compiler/preloader/instrumentation/ReadMe.md index 632eb225b77..dfdb9eac23c 100644 --- a/compiler/preloader/instrumentation/ReadMe.md +++ b/compiler/preloader/instrumentation/ReadMe.md @@ -45,6 +45,7 @@ Whatever the type of the field, if it has methods named by the convention define If any of the methods above, except for ```dump.*```, have parameters, they are treated as follows: * *no annotation* - this parameter receives the respective parameter of the instrumented method * ```@This``` - this parameter receives the ```this``` of the instrumented method, or ```null``` if there's no ```this``` +* ```@ClassName``` - this parameter receives the name of the class containing the instrumented method, must be a ```String``` * ```@MethodName``` - this parameter receives the name of the instrumented method, must be a ```String``` * ```@MethodDesc``` - this parameter receives the JVM descriptor of the instrumented method, like ```(ILjava/lang/Object;)V```, must be a ```String``` * ```@AllArgs``` - this parameter receives an array of all arguments of the instrumented method, must be of type ```Object[]``` diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java index 20772c75388..9444aa61012 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.preloading; import org.jetbrains.jet.preloading.instrumentation.InterceptionInstrumenterAdaptor; +import org.jetbrains.jet.preloading.instrumentation.annotations.ClassName; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodDesc; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodInterceptor; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodName; @@ -104,8 +105,8 @@ public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdapto public static class MethodCollector { private final Collection l = new LinkedHashSet(); - public void enter(@MethodName String name, @MethodDesc String desc) {//long l, Object arg) { - l.add(name + desc); + public void enter(@ClassName String className, @MethodName String name, @MethodDesc String desc) { + l.add(className + "." + name + desc); } public void dump(PrintStream out) { 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 060367bec85..436aa6ebaba 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 @@ -166,6 +166,7 @@ public class InterceptionInstrumenter { private static MethodData getMethodData(FieldData interceptorField, Method method) { Annotation[][] parameterAnnotations = method.getParameterAnnotations(); int thisParameterIndex = -1; + int classNameParameterIndex = -1; int methodNameParameterIndex = -1; int methodDescParameterIndex = -1; int allArgsParameterIndex = -1; @@ -177,6 +178,12 @@ public class InterceptionInstrumenter { } thisParameterIndex = i; } + else if (annotation instanceof ClassName) { + if (classNameParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @ClassName parameters in " + method); + } + classNameParameterIndex = i; + } else if (annotation instanceof MethodName) { if (methodNameParameterIndex > -1) { throw new IllegalArgumentException("Multiple @MethodName parameters in " + method); @@ -203,6 +210,7 @@ public class InterceptionInstrumenter { method.getName(), Type.getMethodDescriptor(method), thisParameterIndex, + classNameParameterIndex, methodNameParameterIndex, methodDescParameterIndex, allArgsParameterIndex); @@ -338,7 +346,7 @@ public class InterceptionInstrumenter { for (MethodData methodData : enterData) { // At the very beginning of a constructor, i.e. before any super() call, 'this' is not available // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); + invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, isConstructor); } super.visitCode(); } @@ -353,13 +361,13 @@ public class InterceptionInstrumenter { case DRETURN: case ARETURN: for (MethodData methodData : normalReturnData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false); + invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, false); } break; case ATHROW: for (MethodData methodData : exceptionData) { // A constructor may throw before calling super(), 'this' is not available in this case - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); + invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, isConstructor); } break; } @@ -445,6 +453,7 @@ public class InterceptionInstrumenter { private static void invokeMethod( int instrumentedMethodAccess, + String instrumentedClassName, String instrumentedMethodName, String instrumentedMethodDesc, InstructionAdapter ia, @@ -475,6 +484,9 @@ public class InterceptionInstrumenter { ia.load(0, OBJECT_TYPE); } } + else if (i == methodData.getClassNameParameterIndex()) { + ia.aconst(instrumentedClassName); + } else if (i == methodData.getMethodNameParameterIndex()) { ia.aconst(instrumentedMethodName); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 31936fea2fa..3a743ecc2a1 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.preloading.instrumentation; public class MethodData extends MemberData { private final FieldData ownerField; private final int thisParameterIndex; + private final int classNameParameterIndex; private final int methodNameParameterIndex; private final int methodDescParameterIndex; private final int allArgsParameterIndex; @@ -29,6 +30,7 @@ public class MethodData extends MemberData { String name, String desc, int thisParameterIndex, + int classNameParameterIndex, int methodNameParameterIndex, int methodDescParameterIndex, int allArgsParameterIndex @@ -36,6 +38,7 @@ public class MethodData extends MemberData { super(declaringClass, name, desc); this.ownerField = ownerField; this.thisParameterIndex = thisParameterIndex; + this.classNameParameterIndex = classNameParameterIndex; this.methodNameParameterIndex = methodNameParameterIndex; this.methodDescParameterIndex = methodDescParameterIndex; this.allArgsParameterIndex = allArgsParameterIndex; @@ -49,6 +52,10 @@ public class MethodData extends MemberData { return thisParameterIndex; } + public int getClassNameParameterIndex() { + return classNameParameterIndex; + } + public int getMethodNameParameterIndex() { return methodNameParameterIndex; } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java new file mode 100644 index 00000000000..f2c70b404cb --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface ClassName { +}