diff --git a/src/main/kotlin/global/InstallationManager.kt b/src/main/kotlin/global/InstallationManager.kt index de7e9c9..0f2733f 100644 --- a/src/main/kotlin/global/InstallationManager.kt +++ b/src/main/kotlin/global/InstallationManager.kt @@ -24,6 +24,7 @@ object InstallationManager { private const val LANGUAGE_AGENT_DOC_ENTRY = "agent-docs/WURST_LANGUAGE.md" private const val GRILL_JAR_NAME = "grill.jar" private const val LEGACY_GRILL_JAR_NAME = "WurstSetup.jar" + private const val COMPACT_OBJECT_HEADERS = "-XX:+UseCompactObjectHeaders" val installDir: Path get() = configuredInstallDir() val compilerDir: Path get() = installDir.resolve("wurst-compiler") @@ -193,7 +194,9 @@ object InstallationManager { fun compilerLaunchCommand(vararg extraArgs: String): Array { val compiler = detectCompilerJar() ?: compilerJar val java = bundledJavaCommand() - return arrayOf(java, "-jar", compiler.toAbsolutePath().toString(), *extraArgs) + // The compiler holds millions of small objects, and the runtime of the distribution carries the base class + // data sharing archive for compact object headers, which a JVM uses only in the header mode it runs with. + return arrayOf(java, COMPACT_OBJECT_HEADERS, "-jar", compiler.toAbsolutePath().toString(), *extraArgs) } private fun bundledJavaCommand(): String { diff --git a/src/test/kotlin/InstallationTests.kt b/src/test/kotlin/InstallationTests.kt index f1412bb..04949d7 100644 --- a/src/test/kotlin/InstallationTests.kt +++ b/src/test/kotlin/InstallationTests.kt @@ -19,6 +19,38 @@ class InstallationTests { assert(InstallationManager.status != InstallationManager.InstallationStatus.NOT_INSTALLED) } + @Test(priority = 8) + fun testCompilerLaunchCommandUsesCompactObjectHeaders() { + val previousInstallDir = System.getProperty("wurst.install.dir") + val installDir = Files.createTempDirectory("wurst-setup-launch") + try { + System.setProperty("wurst.install.dir", installDir.toString()) + Files.createDirectories(InstallationManager.compilerDir) + JarOutputStream(Files.newOutputStream(InstallationManager.compilerJar)).use { } + Files.createDirectories(InstallationManager.bundledJava.parent) + Files.writeString(InstallationManager.bundledJava, "") + InstallationManager.bundledJava.toFile().setExecutable(true) + + // the compiler holds millions of small objects; the runtime of the distribution has the base archive for this mode + Assert.assertEquals( + InstallationManager.compilerLaunchCommand("-build").toList(), + listOf( + InstallationManager.bundledJava.toAbsolutePath().toString(), + "-XX:+UseCompactObjectHeaders", + "-jar", + InstallationManager.compilerJar.toAbsolutePath().toString(), + "-build" + ) + ) + } finally { + if (previousInstallDir == null) { + System.clearProperty("wurst.install.dir") + } else { + System.setProperty("wurst.install.dir", previousInstallDir) + } + } + } + @Test(priority = 8) fun testCompilerWithoutAgentDocsRemovesStaleLanguageDoc() { val previousInstallDir = System.getProperty("wurst.install.dir")