Make KClass instances weak in foreignKClasses

This commit is contained in:
Alexander Udalov
2014-06-10 22:14:25 +04:00
parent a86cfdc5de
commit ef7fbe55cf
@@ -16,8 +16,9 @@
package kotlin.reflect.jvm.internal package kotlin.reflect.jvm.internal
import java.lang.ref.WeakReference
import java.lang.reflect.Method import java.lang.reflect.Method
import java.util.concurrent.ConcurrentHashMap import java.util.Arrays
import kotlin.reflect.jvm.internal.pcollections.HashPMap import kotlin.reflect.jvm.internal.pcollections.HashPMap
// TODO: use stdlib? // TODO: use stdlib?
@@ -47,15 +48,34 @@ private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes:
} }
// TODO: should use weak references // TODO: collect nulls periodically
private var foreignKClasses = HashPMap.empty<Class<*>, KClassImpl<*>>()!! private var FOREIGN_K_CLASSES = HashPMap.empty<String, Array<WeakReference<KClassImpl<*>>>>()!!
fun <T> foreignKotlinClass(jClass: Class<T>): KClassImpl<T> { fun <T> foreignKotlinClass(jClass: Class<T>): KClassImpl<T> {
val cached = foreignKClasses[jClass] as? KClassImpl<T> val name = jClass.getName()
if (cached != null) return cached val cached = FOREIGN_K_CLASSES[name]
val result = KClassImpl<T>(jClass) if (cached != null) {
foreignKClasses = foreignKClasses.plus(jClass, result)!! var i = cached.size - 1
return result while (i >= 0) {
val kClass = cached[i].get()
if (kClass?.jClass == jClass) {
return kClass as KClassImpl<T>
}
i--
}
val newArray = Arrays.copyOf(cached, cached.size + 1) as Array<WeakReference<KClassImpl<*>>>
val newKClass = KClassImpl<T>(jClass)
newArray[cached.size] = WeakReference(newKClass)
FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray)!!
return newKClass
}
val newKClass = KClassImpl<T>(jClass)
val newArray = arrayOfNulls<WeakReference<KClassImpl<*>>>(1)
newArray[0] = WeakReference(newKClass)
FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray as Array<WeakReference<KClassImpl<*>>>)!!
return newKClass
} }
private val K_OBJECT_CLASS = Class.forName("kotlin.jvm.internal.KObject") private val K_OBJECT_CLASS = Class.forName("kotlin.jvm.internal.KObject")