Fix permgen problems with script launching by avoiding reflection as much as possible

This commit is contained in:
Ilya Chernikov
2016-05-04 12:43:50 +02:00
parent b9ea9513b1
commit 956bcf6d7a
2 changed files with 17 additions and 13 deletions
@@ -225,9 +225,8 @@ object KotlinToJVMBytecodeCompiler {
try {
try {
tryConstructClass(scriptClass.kotlin, scriptArgs)
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n" +
"\tconstructors: \n\t\t${scriptClass.kotlin.constructors.joinToString("\n\t\t", "(") { it.parameters.joinToString { it.type.toString() } }}")
tryConstructClass(scriptClass, scriptArgs)
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
}
finally {
// NB: these lines are required (see KT-9546) but aren't covered by tests
@@ -260,9 +259,9 @@ object KotlinToJVMBytecodeCompiler {
}
@TestOnly
fun tryConstructClassPub(scriptClass: KClass<out Any>, scriptArgs: List<String>): Any? = tryConstructClass(scriptClass, scriptArgs)
fun tryConstructClassPub(scriptClass: Class<*>, scriptArgs: List<String>): Any? = tryConstructClass(scriptClass, scriptArgs)
private fun tryConstructClass(scriptClass: KClass<out Any>, scriptArgs: List<String>): Any? {
private fun tryConstructClass(scriptClass: Class<*>, scriptArgs: List<String>): Any? {
fun convertPrimitive(type: KType?, arg: String): Any? =
when (type) {
@@ -312,10 +311,15 @@ object KotlinToJVMBytecodeCompiler {
return state
}
for (ctor in scriptClass.constructors) {
val (ctorArgs, scriptArgsLeft) = ctor.parameters.fold(Pair(emptyList<Any>(), scriptArgs), ::foldingFunc)
if (ctorArgs.size == ctor.parameters.size && (scriptArgsLeft == null || scriptArgsLeft.isEmpty()))
return ctor.call(*ctorArgs.toTypedArray())
try {
return scriptClass.getConstructor(Array<String>::class.java).newInstance(*arrayOf<Any>(scriptArgs.toTypedArray()))
}
catch (e: java.lang.NoSuchMethodException) {
for (ctor in scriptClass.kotlin.constructors) {
val (ctorArgs, scriptArgsLeft) = ctor.parameters.fold(Pair(emptyList<Any>(), scriptArgs), ::foldingFunc)
if (ctorArgs.size == ctor.parameters.size && (scriptArgsLeft == null || scriptArgsLeft.isEmpty()))
return ctor.call(*ctorArgs.toTypedArray())
}
}
return null
}
@@ -53,7 +53,7 @@ class ScriptTest {
fun testStandardScriptWithParams() {
val aClass = compileScript("fib_std.kts", StandardScriptDefinition)
Assert.assertNotNull(aClass)
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, listOf("4", "comment"))
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, listOf("4", "comment"))
Assert.assertNotNull(anObj)
}
@@ -61,7 +61,7 @@ class ScriptTest {
fun testStandardScriptWithoutParams() {
val aClass = compileScript("fib_std.kts", StandardScriptDefinition)
Assert.assertNotNull(aClass)
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, emptyList())
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, emptyList())
Assert.assertNotNull(anObj)
}
@@ -69,7 +69,7 @@ class ScriptTest {
fun testScriptWithParamConversion() {
val aClass = compileScript("fib.kts", SimpleParamsTestScriptDefinition(".kts", numIntParam()))
Assert.assertNotNull(aClass)
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, listOf("4"))
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, listOf("4"))
Assert.assertNotNull(anObj)
}
@@ -138,7 +138,7 @@ class ScriptTest {
Assert.assertNotNull(aClass)
var exceptionThrown = false
try {
KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, emptyList())
KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, emptyList())
}
catch (e: InvocationTargetException) {
Assert.assertTrue(e.cause is IllegalStateException)