From 5d59ae64c27f4248a1b36a263d560dcbf8d129c7 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 6 Dec 2012 13:10:00 +0100 Subject: [PATCH] external build: profiling mode support --- .../compiler/server/BuildManager.java | 19 +++++-- .../jetbrains/jps/cmdline/BuildSession.java | 9 +++ .../jps/cmdline/ProfilingHelper.java | 56 +++++++++++++++++++ .../org/jetbrains/jps/incremental/Utils.java | 1 + 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 jps/jps-builders/src/org/jetbrains/jps/cmdline/ProfilingHelper.java diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 0c8e38be00f9..1d177b699d5a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -770,11 +770,16 @@ public class BuildManager implements ApplicationComponent{ } cmdLine.addParameter("-D"+ GlobalOptions.COMPILE_PARALLEL_OPTION +"=" + Boolean.toString(config.PARALLEL_COMPILATION)); + boolean isProfilingMode = false; final String additionalOptions = config.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS; if (!StringUtil.isEmpty(additionalOptions)) { final StringTokenizer tokenizer = new StringTokenizer(additionalOptions, " ", false); while (tokenizer.hasMoreTokens()) { - cmdLine.addParameter(tokenizer.nextToken()); + final String option = tokenizer.nextToken(); + if ("-Dprofiling.mode=true".equals(option)) { + isProfilingMode = true; + } + cmdLine.addParameter(option); } } @@ -803,9 +808,17 @@ public class BuildManager implements ApplicationComponent{ } } + final File workDirectory = getBuildSystemDirectory(); + workDirectory.mkdirs(); + ensureLogConfigExists(workDirectory); + final List cp = ClasspathBootstrap.getBuildProcessApplicationClasspath(); cp.add(compilerPath); cp.addAll(myClasspathManager.getCompileServerPluginsClasspath(project)); + if (isProfilingMode) { + cp.add(new File(workDirectory, "yjp-controller-api-redist.jar").getPath()); + cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,sessionname=ExternalBuild"); + } cmdLine.addParameter("-classpath"); cmdLine.addParameter(classpathToString(cp)); @@ -815,10 +828,6 @@ public class BuildManager implements ApplicationComponent{ cmdLine.addParameter(Integer.toString(port)); cmdLine.addParameter(sessionId.toString()); - final File workDirectory = getBuildSystemDirectory(); - workDirectory.mkdirs(); - ensureLogConfigExists(workDirectory); - cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath())); cmdLine.setWorkDirectory(workDirectory); diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index 8338c3963098..04c02ef9e59a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -91,6 +91,11 @@ final class BuildSession implements Runnable, CanceledStatus { final Ref hasErrors = new Ref(false); final Ref doneSomething = new Ref(false); try { + ProfilingHelper profilingHelper = null; + if (Utils.IS_PROFILING_MODE) { + profilingHelper = new ProfilingHelper(); + } + runBuild(new MessageHandler() { public void processMessage(BuildMessage buildMessage) { final CmdlineRemoteProto.Message.BuilderMessage response; @@ -132,6 +137,10 @@ final class BuildSession implements Runnable, CanceledStatus { } } }, this); + + if (profilingHelper != null) { + profilingHelper.stopProfiling(); + } } catch (Throwable e) { LOG.info(e); diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ProfilingHelper.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ProfilingHelper.java new file mode 100644 index 000000000000..cd2b94c4b473 --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ProfilingHelper.java @@ -0,0 +1,56 @@ +package org.jetbrains.jps.cmdline; + +import java.lang.reflect.Method; + +/** + * @author Eugene Zhuravlev + * Date: 12/6/12 + */ +class ProfilingHelper { + + private final Class myControllerClass; + private final Object myController; + + ProfilingHelper() throws Exception { + myControllerClass = Class.forName("com.yourkit.api.Controller"); + myController = myControllerClass.newInstance(); + } + + public void startProfiling() { + try { + final Method startMethod = myControllerClass.getDeclaredMethod("startCPUProfiling", long.class, String.class); + if (startMethod != null) { + startMethod.invoke(myController, 4L/*ProfilingModes.CPU_SAMPLING*/, null); + } + else { + System.err.println("Cannot find method 'startCPUProfiling' in class " + myControllerClass.getName()); + } + } + catch (Throwable e) { + e.printStackTrace(); + } + } + + public void stopProfiling() { + try { + final Method captureMethod = myControllerClass.getDeclaredMethod("captureSnapshot", long.class); + if (captureMethod != null) { + final String path = (String)captureMethod.invoke(myController, 0L/*ProfilingModes.SNAPSHOT_WITHOUT_HEAP*/); + System.err.println("CPU Snapshot captured: " + path); + final Method stopMethod = myControllerClass.getDeclaredMethod("stopCPUProfiling"); + if (stopMethod != null) { + stopMethod.invoke(myController); + } + else { + System.err.println("Cannot find method 'stopCPUProfiling' in class " + myControllerClass.getName()); + } + } + else { + System.err.println("Cannot find method 'captureSnapshot' in class " + myControllerClass.getName()); + } + } + catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java index 95c9c43718bf..331e42ac5d8a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java @@ -24,6 +24,7 @@ public class Utils { public static final Key ERRORS_DETECTED_KEY = Key.create("_errors_detected_"); private static volatile File ourSystemRoot = new File(System.getProperty("user.home"), ".idea-build"); public static final boolean IS_TEST_MODE = Boolean.parseBoolean(System.getProperty("test.mode", "false")); + public static final boolean IS_PROFILING_MODE = Boolean.parseBoolean(System.getProperty("profiling.mode", "false")); private Utils() { }