mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cds+ij - cleanup automatic AppCDS enable, cleanup code, prepare for perfTests
GitOrigin-RevId: 6e08233fb3aec173af1d3b1ec1d5d423593316d0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3ecb2cc895
commit
3564675e9c
@@ -104,6 +104,7 @@ public class VMOptions {
|
||||
writeGeneralOptions(
|
||||
Function.<String>identity()
|
||||
.andThen(replaceOrAddOption(Pattern.compile("-Xshare:.*\\r?\\n?"), ""))
|
||||
// we cannot remove "-XX:+UnlockDiagnosticVMOptions", we do not know the reason it was included
|
||||
.andThen(replaceOrAddOption(Pattern.compile("-XX:SharedArchiveFile=.*\\r?\\n?"), ""))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,12 @@ class CDSEnableAction : AnAction("Enable Class Data Sharing") {
|
||||
AppExecutorUtil.getAppExecutorService().execute {
|
||||
ProgressManager.getInstance().run(object : Task.Backgroundable(
|
||||
null,
|
||||
"Configuring Class Data Sharing",
|
||||
"Enable Class Data Sharing (AppCDS)",
|
||||
true,
|
||||
PerformInBackgroundOption.ALWAYS_BACKGROUND
|
||||
) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
indicator.isIndeterminate = true
|
||||
CDSManager.installCDS(indicator)
|
||||
}
|
||||
})
|
||||
@@ -42,11 +43,12 @@ class CDSDisableAction : AnAction("Disable Class Data Sharing") {
|
||||
AppExecutorUtil.getAppExecutorService().execute {
|
||||
ProgressManager.getInstance().run(object : Task.Backgroundable(
|
||||
null,
|
||||
"Uninstalling Class Data Sharing",
|
||||
"Disable Class Data Sharing (AppCDS)",
|
||||
true,
|
||||
PerformInBackgroundOption.ALWAYS_BACKGROUND
|
||||
) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
indicator.isIndeterminate = true
|
||||
CDSManager.removeCDS()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.cds
|
||||
|
||||
import com.google.common.hash.Hashing
|
||||
import com.intellij.diagnostic.VMOptions
|
||||
import com.intellij.execution.process.OSProcessUtil
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.openapi.application.ApplicationInfo
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.ui.playback.PlaybackContext
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.sun.tools.attach.VirtualMachine
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.rejectedPromise
|
||||
import org.jetbrains.concurrency.resolvedPromise
|
||||
import java.io.File
|
||||
import java.lang.management.ManagementFactory
|
||||
import java.nio.file.Files
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
@@ -41,6 +41,11 @@ object CDSManager {
|
||||
return true
|
||||
}
|
||||
|
||||
val isRunningWithCDS: Boolean
|
||||
get() {
|
||||
return isValidEnv && currentCDSArchive != null
|
||||
}
|
||||
|
||||
val canBuildOrUpdateCDS: Boolean
|
||||
get() {
|
||||
if (!isValidEnv) return false
|
||||
@@ -49,20 +54,6 @@ object CDSManager {
|
||||
return !paths.isSame(currentCDSArchive)
|
||||
}
|
||||
|
||||
private val agentPath: File
|
||||
get() {
|
||||
val libPath = File(PathManager.getLibPath()) / "cds" / "classesLogAgent.jar"
|
||||
if (libPath.isFile) return libPath
|
||||
|
||||
LOG.warn("Failed to find bundled CDS classes agent in $libPath")
|
||||
|
||||
//consider local debug IDE case
|
||||
val probe = File(PathManager.getHomePath()) / "out" / "classes" / "artifacts" / "classesLogAgent_jar" / "classesLogAgent.jar"
|
||||
if (probe.isFile) return probe
|
||||
|
||||
error("Failed to resolve path to the CDS agent")
|
||||
}
|
||||
|
||||
private val currentCDSArchive: File?
|
||||
get() {
|
||||
val arguments = ManagementFactory.getRuntimeMXBean().inputArguments
|
||||
@@ -91,20 +82,33 @@ object CDSManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun installCDS(indicator: ProgressIndicator) {
|
||||
fun installCDS(indicator: ProgressIndicator?): CDSPaths? {
|
||||
val paths = CDSPaths.current()
|
||||
if (paths.isSame(currentCDSArchive)) {
|
||||
LOG.info("CDS archive is already generated. Nothing to do")
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
LOG.info("Starting generation of CDS archive to the ${paths.classesArchiveFile} and ${paths.classesArchiveFile} files")
|
||||
|
||||
indicator.text2 = "Collecting classes list..."
|
||||
indicator.checkCanceled()
|
||||
indicator?.text2 = "Collecting classes list..."
|
||||
indicator?.checkCanceled()
|
||||
|
||||
val durationList = measureTimeMillis {
|
||||
try {
|
||||
val agentPath = run {
|
||||
val libPath = File(PathManager.getLibPath()) / "cds" / "classesLogAgent.jar"
|
||||
if (libPath.isFile) return@run libPath
|
||||
|
||||
LOG.warn("Failed to find bundled CDS classes agent in $libPath")
|
||||
|
||||
//consider local debug IDE case
|
||||
val probe = File(PathManager.getHomePath()) / "out" / "classes" / "artifacts" / "classesLogAgent_jar" / "classesLogAgent.jar"
|
||||
if (probe.isFile) return@run probe
|
||||
|
||||
error("Failed to resolve path to the CDS agent")
|
||||
}
|
||||
|
||||
val vm = VirtualMachine.attach(OSProcessUtil.getApplicationPid())
|
||||
try {
|
||||
vm.loadAgent(agentPath.path, "${paths.classesListFile},${paths.classesPathFile}")
|
||||
@@ -115,14 +119,14 @@ object CDSManager {
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
LOG.warn("Failed to attach CDS Java Agent to the running IDE instance. ${t.message}", t)
|
||||
return
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
LOG.info("CDS classes file is generated in ${StringUtil.formatDuration(durationList)}")
|
||||
|
||||
indicator.text2 = "Generating classes archive..."
|
||||
indicator.checkCanceled()
|
||||
indicator?.text2 = "Generating classes archive..."
|
||||
indicator?.checkCanceled()
|
||||
|
||||
val durationLink = measureTimeMillis {
|
||||
val ext = if (SystemInfo.isWindows) ".exe" else ""
|
||||
@@ -140,12 +144,12 @@ object CDSManager {
|
||||
val cwd = File(".").canonicalFile
|
||||
LOG.info("Running CDS generation process: $args in $cwd")
|
||||
|
||||
indicator.checkCanceled()
|
||||
indicator?.checkCanceled()
|
||||
val process = ProcessBuilder().command(args).inheritIO().directory(cwd).start()
|
||||
if (!process.waitFor(10, TimeUnit.MINUTES)) {
|
||||
LOG.warn("Failed to generate CDS archive, the process took too long and will be killed")
|
||||
process.destroyForcibly()
|
||||
return
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,12 +158,35 @@ object CDSManager {
|
||||
"in ${StringUtil.formatDuration(durationLink)}")
|
||||
|
||||
VMOptions.writeEnableCDSArchiveOption(paths.classesArchiveFile.absolutePath)
|
||||
|
||||
return paths
|
||||
}
|
||||
|
||||
fun removeCDS() {
|
||||
LOG.warn("CDS archive is disabled")
|
||||
VMOptions.writeDisableCDSArchiveOption()
|
||||
}
|
||||
}
|
||||
|
||||
private operator fun File.div(s: String) = File(this, s)
|
||||
/**
|
||||
* See com.intellij.openapi.ui.playback.commands.CallCommand
|
||||
*/
|
||||
@JvmStatic
|
||||
@Suppress("unused")
|
||||
fun toggleCDSForPerfTests(@Suppress("UNUSED_PARAMETER") context: PlaybackContext, enableCDS: Boolean): Promise<Any?> =
|
||||
try {
|
||||
if (enableCDS) {
|
||||
val paths = installCDS(null)
|
||||
if (paths == null) rejectedPromise("Failed to install AppCDS, see log for errors")
|
||||
else resolvedPromise<Any?>("ok")
|
||||
}
|
||||
else {
|
||||
removeCDS()
|
||||
resolvedPromise("ok")
|
||||
}
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
rejectedPromise(t)
|
||||
}
|
||||
|
||||
private operator fun File.div(s: String) = File(this, s)
|
||||
}
|
||||
|
||||
@@ -18,8 +18,14 @@ class CDSStartupActivity : StartupActivity {
|
||||
if (!isExecuted.compareAndSet(false, true)) return
|
||||
if (!CDSManager.canBuildOrUpdateCDS) return
|
||||
|
||||
val cdsKey = "intellij.cds.enabled"
|
||||
val cdsEnabled = (System.getProperty(cdsKey, "true")?.toBoolean() == true || Registry.`is`(cdsKey, true))
|
||||
// 1. allow to toggle the feature via -DintelliJ.appCDS.enabled
|
||||
// 2. if not set, use Registry to enable the feature
|
||||
// 3. and finally, fallback to see if we already run with AppCDS
|
||||
val cdsKey = "appcds.enabled"
|
||||
val cdsEnabled = System.getProperty("intellij.$cdsKey")?.toBoolean()
|
||||
?: runCatching {
|
||||
Registry.`is`(cdsKey)
|
||||
}.getOrElse { CDSManager.isRunningWithCDS }
|
||||
|
||||
AppExecutorUtil.getAppExecutorService().execute {
|
||||
ProgressManager.getInstance().run(object : Task.Backgroundable(
|
||||
|
||||
@@ -823,5 +823,6 @@
|
||||
<virtualFileManagerListener implementation="com.intellij.configurationStore.StoreReloadManagerImpl$MyVirtualFileManagerListener"/>
|
||||
|
||||
<postStartupActivity implementation="com.intellij.ide.cds.CDSStartupActivity" order="last"/>
|
||||
<registryKey key="appcds.enabled" defaultValue="false" restartRequired="true" description="Whether IDE should use AppCDS (JRP 310) for faster startup"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
Reference in New Issue
Block a user