/* * 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.ui.sandbox; 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.ui.filechooser.FileChooserList; import org.adoptopenjdk.jitwatch.ui.stage.IStageClosedListener; import org.adoptopenjdk.jitwatch.util.DisassemblyUtil; import org.adoptopenjdk.jitwatch.util.UserInterfaceUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.stage.StageStyle; public class SandboxConfigStage extends Stage { private static final String DEFAULT_DISPLAY_STYLE = "-fx-padding:0px 8px 0px 0px"; private TextField txtFreqInline; private TextField txtMaxInline; private TextField txtCompilerThreshold; private TextField txtExtraSwitches; private CheckBox checkBoxPrintAssembly; private CheckBox checkBoxDisableInlining; private IStageClosedListener closedListener; private JITWatchConfig config; private FileChooserList chooserClasses; private VMLanguageList vmLanguageList; private Scene scene; private static final int labelWidth = 160; private static final Logger logger = LoggerFactory.getLogger(SandboxConfigStage.class); public SandboxConfigStage(final IStageClosedListener closedListener, final JITWatchConfig config) { this.closedListener = closedListener; this.config = config; initStyle(StageStyle.UTILITY); VBox vbox = new VBox(); scene = UserInterfaceUtil.getScene(vbox, 620, 550); setScene(scene); vbox.setPadding(new Insets(2, 8, 2, 8)); vbox.setSpacing(12); chooserClasses = new FileChooserList(this, "Compile and Runtime Classpath", config.getConfiguredClassLocations()); chooserClasses.prefHeightProperty().bind(this.heightProperty().multiply(0.25)); Label lblConfigLangs = new Label("Configure VM Languages"); vmLanguageList = new VMLanguageList(this, config); vbox.getChildren().add(chooserClasses); vbox.getChildren().add(lblConfigLangs); vbox.getChildren().add(vmLanguageList); vbox.getChildren().add(buildHBoxAssemblySyntax()); vbox.getChildren().add(buildHBoxTieredCompilation()); vbox.getChildren().add(buildHBoxCompressedOops()); vbox.getChildren().add(buildHBoxBackgroundCompilation()); vbox.getChildren().add(buildHBoxOnStackReplacement()); vbox.getChildren().add(buildHBoxInliningSettings()); vbox.getChildren().add(buildHBoxCompilationThreshold()); vbox.getChildren().add(buildHBoxExtraSwitches()); vbox.getChildren().add(buildHBoxButtons()); setTitle("Sandbox Configuration"); } private EventHandler<ActionEvent> getEventHandlerForSaveButton() { return new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { config.setClassLocations(chooserClasses.getFiles()); setFrequencyOfInlineSize(config); setMaximumInlineSize(config); setCompilerThreshold(config); setExtraVMSwitches(config); config.setPrintAssembly(checkBoxPrintAssembly.isSelected()); config.setDisableInlining(checkBoxDisableInlining.isSelected()); config.saveConfig(); closedListener.handleStageClosed(SandboxConfigStage.this); close(); } }; } private EventHandler<ActionEvent> getEventHandlerForCancelButton() { return new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { closedListener.handleStageClosed(SandboxConfigStage.this); close(); } }; } private void setCompilerThreshold(JITWatchConfig config) { try { config.setCompileThreshold(Integer.parseInt(txtCompilerThreshold.getText())); } catch (NumberFormatException nfe) { logger.error("Bad CompilerThreshold value", nfe); } } private void setExtraVMSwitches(JITWatchConfig config) { config.setExtraVMSwitches(txtExtraSwitches.getText().trim()); } private void setMaximumInlineSize(JITWatchConfig config) { try { config.setMaxInlineSize(Integer.parseInt(txtMaxInline.getText())); } catch (NumberFormatException nfe) { logger.error("Bad MaxInlineSize value", nfe); } } private void setFrequencyOfInlineSize(JITWatchConfig config) { try { config.setFreqInlineSize(Integer.parseInt(txtFreqInline.getText())); } catch (NumberFormatException nfe) { logger.error("Bad FreqInlineSize value", nfe); } } private HBox buildHBoxAssemblySyntax() { final RadioButton rbATT = new RadioButton("AT&T syntax"); final RadioButton rbIntel = new RadioButton("Intel syntax"); final ToggleGroup groupAssemblySyntax = new ToggleGroup(); boolean intelMode = config.isSandboxIntelMode(); rbATT.setToggleGroup(groupAssemblySyntax); rbIntel.setToggleGroup(groupAssemblySyntax); rbATT.setStyle(DEFAULT_DISPLAY_STYLE); rbATT.setSelected(!intelMode); rbIntel.setSelected(intelMode); groupAssemblySyntax.selectedToggleProperty() .addListener(getChangeListenerForGroupAssemblySyntax(rbIntel, groupAssemblySyntax)); HBox hbox = new HBox(); hbox.getChildren().add(buildCheckBoxPrintAssembly()); hbox.getChildren().add(rbATT); hbox.getChildren().add(rbIntel); return hbox; } private ChangeListener<Toggle> getChangeListenerForGroupAssemblySyntax(final RadioButton rbIntel, final ToggleGroup groupAssemblySyntax) { return new ChangeListener<Toggle>() { @Override public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1, Toggle arg2) { if (groupAssemblySyntax.getSelectedToggle() != null) { boolean nextIntelMode = groupAssemblySyntax.getSelectedToggle().equals(rbIntel); config.setSandboxIntelMode(nextIntelMode); } } }; } private HBox buildHBoxTieredCompilation() { final RadioButton rbVMDefault = new RadioButton("VM Default"); final RadioButton rbForceTiered = new RadioButton("Always"); rbForceTiered.setTooltip(new Tooltip("-XX:+TieredCompilation")); final RadioButton rbForceNoTiered = new RadioButton("Never"); rbForceNoTiered.setTooltip(new Tooltip("-XX:-TieredCompilation")); final ToggleGroup groupTiered = new ToggleGroup(); rbVMDefault.setStyle(DEFAULT_DISPLAY_STYLE); rbForceTiered.setStyle(DEFAULT_DISPLAY_STYLE); TieredCompilation tieredMode = config.getTieredCompilationMode(); switch (tieredMode) { case VM_DEFAULT: rbVMDefault.setSelected(true); rbForceTiered.setSelected(false); rbForceNoTiered.setSelected(false); break; case FORCE_TIERED: rbVMDefault.setSelected(false); rbForceTiered.setSelected(true); rbForceNoTiered.setSelected(false); break; case FORCE_NO_TIERED: rbVMDefault.setSelected(false); rbForceTiered.setSelected(false); rbForceNoTiered.setSelected(true); break; } rbVMDefault.setToggleGroup(groupTiered); rbForceTiered.setToggleGroup(groupTiered); rbForceNoTiered.setToggleGroup(groupTiered); groupTiered.selectedToggleProperty() .addListener(getChangeListenerForGroupTiered(rbVMDefault, rbForceTiered, rbForceNoTiered, groupTiered)); HBox hbox = new HBox(); Label lblMode = new Label("Tiered Compilation:"); lblMode.setMinWidth(labelWidth); hbox.getChildren().add(lblMode); hbox.getChildren().add(rbVMDefault); hbox.getChildren().add(rbForceTiered); hbox.getChildren().add(rbForceNoTiered); return hbox; } private ChangeListener<Toggle> getChangeListenerForGroupTiered(final RadioButton rbVMDefault, final RadioButton rbForceTiered, final RadioButton rbForceNoTiered, final ToggleGroup groupTiered) { return new ChangeListener<Toggle>() { @Override public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1, Toggle arg2) { Toggle selectedToggle = groupTiered.getSelectedToggle(); if (selectedToggle != null) { if (selectedToggle.equals(rbForceNoTiered)) { config.setTieredCompilationMode(TieredCompilation.FORCE_NO_TIERED); } else if (selectedToggle.equals(rbForceTiered)) { config.setTieredCompilationMode(TieredCompilation.FORCE_TIERED); } else if (selectedToggle.equals(rbVMDefault)) { config.setTieredCompilationMode(TieredCompilation.VM_DEFAULT); } } } }; } private HBox buildHBoxCompressedOops() { final RadioButton rbVMDefault = new RadioButton("VM Default"); final RadioButton rbForceCompressed = new RadioButton("Always"); rbForceCompressed.setTooltip(new Tooltip("-XX:+UseCompressedOops")); final RadioButton rbForceNoCompressed = new RadioButton("Never"); rbForceNoCompressed.setTooltip(new Tooltip("-XX:-UseCompressedOops")); final ToggleGroup groupOops = new ToggleGroup(); rbVMDefault.setStyle(DEFAULT_DISPLAY_STYLE); rbForceCompressed.setStyle(DEFAULT_DISPLAY_STYLE); CompressedOops oopsMode = config.getCompressedOopsMode(); switch (oopsMode) { case VM_DEFAULT: rbVMDefault.setSelected(true); rbForceCompressed.setSelected(false); rbForceNoCompressed.setSelected(false); break; case FORCE_COMPRESSED: rbVMDefault.setSelected(false); rbForceCompressed.setSelected(true); rbForceNoCompressed.setSelected(false); break; case FORCE_NO_COMPRESSED: rbVMDefault.setSelected(false); rbForceCompressed.setSelected(false); rbForceNoCompressed.setSelected(true); break; } rbVMDefault.setToggleGroup(groupOops); rbForceCompressed.setToggleGroup(groupOops); rbForceNoCompressed.setToggleGroup(groupOops); groupOops.selectedToggleProperty() .addListener(getChangeListenerForGroupOops(rbVMDefault, rbForceCompressed, rbForceNoCompressed, groupOops)); HBox hbox = new HBox(); Label lblMode = new Label("Compressed Oops:"); lblMode.setMinWidth(labelWidth); hbox.getChildren().add(lblMode); hbox.getChildren().add(rbVMDefault); hbox.getChildren().add(rbForceCompressed); hbox.getChildren().add(rbForceNoCompressed); return hbox; } private HBox buildHBoxBackgroundCompilation() { final RadioButton rbVMDefault = new RadioButton("VM Default"); final RadioButton rbForceBackgroundCompilation = new RadioButton("Always"); rbForceBackgroundCompilation.setTooltip(new Tooltip("-XX:+BackgroundCompilation")); final RadioButton rbForceNoBackgroundCompilation = new RadioButton("Never"); rbForceNoBackgroundCompilation.setTooltip(new Tooltip("-XX:-BackgroundCompilation")); final ToggleGroup groupBackgroundCompilation = new ToggleGroup(); rbVMDefault.setStyle(DEFAULT_DISPLAY_STYLE); rbForceBackgroundCompilation.setStyle(DEFAULT_DISPLAY_STYLE); BackgroundCompilation backgroundCompilationMode = config.getBackgroundCompilationMode(); switch (backgroundCompilationMode) { case VM_DEFAULT: rbVMDefault.setSelected(true); rbForceBackgroundCompilation.setSelected(false); rbForceNoBackgroundCompilation.setSelected(false); break; case FORCE_BACKGROUND_COMPILATION: rbVMDefault.setSelected(false); rbForceBackgroundCompilation.setSelected(true); rbForceNoBackgroundCompilation.setSelected(false); break; case FORCE_NO_BACKGROUND_COMPILATION: rbVMDefault.setSelected(false); rbForceBackgroundCompilation.setSelected(false); rbForceNoBackgroundCompilation.setSelected(true); break; } rbVMDefault.setToggleGroup(groupBackgroundCompilation); rbForceBackgroundCompilation.setToggleGroup(groupBackgroundCompilation); rbForceNoBackgroundCompilation.setToggleGroup(groupBackgroundCompilation); groupBackgroundCompilation.selectedToggleProperty().addListener(getChangeListenerForBackgroundCompilation(rbVMDefault, rbForceBackgroundCompilation, rbForceNoBackgroundCompilation, groupBackgroundCompilation)); HBox hbox = new HBox(); Label lblMode = new Label("Background JIT:"); lblMode.setMinWidth(labelWidth); hbox.getChildren().add(lblMode); hbox.getChildren().add(rbVMDefault); hbox.getChildren().add(rbForceBackgroundCompilation); hbox.getChildren().add(rbForceNoBackgroundCompilation); return hbox; } private HBox buildHBoxOnStackReplacement() { final RadioButton rbVMDefault = new RadioButton("VM Default"); final RadioButton rbAlways = new RadioButton("Always"); rbAlways.setTooltip(new Tooltip("-XX:+OnStackReplacement")); final RadioButton rbNever = new RadioButton("Never"); rbNever.setTooltip(new Tooltip("-XX:-OnStackReplacement")); final ToggleGroup group = new ToggleGroup(); rbVMDefault.setStyle(DEFAULT_DISPLAY_STYLE); rbAlways.setStyle(DEFAULT_DISPLAY_STYLE); OnStackReplacement osrMode = config.getOnStackReplacementMode(); switch (osrMode) { case VM_DEFAULT: rbVMDefault.setSelected(true); rbAlways.setSelected(false); rbNever.setSelected(false); break; case FORCE_ON_STACK_REPLACEMENT: rbVMDefault.setSelected(false); rbAlways.setSelected(true); rbNever.setSelected(false); break; case FORCE_NO_ON_STACK_REPLACEMENT: rbVMDefault.setSelected(false); rbAlways.setSelected(false); rbNever.setSelected(true); break; } rbVMDefault.setToggleGroup(group); rbAlways.setToggleGroup(group); rbNever.setToggleGroup(group); group.selectedToggleProperty().addListener(getChangeListenerForOnStackReplacement(rbVMDefault, rbAlways, rbNever, group)); HBox hbox = new HBox(); Label lblMode = new Label("On Stack Replacement:"); lblMode.setMinWidth(labelWidth); hbox.getChildren().add(lblMode); hbox.getChildren().add(rbVMDefault); hbox.getChildren().add(rbAlways); hbox.getChildren().add(rbNever); return hbox; } private HBox buildHBoxInliningSettings() { HBox hbox = new HBox(); hbox.setSpacing(20); hbox.getChildren().add(buildCheckBoxDisableInlining()); buildHBoxFreqInline(hbox); buildHBoxMaxInline(hbox); return hbox; } private HBox buildHBoxCompilationThreshold() { HBox hbox = new HBox(); Label labelThreshold = new Label("Compile Threshold:"); labelThreshold.setTooltip(new Tooltip("-XX:CompileThreshold")); labelThreshold.setMinWidth(labelWidth); txtCompilerThreshold = new TextField(Integer.toString(config.getCompileThreshold())); txtCompilerThreshold.setMaxWidth(60); txtCompilerThreshold.setAlignment(Pos.BASELINE_RIGHT); hbox.getChildren().add(labelThreshold); hbox.getChildren().add(txtCompilerThreshold); return hbox; } private HBox buildHBoxExtraSwitches() { HBox hbox = new HBox(); Label labelExtra = new Label("Extra VM switches:"); labelExtra.setMinWidth(labelWidth); txtExtraSwitches = new TextField(config.getExtraVMSwitches()); txtExtraSwitches.prefWidthProperty().bind(scene.widthProperty()); txtExtraSwitches.setAlignment(Pos.BASELINE_LEFT); hbox.getChildren().add(labelExtra); hbox.getChildren().add(txtExtraSwitches); return hbox; } private ChangeListener<Toggle> getChangeListenerForGroupOops(final RadioButton rbVMDefault, final RadioButton rbForceCompressed, final RadioButton rbForceNoCompressed, final ToggleGroup groupOops) { return new ChangeListener<Toggle>() { @Override public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1, Toggle arg2) { Toggle selectedToggle = groupOops.getSelectedToggle(); if (selectedToggle != null) { if (selectedToggle.equals(rbForceNoCompressed)) { config.setCompressedOopsMode(CompressedOops.FORCE_NO_COMPRESSED); } else if (selectedToggle.equals(rbForceCompressed)) { config.setCompressedOopsMode(CompressedOops.FORCE_COMPRESSED); } else if (selectedToggle.equals(rbVMDefault)) { config.setCompressedOopsMode(CompressedOops.VM_DEFAULT); } } } }; } private ChangeListener<Toggle> getChangeListenerForBackgroundCompilation(final RadioButton rbVMDefault, final RadioButton rbForceBackgroundCompilation, final RadioButton rbForceNoBackgroundCompilation, final ToggleGroup groupBackgroundCompilation) { return new ChangeListener<Toggle>() { @Override public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1, Toggle arg2) { Toggle selectedToggle = groupBackgroundCompilation.getSelectedToggle(); if (selectedToggle != null) { if (selectedToggle.equals(rbForceBackgroundCompilation)) { config.setBackgroundCompilationMode(BackgroundCompilation.FORCE_BACKGROUND_COMPILATION); } else if (selectedToggle.equals(rbForceNoBackgroundCompilation)) { config.setBackgroundCompilationMode(BackgroundCompilation.FORCE_NO_BACKGROUND_COMPILATION); } else if (selectedToggle.equals(rbVMDefault)) { config.setBackgroundCompilationMode(BackgroundCompilation.VM_DEFAULT); } } } }; } private ChangeListener<Toggle> getChangeListenerForOnStackReplacement(final RadioButton rbVMDefault, final RadioButton rbAlways, final RadioButton rbNever, final ToggleGroup group) { return new ChangeListener<Toggle>() { @Override public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1, Toggle arg2) { Toggle selectedToggle = group.getSelectedToggle(); if (selectedToggle != null) { if (selectedToggle.equals(rbAlways)) { config.setOnStackReplacementMode(OnStackReplacement.FORCE_ON_STACK_REPLACEMENT); } else if (selectedToggle.equals(rbNever)) { config.setOnStackReplacementMode(OnStackReplacement.FORCE_NO_ON_STACK_REPLACEMENT); } else if (selectedToggle.equals(rbVMDefault)) { config.setOnStackReplacementMode(OnStackReplacement.VM_DEFAULT); } } } }; } private void buildHBoxFreqInline(HBox hbCompilerSettings) { txtFreqInline = new TextField(Integer.toString(config.getFreqInlineSize())); txtFreqInline.setMaxWidth(50); txtFreqInline.setAlignment(Pos.BASELINE_RIGHT); txtFreqInline.setDisable(config.isDisableInlining()); Label label = new Label("FreqInlineSize:"); label.setTooltip(new Tooltip("-XX:FreqInlineSize")); hbCompilerSettings.getChildren().add(label); hbCompilerSettings.getChildren().add(txtFreqInline); } private void buildHBoxMaxInline(HBox hbCompilerSettings) { txtMaxInline = new TextField(Integer.toString(config.getMaxInlineSize())); txtMaxInline.setMaxWidth(50); txtMaxInline.setAlignment(Pos.BASELINE_RIGHT); txtMaxInline.setDisable(config.isDisableInlining()); Label label = new Label("MaxInlineSize:"); label.setTooltip(new Tooltip("-XX:MaxInlineSize")); hbCompilerSettings.getChildren().add(label); hbCompilerSettings.getChildren().add(txtMaxInline); } private CheckBox buildCheckBoxPrintAssembly() { checkBoxPrintAssembly = new CheckBox("Show Disassembly"); checkBoxPrintAssembly.setMinWidth(labelWidth); boolean checked = false; if (DisassemblyUtil.isDisassemblerAvailable()) { if (config.isPrintAssembly()) { checked = true; } } else { checkBoxPrintAssembly.setDisable(true); } checkBoxPrintAssembly.setSelected(checked); return checkBoxPrintAssembly; } private CheckBox buildCheckBoxDisableInlining() { checkBoxDisableInlining = new CheckBox("Disable Inlining"); checkBoxDisableInlining.setTooltip(new Tooltip("-XX:-Inline")); checkBoxDisableInlining.setMinWidth(labelWidth - 20); checkBoxDisableInlining.setSelected(config.isDisableInlining()); checkBoxDisableInlining.selectedProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean oldVal, Boolean newVal) { txtFreqInline.setDisable(newVal); txtMaxInline.setDisable(newVal); } }); return checkBoxDisableInlining; } private HBox buildHBoxButtons() { HBox hbox = new HBox(); hbox.setSpacing(20); hbox.setPadding(new Insets(0, 10, 0, 10)); hbox.setAlignment(Pos.CENTER); Button btnSave = new Button("Save"); Button btnCancel = new Button("Cancel"); btnSave.setOnAction(getEventHandlerForSaveButton()); btnCancel.setOnAction(getEventHandlerForCancelButton()); hbox.getChildren().add(btnCancel); hbox.getChildren().add(btnSave); return hbox; } }