Introduce KClass-based cache for KPackageFragment
* It is a heavy-weight object that is hard to compute * It is being constructed each type _cached_ method ref is used in equals/hashCode * Module name is deliberately ignored, corresponding doc is added where appropriate #KT-48136 Merge-request: KT-MR-6817 Merged-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
This commit is contained in:
committed by
Space
parent
28310eb970
commit
c6cbab43f7
+12
@@ -41267,6 +41267,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("jvmKPackageCaching.kt")
|
||||
public void testJvmKPackageCaching() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/jvmKPackageCaching.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("jvmKTypeCaching.kt")
|
||||
public void testJvmKTypeCaching() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/jvmKTypeCaching.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// FULL_JDK
|
||||
// WITH_REFLECT
|
||||
import kotlin.jvm.internal.*
|
||||
|
||||
class A
|
||||
fun box(): String {
|
||||
val pckg = Reflection.getOrCreateKotlinPackage(A::class.java)
|
||||
System.gc()
|
||||
val pckg2 = Reflection.getOrCreateKotlinPackage(A::class.java)
|
||||
if (pckg === pckg2) return "OK"
|
||||
return "Fail"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// FULL_JDK
|
||||
// WITH_REFLECT
|
||||
|
||||
class A
|
||||
|
||||
fun box(): String {
|
||||
val clz = A::class
|
||||
System.gc()
|
||||
val clz2 = A::class
|
||||
if (clz === clz2) return "OK"
|
||||
return "Fail"
|
||||
}
|
||||
+12
@@ -41267,6 +41267,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("jvmKPackageCaching.kt")
|
||||
public void testJvmKPackageCaching() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/jvmKPackageCaching.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("jvmKTypeCaching.kt")
|
||||
public void testJvmKTypeCaching() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/jvmKTypeCaching.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+7
-1
@@ -5,13 +5,19 @@
|
||||
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import kotlin.reflect.KDeclarationContainer
|
||||
|
||||
|
||||
private val K_CLASS_CACHE = createCache { KClassImpl(it) }
|
||||
private val K_PACKAGE_CACHE = createCache { KPackageImpl(it) }
|
||||
|
||||
// This function is invoked on each reflection access to Java classes, properties, etc. Performance is critical here.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal fun <T : Any> getOrCreateKotlinClass(jClass: Class<T>): KClassImpl<T> = K_CLASS_CACHE.get(jClass) as KClassImpl<T>
|
||||
|
||||
internal fun clearKClassCache() {
|
||||
internal fun <T : Any> getOrCreateKotlinPackage(jClass: Class<T>): KDeclarationContainer = K_PACKAGE_CACHE.get(jClass)
|
||||
|
||||
internal fun clearCaches() {
|
||||
K_CLASS_CACHE.clear()
|
||||
K_PACKAGE_CACHE.clear()
|
||||
}
|
||||
@@ -37,7 +37,6 @@ import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.D
|
||||
|
||||
internal class KPackageImpl(
|
||||
override val jClass: Class<*>,
|
||||
@Suppress("unused") val usageModuleName: String? = null // may be useful for debug
|
||||
) : KDeclarationContainerImpl() {
|
||||
private inner class Data : KDeclarationContainerImpl.Data() {
|
||||
private val kotlinClass: ReflectKotlinClass? by ReflectProperties.lazySoft {
|
||||
|
||||
@@ -32,17 +32,18 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
|
||||
|
||||
@Override
|
||||
public KDeclarationContainer getOrCreateKotlinPackage(Class javaClass, String moduleName) {
|
||||
return new KPackageImpl(javaClass, moduleName);
|
||||
// moduleName is unused deliberately and only left in public ABI
|
||||
return ClassCachesKt.getOrCreateKotlinPackage(javaClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KClass getOrCreateKotlinClass(Class javaClass) {
|
||||
return KClassCacheKt.getOrCreateKotlinClass(javaClass);
|
||||
return ClassCachesKt.getOrCreateKotlinClass(javaClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KClass getOrCreateKotlinClass(Class javaClass, String internalName) {
|
||||
return KClassCacheKt.getOrCreateKotlinClass(javaClass);
|
||||
return ClassCachesKt.getOrCreateKotlinClass(javaClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,7 +155,7 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
|
||||
// Misc
|
||||
|
||||
public static void clearCaches() {
|
||||
KClassCacheKt.clearKClassCache();
|
||||
ClassCachesKt.clearCaches();
|
||||
ModuleByClassLoaderKt.clearModuleByClassLoaderCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public class Reflection {
|
||||
}
|
||||
|
||||
public static KDeclarationContainer getOrCreateKotlinPackage(Class javaClass, String moduleName) {
|
||||
// This signature cannot be removed as it is used in FunctionReferenceLowering.kt non-directly
|
||||
return factory.getOrCreateKotlinPackage(javaClass, moduleName);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user