The main purpose of Preloader is to speed up class loading at compiler‘s startup. But as a side effect, we got a chance to support instrumenting the compiler’s code, which is mainly useful for profiling.
To run Preloader with instrumentation, pass instrument=...
on the command line:
org.jetbrains.kotlin.preloading.Preloader \ dist/kotlinc/lib/kotlin-compiler.jar \ org.jetbrains.kotlin.cli.jvm.K2JVMCompiler \ 5000 \ instrument=out/artifacts/Instrumentation/instrumentation.jar \ <compiler's command-line args>
This example uses an artifact already configured in our project. In this artifact, what to instrument is configured in the org.jetbrains.kotlin.preloading.ProfilingInstrumenterExample
class. This is determined by the src/META-INF/services/org.jetbrains.kotlin.preloading.instrumentation.Instrumenter
file (see JavaDoc for java.util.ServiceLoader
).
Instrumenter is any implementation of org.jetbrains.kotlin.preloading.instrumentation.Instrumenter
interface.
Preloader loads the first instrumenter service found on the class path. Services are provided through the standard JDK mechanism.
Every preloaded class is run through the instrumenter. Before exiting the program instrumenter‘s dump() method is called. Note JDK classes and everything in the Preloader’s own class path are not preloaded, thus not instrumented.
The instrumentation
module provides a convenient way to define useful instrumenters:
org.jetbrains.kotlin.preloading.instrumentation.InterceptionInstrumenterAdaptor
@MethodInterceptor
annotationWhatever the type of the field, if it has methods named by the convention defined below, they will be called as follows:
enter.*
- upon entering the instrumented methodnormalReturn.*
- upon returning normally from the instrumented method (not throwing an exception)exception.*
- upon explicitly throwing an exception from the instrumented methodexit.*
- upon exiting the instrumented method (either return or throw)dump.*
- upon program termination, useful to display the resultsIf any of the methods above, except for dump.*
, have parameters, they are treated as follows:
@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[]
See org.jetbrains.kotlin.preloading.ProfilingInstrumenterExample
.