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 {
try { try {
tryConstructClass(scriptClass.kotlin, scriptArgs) tryConstructClass(scriptClass, scriptArgs)
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n" + ?: 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() } }}")
} }
finally { finally {
// NB: these lines are required (see KT-9546) but aren't covered by tests // NB: these lines are required (see KT-9546) but aren't covered by tests
@@ -260,9 +259,9 @@ object KotlinToJVMBytecodeCompiler {
} }
@TestOnly @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? = fun convertPrimitive(type: KType?, arg: String): Any? =
when (type) { when (type) {
@@ -312,10 +311,15 @@ object KotlinToJVMBytecodeCompiler {
return state return state
} }
for (ctor in scriptClass.constructors) { try {
val (ctorArgs, scriptArgsLeft) = ctor.parameters.fold(Pair(emptyList<Any>(), scriptArgs), ::foldingFunc) return scriptClass.getConstructor(Array<String>::class.java).newInstance(*arrayOf<Any>(scriptArgs.toTypedArray()))
if (ctorArgs.size == ctor.parameters.size && (scriptArgsLeft == null || scriptArgsLeft.isEmpty())) }
return ctor.call(*ctorArgs.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 return null
} }
@@ -53,7 +53,7 @@ class ScriptTest {
fun testStandardScriptWithParams() { fun testStandardScriptWithParams() {
val aClass = compileScript("fib_std.kts", StandardScriptDefinition) val aClass = compileScript("fib_std.kts", StandardScriptDefinition)
Assert.assertNotNull(aClass) Assert.assertNotNull(aClass)
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, listOf("4", "comment")) val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, listOf("4", "comment"))
Assert.assertNotNull(anObj) Assert.assertNotNull(anObj)
} }
@@ -61,7 +61,7 @@ class ScriptTest {
fun testStandardScriptWithoutParams() { fun testStandardScriptWithoutParams() {
val aClass = compileScript("fib_std.kts", StandardScriptDefinition) val aClass = compileScript("fib_std.kts", StandardScriptDefinition)
Assert.assertNotNull(aClass) Assert.assertNotNull(aClass)
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, emptyList()) val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, emptyList())
Assert.assertNotNull(anObj) Assert.assertNotNull(anObj)
} }
@@ -69,7 +69,7 @@ class ScriptTest {
fun testScriptWithParamConversion() { fun testScriptWithParamConversion() {
val aClass = compileScript("fib.kts", SimpleParamsTestScriptDefinition(".kts", numIntParam())) val aClass = compileScript("fib.kts", SimpleParamsTestScriptDefinition(".kts", numIntParam()))
Assert.assertNotNull(aClass) Assert.assertNotNull(aClass)
val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, listOf("4")) val anObj = KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, listOf("4"))
Assert.assertNotNull(anObj) Assert.assertNotNull(anObj)
} }
@@ -138,7 +138,7 @@ class ScriptTest {
Assert.assertNotNull(aClass) Assert.assertNotNull(aClass)
var exceptionThrown = false var exceptionThrown = false
try { try {
KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!.kotlin, emptyList()) KotlinToJVMBytecodeCompiler.tryConstructClassPub(aClass!!, emptyList())
} }
catch (e: InvocationTargetException) { catch (e: InvocationTargetException) {
Assert.assertTrue(e.cause is IllegalStateException) Assert.assertTrue(e.cause is IllegalStateException)