diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/AsyncProfilerWrapper.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/AsyncProfilerWrapper.kt index 279e06b2941..7b29edf730b 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/AsyncProfilerWrapper.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/AsyncProfilerWrapper.kt @@ -17,7 +17,14 @@ interface AsyncProfilerReflected { } object AsyncProfilerHelper { + private var instance: AsyncProfilerReflected? = null + fun getInstance(libPath: String?): AsyncProfilerReflected { + // JVM doesn't support loading a native library multiple times even in different class loaders, so we don't attempt to load + // async-profiler again after the first use, which allows to profile the same compiler process multiple times, + // for example in the compiler daemon scenario. + instance?.let { return it } + val profilerClass = loadAsyncProfilerClass(libPath) val getInstanceHandle = MethodHandles.lookup().findStatic(profilerClass, "getInstance", MethodType.methodType(profilerClass, String::class.java)) @@ -49,7 +56,7 @@ object AsyncProfilerHelper { override val version: String get() = boundGetVersion.invokeWithArguments() as String - } + }.also { this.instance = it } } private fun loadAsyncProfilerClass(libPath: String?): Class<*> {