org.adoptopenjdk.jitwatch.sandbox.Sandbox Maven / Gradle / Ivy
/*
* Copyright (c) 2013-2017 Chris Newland.
* Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD
* Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki
*/
package org.adoptopenjdk.jitwatch.sandbox;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_DOLLAR;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_SPACE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.VM_LANGUAGE_SCALA;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.adoptopenjdk.jitwatch.core.JITWatchConfig;
import org.adoptopenjdk.jitwatch.core.JITWatchConfig.BackgroundCompilation;
import org.adoptopenjdk.jitwatch.core.JITWatchConfig.CompressedOops;
import org.adoptopenjdk.jitwatch.core.JITWatchConfig.OnStackReplacement;
import org.adoptopenjdk.jitwatch.core.JITWatchConfig.TieredCompilation;
import org.adoptopenjdk.jitwatch.core.JITWatchConstants;
import org.adoptopenjdk.jitwatch.jvmlang.LanguageManager;
import org.adoptopenjdk.jitwatch.logger.ILogListener;
import org.adoptopenjdk.jitwatch.model.IMetaMember;
import org.adoptopenjdk.jitwatch.model.IReadOnlyJITDataModel;
import org.adoptopenjdk.jitwatch.model.MetaClass;
import org.adoptopenjdk.jitwatch.parser.ILogParser;
import org.adoptopenjdk.jitwatch.process.IExternalProcess;
import org.adoptopenjdk.jitwatch.process.compiler.ICompiler;
import org.adoptopenjdk.jitwatch.process.runtime.IRuntime;
import org.adoptopenjdk.jitwatch.ui.sandbox.ISandboxStage;
import org.adoptopenjdk.jitwatch.util.FileUtil;
import org.adoptopenjdk.jitwatch.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Sandbox
{
private static final Logger logger = LoggerFactory.getLogger(Sandbox.class);
private ILogListener logListener;
private ISandboxStage sandboxStage;
public static final Path SANDBOX_DIR;
public static final Path SANDBOX_SOURCE_DIR;
public static final Path SANDBOX_CLASS_DIR;
public static final Path PATH_STD_ERR;
public static final Path PATH_STD_OUT;
private static final String SANDBOX_LOGFILE = "sandbox.log";
private File sandboxLogFile = new File(SANDBOX_DIR.toFile(), SANDBOX_LOGFILE);
private ILogParser logParser;
private LanguageManager languageManager;
private IExternalProcess lastProcess;
static
{
String userDir = System.getProperty("user.dir");
SANDBOX_DIR = Paths.get(userDir, "sandbox");
SANDBOX_SOURCE_DIR = Paths.get(SANDBOX_DIR.toString(), "sources");
SANDBOX_CLASS_DIR = Paths.get(SANDBOX_DIR.toString(), "classes");
PATH_STD_ERR = new File(Sandbox.SANDBOX_DIR.toFile(), "sandbox.err").toPath();
PATH_STD_OUT = new File(Sandbox.SANDBOX_DIR.toFile(), "sandbox.out").toPath();
initialise();
}
private static void initialise()
{
File sandboxSources = SANDBOX_SOURCE_DIR.toFile();
if (!sandboxSources.exists())
{
logger.debug("Creating Sandbox source directory {}", sandboxSources);
sandboxSources.mkdirs();
if (sandboxSources.exists())
{
copyExamples();
}
}
File sandboxClasses = SANDBOX_CLASS_DIR.toFile();
if (!sandboxClasses.exists())
{
sandboxClasses.mkdirs();
}
}
public void reset()
{
logger.debug("Resetting Sandbox to default settings");
FileUtil.emptyDir(SANDBOX_DIR.toFile());
initialise();
}
private static void copyExamples()
{
File srcDir = new File("core/src/main/resources/examples");
File dstDir = SANDBOX_SOURCE_DIR.toFile();
logger.debug("Copying Sandbox examples from {} to {}", srcDir, dstDir);
FileUtil.copyFilesToDir(srcDir, dstDir);
}
public Sandbox(ILogParser parser, ILogListener logger, ISandboxStage sandboxStage)
{
this.logParser = parser;
this.logListener = logger;
this.sandboxStage = sandboxStage;
languageManager = new LanguageManager(logParser.getConfig(), logListener);
}
public void runSandbox(String language, List compileList, File fileToRun) throws Exception
{
logListener.handleLogEntry("Running Sandbox");
logListener.handleLogEntry("Language is " + language);
String languagePath = logParser.getConfig().getVMLanguagePath(language);
logListener.handleLogEntry(language + " home dir: " + languagePath);
ICompiler compiler = languageManager.getCompiler(language);
if (compiler == null)
{
logListener.handleErrorEntry(language + " compiler path not set. Please click Configure Sandbox and set up the path.");
return;
}
IRuntime runtime = languageManager.getRuntime(language);
if (runtime == null)
{
logListener.handleErrorEntry(language + " runtime path not set. Please click Configure Sandbox and set up the path.");
return;
}
logListener.handleLogEntry("Compiling: " + StringUtil.listToString(compileList));
lastProcess = compiler;
boolean compiledOK = compiler.compile(compileList, buildUniqueClasspath(logParser.getConfig()), SANDBOX_CLASS_DIR.toFile(),
logListener);
logListener.handleLogEntry("Compilation success: " + compiledOK);
if (compiledOK)
{
String fqClassNameToRun = runtime.getClassToExecute(fileToRun);
lastProcess = runtime;
boolean executionSuccess = executeClass(fqClassNameToRun, runtime, logParser.getConfig().isSandboxIntelMode());
logListener.handleLogEntry("Execution success: " + executionSuccess);
if (executionSuccess)
{
runJITWatch();
if (!logParser.hasParseError())
{
String fqClassNameForTriView = runtime.getClassForTriView(fileToRun);
showTriView(language, fqClassNameForTriView);
}
}
else
{
sandboxStage.showError(runtime.getErrorStream());
}
}
else
{
sandboxStage.showError(compiler.getErrorStream());
}
}
public IExternalProcess getLastProcess()
{
return lastProcess;
}
private List buildUniqueClasspath(JITWatchConfig config)
{
List classpath = new ArrayList<>();
classpath.add(SANDBOX_CLASS_DIR.toString());
for (String path : config.getConfiguredClassLocations())
{
if (!classpath.contains(path))
{
classpath.add(path);
}
}
return classpath;
}
private boolean executeClass(String fqClassName, IRuntime runtime, boolean intelMode) throws Exception
{
List classpath = buildUniqueClasspath(logParser.getConfig());
List options = new ArrayList<>();
options.add("-XX:+UnlockDiagnosticVMOptions");
options.add("-XX:+TraceClassLoading");
options.add("-XX:+LogCompilation");
options.add("-XX:LogFile=" + sandboxLogFile.getCanonicalPath());
if (logParser.getConfig().isPrintAssembly())
{
options.add("-XX:+PrintAssembly");
if (intelMode)
{
options.add("-XX:PrintAssemblyOptions=intel");
}
}
boolean isDisableInlining = logParser.getConfig().isDisableInlining();
if (isDisableInlining)
{
options.add("-XX:-Inline");
}
TieredCompilation tieredMode = logParser.getConfig().getTieredCompilationMode();
if (tieredMode == TieredCompilation.FORCE_TIERED)
{
options.add("-XX:+TieredCompilation");
}
else if (tieredMode == TieredCompilation.FORCE_NO_TIERED)
{
options.add("-XX:-TieredCompilation");
}
CompressedOops oopsMode = logParser.getConfig().getCompressedOopsMode();
if (oopsMode == CompressedOops.FORCE_COMPRESSED)
{
options.add("-XX:+UseCompressedOops");
}
else if (oopsMode == CompressedOops.FORCE_NO_COMPRESSED)
{
options.add("-XX:-UseCompressedOops");
}
BackgroundCompilation backgroundCompilationMode = logParser.getConfig().getBackgroundCompilationMode();
if (backgroundCompilationMode == BackgroundCompilation.FORCE_BACKGROUND_COMPILATION)
{
options.add("-XX:+BackgroundCompilation");
}
else if (backgroundCompilationMode == BackgroundCompilation.FORCE_NO_BACKGROUND_COMPILATION)
{
options.add("-XX:-BackgroundCompilation");
}
OnStackReplacement onStackReplacementMode = logParser.getConfig().getOnStackReplacementMode();
if (onStackReplacementMode == OnStackReplacement.FORCE_ON_STACK_REPLACEMENT)
{
options.add("-XX:+UseOnStackReplacement");
}
else if (onStackReplacementMode == OnStackReplacement.FORCE_NO_ON_STACK_REPLACEMENT)
{
options.add("-XX:-UseOnStackReplacement");
}
if (!isDisableInlining && logParser.getConfig().getFreqInlineSize() != JITWatchConstants.DEFAULT_FREQ_INLINE_SIZE)
{
options.add("-XX:FreqInlineSize=" + logParser.getConfig().getFreqInlineSize());
}
if (!isDisableInlining && logParser.getConfig().getMaxInlineSize() != JITWatchConstants.DEFAULT_MAX_INLINE_SIZE)
{
options.add("-XX:MaxInlineSize=" + logParser.getConfig().getMaxInlineSize());
}
if (logParser.getConfig().getCompileThreshold() != JITWatchConstants.DEFAULT_COMPILER_THRESHOLD)
{
options.add("-XX:CompileThreshold=" + logParser.getConfig().getCompileThreshold());
}
if (logParser.getConfig().getExtraVMSwitches().length() > 0)
{
String extraSwitchString = logParser.getConfig().getExtraVMSwitches();
String[] switches = extraSwitchString.split(S_SPACE);
for (String sw : switches)
{
options.add(sw);
}
}
logListener.handleLogEntry("Executing: " + fqClassName);
logListener.handleLogEntry("Classpath: " + StringUtil.listToString(classpath, File.pathSeparatorChar));
logListener.handleLogEntry("VM options: " + StringUtil.listToString(options));
return runtime.execute(fqClassName, classpath, options, logListener);
}
private void runJITWatch() throws IOException
{
JITWatchConfig config = logParser.getConfig();
List sourceLocations = new ArrayList<>(config.getSourceLocations());
List classLocations = new ArrayList<>(config.getConfiguredClassLocations());
String sandboxSourceDirString = SANDBOX_SOURCE_DIR.toString();
String sandboxClassDirString = SANDBOX_CLASS_DIR.toString();
boolean configChanged = false;
if (!sourceLocations.contains(sandboxSourceDirString))
{
configChanged = true;
sourceLocations.add(sandboxSourceDirString);
}
if (!classLocations.contains(sandboxClassDirString))
{
configChanged = true;
classLocations.add(sandboxClassDirString);
}
File jdkSrcZip = FileUtil.getJDKSourceZip();
if (jdkSrcZip != null)
{
String jdkSourceZipString = jdkSrcZip.toPath().toString();
if (!sourceLocations.contains(jdkSourceZipString))
{
configChanged = true;
sourceLocations.add(jdkSourceZipString);
}
}
config.setSourceLocations(sourceLocations);
config.setClassLocations(classLocations);
if (configChanged)
{
config.saveConfig();
}
logListener.handleLogEntry("Parsing JIT log: " + sandboxLogFile.toString());
logParser.processLogFile(sandboxLogFile, sandboxStage);
logListener.handleLogEntry("Parsing complete");
}
private void showTriView(String language, String openClassInTriView)
{
IReadOnlyJITDataModel model = logParser.getModel();
IMetaMember triViewMember = getMemberForClass(openClassInTriView, model);
if (triViewMember == null && VM_LANGUAGE_SCALA.equals(language) && openClassInTriView.endsWith(S_DOLLAR))
{
// Scala and nothing found for Foo$ so try Foo
triViewMember = getMemberForClass(openClassInTriView.substring(0, openClassInTriView.length() - 1), model);
}
sandboxStage.openTriView(triViewMember);
}
private IMetaMember getMemberForClass(String openClassInTriView, IReadOnlyJITDataModel model)
{
IMetaMember triViewMember = null;
logListener.handleLogEntry("Looking up class: " + openClassInTriView);
MetaClass metaClass = model.getPackageManager().getMetaClass(openClassInTriView);
if (metaClass != null)
{
logListener.handleLogEntry("looking for compiled members of " + metaClass.getFullyQualifiedName());
// select first compiled member if any
List memberList = metaClass.getMetaMembers();
for (IMetaMember mm : memberList)
{
logListener.handleLogEntry("Checking JIT compilation status of " + mm.toString());
if (triViewMember == null)
{
// take the first member encountered
triViewMember = mm;
}
if (mm.isCompiled())
{
// override with the first JIT-compiled member
triViewMember = mm;
break;
}
}
}
return triViewMember;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy