8283930: IGV: add toggle button to show/hide empty blocks in CFG view

Reviewed-by: kvn, chagedorn
This commit is contained in:
Roberto Castañeda Lozano 2022-04-08 08:41:30 +00:00
parent a445ecd1e9
commit 6028181071
9 changed files with 117 additions and 32 deletions

View File

@ -100,11 +100,6 @@ public class BlockConnection implements Connection {
controlPoints = list;
}
@Override
public boolean isAlwaysVisible() {
return true;
}
@Override
public boolean hasSlots() {
return false;

View File

@ -41,8 +41,6 @@ public interface Connection extends Link {
public String getToolTipText();
public boolean isAlwaysVisible();
public boolean hasSlots();
}

View File

@ -148,11 +148,6 @@ public class FigureConnection implements Connection {
controlPoints = list;
}
@Override
public boolean isAlwaysVisible() {
return false;
}
@Override
public boolean hasSlots() {
return true;

View File

@ -605,17 +605,22 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
}
private boolean isVisible(Connection c) {
if (getModel().getShowCFG()) {
return c.isAlwaysVisible();
// Generally, a connection is visible if its source and destination
// widgets are visible. An exception is Figure connections in the CFG
// view, which are never shown.
if (getModel().getShowCFG() && c instanceof FigureConnection) {
return false;
}
FigureWidget w1 = getWidget(c.getFrom().getVertex());
FigureWidget w2 = getWidget(c.getTo().getVertex());
if (w1.isVisible() && w2.isVisible()) {
return true;
Widget w1, w2;
if (c instanceof BlockConnection) {
w1 = getWidget(((Block)c.getFromCluster()).getInputBlock());
w2 = getWidget(((Block)c.getToCluster()).getInputBlock());
} else {
assert (c instanceof FigureConnection);
w1 = getWidget(c.getFrom().getVertex());
w2 = getWidget(c.getTo().getVertex());
}
return false;
return w1.isVisible() && w2.isVisible();
}
private void relayout(Set<Widget> oldVisibleWidgets) {
@ -697,10 +702,21 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
}
}
}
// Add connections for CFG edges.
edges.addAll(diagram.getBlockConnections());
// Add visible connections for CFG edges.
for (BlockConnection c : diagram.getBlockConnections()) {
if (isVisible(c)) {
edges.add(c);
}
}
m.setSubManager(new LinearLayoutManager(figureRank));
m.setClusters(new HashSet<>(diagram.getBlocks()));
Set<Block> visibleBlocks = new HashSet<>();
for (Block b : diagram.getBlocks()) {
BlockWidget w = getWidget(b.getInputBlock());
if (w.isVisible()) {
visibleBlocks.add(b);
}
}
m.setClusters(new HashSet<>(visibleBlocks));
m.doLayout(new LayoutGraph(edges, figures));
}
@ -795,8 +811,9 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
if (getModel().getShowCFG()) {
for (BlockConnection c : diagram.getBlockConnections()) {
SceneAnimator anim = animator;
processOutputSlot(lastLineCache, null, Collections.singletonList(c), 0, null, null, offx2, offy2, anim);
if (isVisible(c)) {
processOutputSlot(lastLineCache, null, Collections.singletonList(c), 0, null, null, offx2, offy2, animator);
}
}
}
@ -1211,18 +1228,19 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
w.setVisible(false);
}
}
visibleBlocks.clear();
for (InputBlock b : diagram.getGraph().getBlocks()) {
if (!b.isArtificial()) {
visibleBlocks.add(b);
}
if (getModel().getShowEmptyBlocks()) {
// Add remaining blocks.
visibleBlocks.addAll(diagram.getGraph().getBlocks());
}
}
if (getModel().getShowBlocks() || getModel().getShowCFG()) {
for (InputBlock b : diagram.getGraph().getBlocks()) {
boolean visibleAfter = visibleBlocks.contains(b);
// A block is visible if it is marked as such, except for
// artificial or null blocks in the CFG view.
boolean visibleAfter = visibleBlocks.contains(b) &&
!(getModel().getShowCFG() && (b.isArtificial() || b.getNodes().isEmpty()));
BlockWidget w = getWidget(b);
if (visibleAfter) {

View File

@ -62,6 +62,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
private boolean showBlocks;
private boolean showCFG;
private boolean showNodeHull;
private boolean showEmptyBlocks;
private boolean hideDuplicates;
private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
@ -166,6 +167,15 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
viewPropertiesChangedEvent.fire();
}
public boolean getShowEmptyBlocks() {
return showEmptyBlocks;
}
public void setShowEmptyBlocks(boolean b) {
showEmptyBlocks = b;
viewPropertiesChangedEvent.fire();
}
public boolean getHideDuplicates() {
return hideDuplicates;
}
@ -194,6 +204,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
this.showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES;
this.showCFG = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH;
this.showNodeHull = true;
this.showEmptyBlocks = true;
this.group = g;
filterGraphs();
assert filterChain != null;

View File

@ -99,6 +99,7 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
private OverviewAction overviewAction;
private HideDuplicatesAction hideDuplicatesAction;
private PredSuccAction predSuccAction;
private ShowEmptyBlocksAction showEmptyBlocksAction;
private SelectionModeAction selectionModeAction;
private PanModeAction panModeAction;
private boolean notFirstTime;
@ -279,6 +280,13 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
toolBar.add(button);
predSuccAction.addPropertyChangeListener(this);
showEmptyBlocksAction = new ShowEmptyBlocksAction();
button = new JToggleButton(showEmptyBlocksAction);
button.setSelected(true);
button.setEnabled(Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH);
toolBar.add(button);
showEmptyBlocksAction.addPropertyChangeListener(this);
hideDuplicatesAction = new HideDuplicatesAction();
hideDuplicatesButton = new JToggleButton(hideDuplicatesAction);
hideDuplicatesButton.setSelected(false);
@ -546,6 +554,9 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
if (evt.getSource() == this.predSuccAction) {
boolean b = (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
this.getModel().setShowNodeHull(b);
} else if (evt.getSource() == this.showEmptyBlocksAction) {
boolean b = (Boolean) showEmptyBlocksAction.getValue(ShowEmptyBlocksAction.STATE);
this.getModel().setShowEmptyBlocks(b);
} else if (evt.getSource() == this.overviewAction) {
boolean b = (Boolean) overviewAction.getValue(OverviewAction.STATE);
if (b) {
@ -556,12 +567,15 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
} else if (evt.getSource() == this.seaLayoutAction) {
boolean b = seaLayoutAction.isSelected();
this.getModel().setShowSea(b);
this.showEmptyBlocksAction.setEnabled(false);
} else if (evt.getSource() == this.blockLayoutAction) {
boolean b = blockLayoutAction.isSelected();
this.getModel().setShowBlocks(b);
this.showEmptyBlocksAction.setEnabled(false);
} else if (evt.getSource() == this.cfgLayoutAction) {
boolean b = cfgLayoutAction.isSelected();
this.getModel().setShowCFG(b);
this.showEmptyBlocksAction.setEnabled(true);
} else if (evt.getSource() == this.hideDuplicatesAction) {
boolean b = (Boolean) hideDuplicatesAction.getValue(HideDuplicatesAction.STATE);
this.getModel().setHideDuplicates(b);

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package com.sun.hotspot.igv.view.actions;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import org.openide.util.ImageUtilities;
public class ShowEmptyBlocksAction extends AbstractAction {
private boolean state;
public static final String STATE = "state";
public ShowEmptyBlocksAction() {
state = true;
putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
putValue(STATE, true);
putValue(Action.SHORT_DESCRIPTION, "Show empty blocks in control-flow graph view");
}
@Override
public void actionPerformed(ActionEvent ev) {
this.state = !state;
this.putValue(STATE, state);
}
protected String iconResource() {
return "com/sun/hotspot/igv/view/images/showEmptyBlocks.png";
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -17,6 +17,7 @@
<file name="com-sun-hotspot-igv-view-actions-ZoomOutAction.instance"><attr name="position" intvalue="2001"/></file>
<file name="com-sun-hotspot-igv-view-actions-OverviewAction.instance"><attr name="position" intvalue="2001"/></file>
<file name="com-sun-hotspot-igv-view-actions-PredSuccAction.instance"><attr name="position" intvalue="2001"/></file>
<file name="com-sun-hotspot-igv-view-actions-ShowEmptyBlocksAction.instance"><attr name="position" intvalue="2001"/></file>
<file name="com-sun-hotspot-igv-view-actions-EnableSeaLayoutAction.instance"><attr name="position" intvalue="2001"/></file>
<file name="com-sun-hotspot-igv-view-actions-EnableBlockLayoutAction.instance"><attr name="position" intvalue="2001"/></file>
<file name="com-sun-hotspot-igv-view-actions-EnableCFGLayoutAction.instance"><attr name="position" intvalue="2001"/></file>