diff --git a/core/runtime.jvm/src/kotlin/reflect/jvm/internal/util.kt b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/util.kt index cf150b786b3..420555dafb1 100644 --- a/core/runtime.jvm/src/kotlin/reflect/jvm/internal/util.kt +++ b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/util.kt @@ -16,8 +16,9 @@ package kotlin.reflect.jvm.internal +import java.lang.ref.WeakReference import java.lang.reflect.Method -import java.util.concurrent.ConcurrentHashMap +import java.util.Arrays import kotlin.reflect.jvm.internal.pcollections.HashPMap // TODO: use stdlib? @@ -47,15 +48,34 @@ private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: } -// TODO: should use weak references -private var foreignKClasses = HashPMap.empty, KClassImpl<*>>()!! +// TODO: collect nulls periodically +private var FOREIGN_K_CLASSES = HashPMap.empty>>>()!! fun foreignKotlinClass(jClass: Class): KClassImpl { - val cached = foreignKClasses[jClass] as? KClassImpl - if (cached != null) return cached - val result = KClassImpl(jClass) - foreignKClasses = foreignKClasses.plus(jClass, result)!! - return result + val name = jClass.getName() + val cached = FOREIGN_K_CLASSES[name] + if (cached != null) { + var i = cached.size - 1 + while (i >= 0) { + val kClass = cached[i].get() + if (kClass?.jClass == jClass) { + return kClass as KClassImpl + } + i-- + } + + val newArray = Arrays.copyOf(cached, cached.size + 1) as Array>> + val newKClass = KClassImpl(jClass) + newArray[cached.size] = WeakReference(newKClass) + FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray)!! + return newKClass + } + + val newKClass = KClassImpl(jClass) + val newArray = arrayOfNulls>>(1) + newArray[0] = WeakReference(newKClass) + FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray as Array>>)!! + return newKClass } private val K_OBJECT_CLASS = Class.forName("kotlin.jvm.internal.KObject")