From 6028181071b2fc12e32c38250e693fac186432c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 8 Apr 2022 08:41:30 +0000 Subject: [PATCH] 8283930: IGV: add toggle button to show/hide empty blocks in CFG view Reviewed-by: kvn, chagedorn --- .../hotspot/igv/graph/BlockConnection.java | 5 -- .../com/sun/hotspot/igv/graph/Connection.java | 2 - .../hotspot/igv/graph/FigureConnection.java | 5 -- .../sun/hotspot/igv/view/DiagramScene.java | 58 ++++++++++++------ .../hotspot/igv/view/DiagramViewModel.java | 11 ++++ .../hotspot/igv/view/EditorTopComponent.java | 14 +++++ .../view/actions/ShowEmptyBlocksAction.java | 53 ++++++++++++++++ .../igv/view/images/showEmptyBlocks.png | Bin 0 -> 1750 bytes .../com/sun/hotspot/igv/view/layer.xml | 1 + 9 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowEmptyBlocksAction.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/showEmptyBlocks.png diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/BlockConnection.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/BlockConnection.java index f846446ffb1..84b7a4ec09f 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/BlockConnection.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/BlockConnection.java @@ -100,11 +100,6 @@ public class BlockConnection implements Connection { controlPoints = list; } - @Override - public boolean isAlwaysVisible() { - return true; - } - @Override public boolean hasSlots() { return false; diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Connection.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Connection.java index faa8f736988..1d7825f5d58 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Connection.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Connection.java @@ -41,8 +41,6 @@ public interface Connection extends Link { public String getToolTipText(); - public boolean isAlwaysVisible(); - public boolean hasSlots(); } diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/FigureConnection.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/FigureConnection.java index 0b64668816c..4d54f5bb894 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/FigureConnection.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/FigureConnection.java @@ -148,11 +148,6 @@ public class FigureConnection implements Connection { controlPoints = list; } - @Override - public boolean isAlwaysVisible() { - return false; - } - @Override public boolean hasSlots() { return true; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 703cbe6e618..72ad1aa102f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -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 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 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) { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index b532a3ebe4b..0a523f3bace 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -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 filterChainChangedListener = new ChangedListener() { @@ -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; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index 5ae8c8e8dbb..6265b83c268 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -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); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowEmptyBlocksAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowEmptyBlocksAction.java new file mode 100644 index 00000000000..7fffdfa4f85 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowEmptyBlocksAction.java @@ -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"; + } +} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/showEmptyBlocks.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/showEmptyBlocks.png new file mode 100644 index 0000000000000000000000000000000000000000..841d8aeeddf2c7fc128add4f766951c59cdfa156 GIT binary patch literal 1750 zcmV;{1}XW8P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1Yuw(BSi{MRaa2}n$0Ihf&`w}W1O7nqFqCb3`I z#0&yUg-U`@`}a?$fAEMnCFi4t6oSFyl1q}&QL{gJ)@^M zyg@ElFH2sQo(#FaQg#rDTcnX8imfSwE z7q0D;)AI!T-|3#5-XV(aYFHi+xi&m?_vr2Iy=w1m-(7YATMlbemz^+8Dtp~V5X{d4 zO2q5YkFz8cMYdhfKjmk}`-#0HAP} zXp^m0L484}SV*OJT3C46P19ash2_dvDhy>jW9dVoBa7aZ-bXGm)5;m%36>eBJltqU zjb&hj`*NzE4!)GffLz2{Q0S+d6&uWE+f{6yZ?R=3(H84G+C8~B*8TgT$icP;7`C9m z1h$?7nlidn5X^%^v)YSNq}S)9f` zAsv&ZlyZj649z)E#`+A&CY#;d=C`oLO}Dh=g77J>_!3GiT2jeXs;$W58fvUsQ_YPV zLaDjtsf8Asw$yS*taaO6_dWF3wWpr1tSwf5loPD+VofGfV_m$m25F3YOEX@eWN-$? z#4#9;g8>Az49<+Qb26A4oS7uZ3NHZZ2RD^X<{*x&Yb?I=mAe~rr+A~_-ts0#nWI77 zm&{GxsQEkIeqpVSYr9Ow_ADGeH5S>2HCYrt+@_**>5SGk&$GLA59hck&EvNH+|s)R zJ#Tq-d&%RTx&!c|r8j`Omo+rmwytl1(K|p=m!jxxGwv-wdV%ybKsx5i&j9JY3*P~h zwuT7WP3a895BQ$c(g}v&!HeYA*lyzf8lB0Rb~QLBw0{MT?$CV&j_%NX1&$6ddk7UB zVD=C^`pj(Rw)DV8C@*l)XKqv5yS?_(`PJD%r$g@rz|$%63Lt%%8$aUcue0OgF**n6 zH9&eq_=1vG8@gLg|BHh@T}Ll){;H3@aP;Bp=nSAUx5!OzTp?MCYvpCq-aH%Z<%nul z%LjaP%c0-w95+L6@t%N7hx~cK3>|UH>HkM36Xf{c8vOA~^dE5LRRm^yU&{ah0flKp zLr_UWLm+T+Z)Rz1WdHzpoPCi!NW)MRg-_E;MJgigAfk|=I$01Eanvdlp+cw?T6Hja z=^r#{NLpMR1=oUuKZ{id7iV1^Tm?b!2gK3INzp}0ye}!Vi1EVXeVljC;l29+p;2a< z6&MFJy=tZsaWRu!6@#w`z=tsUF)TC7n3JR=JnQS8da3SWJj=W9&+1ik76W`D@hmgU zD)9#K^k&uIyiXiqMOh_2Cmu8Dg2azpS6qJMTyR+6nGrLcnkSABi-itWI+ztrjd+SU zs%kpr3mKPH&Rd+da*eg_$zK@C=_|`zr!|BG7O?~gA{5k6LK#)WXxB-xkfQUrhkwxV zOXO0>RRSZ&0xHlTJAUv#_&r-IKRMwhh2lWhi*0|50Kr|LS-0))W7}??0RCs-N^kos z4PfSz^m<#19szyZz{Pc2Q}%$%9bn+ekWJZ<{IrC89(X^aZ^{DUTcBsnom=Z1rw>4y zW|h1F4i16Q0%fmzyt}(|ZvXbQ=Jx{~?{bB`Ug}!_000JJOGiWi{{a60|De66lK=n! z32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rh1OXE=7Dh2|lK=n!8FWQhbVF}#ZDnqB z07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b0GCNbK~y-)WBmXBKLZTd*f1bCc)*b(42&=~ z3%cZH-*mj1eK*fU;WIH%3jY89569Nl|Nk>EFyO`3*8l$_>%s8C+S9M_TG&^>Fxb8D z?rsPEScs#t7Z@o`NGJxN8w68`&c|?pjSXtJ!sMWuVDc#9@T82#+5eFg|HonhA}?&% sfT=qm0F{qR4dt-_O+0u*8(-`I08+AXaSvbWy#N3J07*qoM6N<$f-8|aG5`Po literal 0 HcmV?d00001 diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml index ee65bf0799c..05310ac2c1d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml +++ b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml @@ -17,6 +17,7 @@ +