diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/AbstractFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/AbstractFilter.java index 15492d83f3f..b1cc9cd791c 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/AbstractFilter.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/AbstractFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -26,6 +26,7 @@ package com.sun.hotspot.igv.filter; import com.sun.hotspot.igv.data.ChangedEvent; import com.sun.hotspot.igv.data.Properties; +import com.sun.hotspot.igv.graph.Figure; import org.openide.cookies.OpenCookie; /** @@ -60,4 +61,14 @@ public abstract class AbstractFilter implements Filter { protected void fireChangedEvent() { changedEvent.fire(); } + + protected static String getFirstMatchingProperty(Figure figure, String[] propertyNames) { + for (String propertyName : propertyNames) { + String s = figure.getProperties().resolveString(propertyName); + if (s != null && !s.isEmpty()) { + return s; + } + } + return null; + } } diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CombineFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CombineFilter.java index f26e878132e..be1d813ab52 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CombineFilter.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/CombineFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -23,13 +23,9 @@ */ package com.sun.hotspot.igv.filter; -import com.sun.hotspot.igv.data.Properties; -import com.sun.hotspot.igv.data.Properties.PropertyMatcher; import com.sun.hotspot.igv.graph.*; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * @@ -53,12 +49,11 @@ public class CombineFilter extends AbstractFilter { @Override public void apply(Diagram diagram) { - Properties.PropertySelector
selector = new Properties.PropertySelector<>(diagram.getFigures()); for (CombineRule r : rules) { - List
list = selector.selectMultiple(r.getFirstMatcher()); - Set
figuresToRemove = new HashSet<>(); - for (Figure f : list) { + List
first = r.getFirstSelector().selected(diagram); + List
second = r.getSecondSelector().selected(diagram); + for (Figure f : first) { List
successors = new ArrayList<>(f.getSuccessors()); if (r.isReversed()) { @@ -75,8 +70,8 @@ public class CombineFilter extends AbstractFilter { } slot.getSource().addSourceNode(f.getInputNode()); - if (r.getShortProperty() != null) { - String s = f.getProperties().get(r.getShortProperty()); + if (r.getPropertyNames() != null && r.getPropertyNames().length > 0) { + String s = r.getFirstMatchingProperty(f); if (s != null && s.length() > 0) { slot.setShortName(s); slot.setText(s); @@ -103,15 +98,12 @@ public class CombineFilter extends AbstractFilter { newConn.setStyle(c.getStyle()); } } - - figuresToRemove.add(f); } } else { for (Figure succ : successors) { - if (succ.getPredecessors().size() == 1 && succ.getInputSlots().size() == 1) { - if (succ.getProperties().selectSingle(r.getSecondMatcher()) != null && succ.getOutputSlots().size() == 1) { - + if (succ.getPredecessors().size() == 1) { + if (second.contains(succ) && succ.getOutputSlots().size() <= 1) { OutputSlot oldSlot = null; for (OutputSlot s : f.getOutputSlots()) { @@ -124,15 +116,19 @@ public class CombineFilter extends AbstractFilter { assert oldSlot != null; - OutputSlot nextSlot = succ.getOutputSlots().get(0); + OutputSlot nextSlot = null; + if (succ.getOutputSlots().size() == 1) { + nextSlot = succ.getOutputSlots().get(0); + } + int pos = 0; if (succ.getProperties().get("con") != null) { pos = Integer.parseInt(succ.getProperties().get("con")); } OutputSlot slot = f.createOutputSlot(pos); slot.getSource().addSourceNode(succ.getInputNode()); - if (r.getShortProperty() != null) { - String s = succ.getProperties().get(r.getShortProperty()); + if (r.getPropertyNames() != null && r.getPropertyNames().length > 0) { + String s = r.getFirstMatchingProperty(succ); if (s != null && s.length() > 0) { slot.setShortName(s); slot.setText(s); @@ -155,14 +151,15 @@ public class CombineFilter extends AbstractFilter { } } } - for (FigureConnection c : nextSlot.getConnections()) { - FigureConnection newConn = diagram.createConnection(c.getInputSlot(), slot, c.getLabel()); - newConn.setColor(c.getColor()); - newConn.setStyle(c.getStyle()); + if (nextSlot != null) { + for (FigureConnection c : nextSlot.getConnections()) { + FigureConnection newConn = diagram.createConnection(c.getInputSlot(), slot, c.getLabel()); + newConn.setColor(c.getColor()); + newConn.setStyle(c.getStyle()); + } } - - figuresToRemove.add(succ); + diagram.removeFigure(succ); if (oldSlot.getConnections().size() == 0) { f.removeSlot(oldSlot); @@ -172,8 +169,6 @@ public class CombineFilter extends AbstractFilter { } } } - - diagram.removeAllFigures(figuresToRemove); } } @@ -183,41 +178,36 @@ public class CombineFilter extends AbstractFilter { public static class CombineRule { - private PropertyMatcher first; - private PropertyMatcher second; + private Selector first; + private Selector second; private boolean reversed; - private String shortProperty; + private String[] propertyNames; - public CombineRule(PropertyMatcher first, PropertyMatcher second) { - this(first, second, false); - - } - - public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed) { - this(first, second, reversed, null); - } - - public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed, String shortProperty) { + public CombineRule(Selector first, Selector second, boolean reversed, String[] propertyNames) { this.first = first; this.second = second; this.reversed = reversed; - this.shortProperty = shortProperty; + this.propertyNames = propertyNames; } public boolean isReversed() { return reversed; } - public PropertyMatcher getFirstMatcher() { + public Selector getFirstSelector() { return first; } - public PropertyMatcher getSecondMatcher() { + public Selector getSecondSelector() { return second; } - public String getShortProperty() { - return shortProperty; + public String[] getPropertyNames() { + return propertyNames; + } + + public String getFirstMatchingProperty(Figure figure) { + return AbstractFilter.getFirstMatchingProperty(figure, propertyNames); } } } diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/EditPropertyFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/EditPropertyFilter.java new file mode 100644 index 00000000000..b26e34049c8 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/EditPropertyFilter.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023, 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.filter; + +import com.sun.hotspot.igv.graph.Diagram; +import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.graph.Selector; +import java.util.function.UnaryOperator; +import java.util.List; + +public class EditPropertyFilter extends AbstractFilter { + + private String name; + private Selector selector; + private final String inputPropertyName; + private final String outputPropertyName; + private final UnaryOperator editFunction; + + public EditPropertyFilter(String name, Selector selector, + String inputPropertyName, String outputPropertyName, + UnaryOperator editFunction) { + this.name = name; + this.selector = selector; + this.inputPropertyName = inputPropertyName; + this.outputPropertyName = outputPropertyName; + this.editFunction = editFunction; + } + + @Override + public String getName() { + return name; + } + + @Override + public void apply(Diagram diagram) { + List
list = selector.selected(diagram); + for (Figure f : list) { + String inputVal = f.getProperties().get(inputPropertyName); + String outputVal = editFunction.apply(inputVal); + f.getProperties().setProperty(outputPropertyName, outputVal); + } + } +} diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveEmptySlotsFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveEmptySlotsFilter.java new file mode 100644 index 00000000000..3db8b2a3444 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveEmptySlotsFilter.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023, 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.filter; + +import com.sun.hotspot.igv.graph.*; +import java.util.ArrayList; +import java.util.List; + +public class RemoveEmptySlotsFilter extends AbstractFilter { + + private String name; + private Selector selector; + + public RemoveEmptySlotsFilter(String name, Selector selector) { + this.name = name; + this.selector = selector; + } + + @Override + public String getName() { + return name; + } + + @Override + public void apply(Diagram diagram) { + List
list = selector.selected(diagram); + for (Figure f : list) { + List empty = new ArrayList<>(); + for (InputSlot is : f.getInputSlots()) { + if (is.getConnections().isEmpty()) { + empty.add(is); + } + } + for (InputSlot is : empty) { + f.removeSlot(is); + } + } + } +} diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveInputsFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveInputsFilter.java index eacc4c9aae7..83ac5f05516 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveInputsFilter.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/RemoveInputsFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -48,53 +48,17 @@ public class RemoveInputsFilter extends AbstractFilter { @Override public void apply(Diagram diagram) { - for (RemoveInputsRule r : rules) { - - List
list = r.getSelector().selected(diagram); + List
list = r.getNodeSelector().selected(diagram); + List
slotList = r.getSlotSelector().selected(diagram); for (Figure f : list) { - int z = 0; - List last = new ArrayList<>(); for (InputSlot is : f.getInputSlots()) { - if (z >= r.getStartingIndex() && z <= r.getEndIndex() && is.getConnections().size() > 0) { - StringBuilder sb = new StringBuilder(); - List conns = is.getConnections(); - for (int i = 0; i < conns.size(); i++) { - FigureConnection c = conns.get(i); - OutputSlot os = c.getOutputSlot(); - Figure pred = os.getFigure(); - if (i != 0) { - sb.append("
"); - } - sb.append(pred.getLines()[0]); + List conns = is.getConnections(); + if (conns.size() == 1) { + Figure i = conns.get(0).getOutputSlot().getFigure(); + if (slotList.contains(i)) { + is.removeAllConnections(); } - is.removeAllConnections(); - is.setShortName("X"); - is.setText(sb.toString()); - last.add(is); - } else { - last.clear(); - } - z++; - } - - if (last.size() > 3) { - InputSlot first = last.get(0); - first.setShortName("XX"); - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < last.size(); i++) { - InputSlot is2 = last.get(i); - if (i != 0) { - sb.append("
"); - } - sb.append(is2.getText()); - } - - first.setText(sb.toString()); - - for (int i = 1; i < last.size(); i++) { - f.removeSlot(last.get(i)); } } } @@ -107,34 +71,20 @@ public class RemoveInputsFilter extends AbstractFilter { public static class RemoveInputsRule { - private Selector selector; - private int startingIndex; - private int endIndex; + private Selector nodeSelector; + private Selector slotSelector; - public RemoveInputsRule(Selector selector) { - this(selector, 0); + public RemoveInputsRule(Selector nodeSelector, Selector slotSelector) { + this.nodeSelector = nodeSelector; + this.slotSelector = slotSelector; } - public RemoveInputsRule(Selector selector, int startIndex) { - this(selector, startIndex, Integer.MAX_VALUE); + public Selector getNodeSelector() { + return nodeSelector; } - public RemoveInputsRule(Selector selector, int startIndex, int endIndex) { - this.startingIndex = startIndex; - this.endIndex = endIndex; - this.selector = selector; - } - - public int getStartingIndex() { - return startingIndex; - } - - public int getEndIndex() { - return endIndex; - } - - public Selector getSelector() { - return selector; + public Selector getSlotSelector() { + return slotSelector; } } } diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/SplitFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/SplitFilter.java index f83901a28b7..aa8d5ae2669 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/SplitFilter.java +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/SplitFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -34,12 +34,12 @@ public class SplitFilter extends AbstractFilter { private String name; private Selector selector; - private String propertyName; + private String[] propertyNames; - public SplitFilter(String name, Selector selector, String propertyName) { + public SplitFilter(String name, Selector selector, String[] propertyNames) { this.name = name; this.selector = selector; - this.propertyName = propertyName; + this.propertyNames = propertyNames; } @Override @@ -52,23 +52,7 @@ public class SplitFilter extends AbstractFilter { List
list = selector.selected(d); for (Figure f : list) { - - for (InputSlot is : f.getInputSlots()) { - for (FigureConnection c : is.getConnections()) { - OutputSlot os = c.getOutputSlot(); - if (f.getInputNode() != null) { - os.getSource().addSourceNode(f.getInputNode()); - os.setColor(f.getColor()); - } - - - String s = f.getProperties().resolveString(propertyName); - if (s != null) { - os.setShortName(s); - } - - } - } + String s = AbstractFilter.getFirstMatchingProperty(f, propertyNames); for (OutputSlot os : f.getOutputSlots()) { for (FigureConnection c : os.getConnections()) { InputSlot is = c.getInputSlot(); @@ -76,8 +60,6 @@ public class SplitFilter extends AbstractFilter { is.getSource().addSourceNode(f.getInputNode()); is.setColor(f.getColor()); } - - String s = f.getProperties().resolveString(propertyName); if (s != null) { is.setShortName(s); } diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js index bf4d3c239a9..92b3c3ab5eb 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -21,61 +21,122 @@ * questions. * */ - + /** * * @author Thomas Wuerthinger */ - -function colorize(property, regexp, color) { - var f = new ColorFilter(""); - f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), color)); - f.apply(graph); + +// Split a string by whitespace, collapsing repeated ones. +function split_string(s) { + return s.split(/(\s+)/).filter(function(e) {return e.trim().length > 0;}); } +// Select the node union in a list of selectors. +function or(selectors) { + return new OrSelector(selectors); +} + +// Select the node intersection in a list of selectors. +function and(selectors) { + return new AndSelector(selectors); +} + +// Select the nodes that are not selected by a given selector. +function not(selector) { + return new InvertSelector(selector); +} + +// Select the nodes that succeed those given by a selector. +function successorOf(selector) { + return new SuccessorSelector(selector); +} + +// Select the blocks where at least one node is selected by the given selector. +function hasAnyNode(selector) { + return new AnySelector(selector); +} + +// Select the nodes whose given property matches a given regular expression. +function matches(property, regexp) { + return new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)); +} + +// Color the selected nodes. +function colorize(selector, color) { + var f = new ColorFilter(""); + f.addRule(new ColorFilter.ColorRule(selector, color)); + f.apply(graph); +} + +// Invisible connection style (used to hide edges). +invisibleConnection = Connection.ConnectionStyle.INVISIBLE; + +// Apply a given style (e.g. invisible) and color to the out edges of the +// selected nodes. +function styleOutputConnections(selector, color, style) { + var f = new ConnectionFilter(""); + f.addRule(new ConnectionFilter.ConnectionStyleRule(selector, color, style)); + f.apply(graph); +} + +// Display a warning with the contents of a given property ('propertyToShow') in +// the nodes whose given property ('propertyToMatch') matches a regular +// expression. function warn(propertyToMatch, regexp, propertyToShow) { var f = new WarningFilter("", "[" + propertyToShow + "]"); - f.addRule(new WarningFilter.WarningRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(propertyToMatch, regexp)))); + f.addRule(new WarningFilter.WarningRule(matches(propertyToMatch, regexp))); f.apply(graph); } -function remove(property, regexp) { +// Remove edges with the same source and destination node. +function removeSelfLoops() { + var f = new RemoveSelfLoopsFilter(""); + f.apply(graph); +} + +// Remove the selected nodes. +function remove(selector) { var f = new RemoveFilter(""); - f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)))); + f.addRule(new RemoveFilter.RemoveRule(selector)); f.apply(graph); } +// Remove the selected nodes and nodes that become orphan after the removal. function removeIncludingOrphans(property, regexp) { var f = new RemoveFilter(""); f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), true)); f.apply(graph); } -function split(property, regexp, propertyName) { - if (propertyName == undefined) { - propertyName = graph.getNodeText(); - } - var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), propertyName); - f.apply(graph); -} - -function removeInputs(property, regexp, from, to) { - var f = new RemoveInputsFilter(""); - if(from == undefined && to == undefined) { - f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)))); - } else if(to == undefined) { - f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), from)); - } else { - f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), from, to)); +// Inline the selected nodes into their successors and display the first found +// property in the given property list in the resulting input slots. +function split(selector, propertyNames) { + if (propertyNames == undefined) { + propertyNames = []; } + new SplitFilter("", selector, propertyNames).apply(graph); +} + +// Combine the selected (second) nodes into their selected (first) predecessors +// and display the first found property in the given property list in the +// resulting output slots. +function combine(first, second, propertyNames) { + if (propertyNames == undefined) { + propertyNames = []; + } + var f = new CombineFilter(""); + f.addRule(new CombineFilter.CombineRule(first, second, false, propertyNames)); f.apply(graph); } +// Remove (input and/or output) slots without connecting edges. function removeUnconnectedSlots(inputs, outputs) { var f = new UnconnectedSlotFilter(inputs, outputs); f.apply(graph); } +// Color nodes using a gradient based on the given property and min/max values. function colorizeGradient(property, min, max) { var f = new GradientColorFilter(); f.setPropertyName(property); @@ -84,6 +145,8 @@ function colorizeGradient(property, min, max) { f.apply(graph); } +// Color nodes using a gradient based on the given property, min/max values, and +// mode ("LINEAR" or "LOGARITHMIC"). function colorizeGradientWithMode(property, min, max, mode) { var f = new GradientColorFilter(); f.setPropertyName(property); @@ -93,6 +156,9 @@ function colorizeGradientWithMode(property, min, max, mode) { f.apply(graph); } +// Color nodes using a custom gradient based on the given property, min/max +// values, mode ("LINEAR" or "LOGARITHMIC"), list of colors, list of fractions, +// and number of shades. function colorizeGradientCustom(property, min, max, mode, colors, fractions, nshades) { var f = new GradientColorFilter(); f.setPropertyName(property); @@ -105,6 +171,7 @@ function colorizeGradientCustom(property, min, max, mode, colors, fractions, nsh f.apply(graph); } +// Pre-defined colors for coloring filters. var black = Color.black; var blue = Color.blue; var cyan = Color.cyan; @@ -118,3 +185,38 @@ var pink = Color.pink var red = Color.red; var yellow = Color.yellow; var white = Color.white; + +// Update the value of the given property in the selected nodes according to a +// function that takes as input the old property value and returns the new +// property value. +function editSameProperty(selector, propertyName, editFunction) { + var f = new EditPropertyFilter("", selector, propertyName, propertyName, editFunction); + f.apply(graph); +} + +// Update the value of the given property ('outputPropertyName') in the selected +// nodes according to a function that takes as input the value of a possibly +// different property ('inputPropertyName') and returns the new property value. +function editProperty(selector, inputPropertyName, outputPropertyName, editFunction) { + var f = new EditPropertyFilter("", selector, inputPropertyName, outputPropertyName, editFunction); + f.apply(graph); +} + +// Remove edges that go from the selected slots into the selected nodes. +function removeInputs(nodeSelector, slotSelector) { + var f = new RemoveInputsFilter(""); + f.addRule(new RemoveInputsFilter.RemoveInputsRule(nodeSelector, slotSelector)); + f.apply(graph); +} + +// Remove empty slots in the selected nodes, condensing all inputs as a result. +function removeEmptySlots(selector) { + new RemoveEmptySlotsFilter("", selector).apply(graph); +} + +// Remove the selected block. +function removeBlock(selector) { + var f = new RemoveBlockFilter(""); + f.addRule(new RemoveBlockFilter.RemoveBlockRule(selector)); + f.apply(graph); +} diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/AndSelector.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/AndSelector.java index eba645e11ce..57986c47fd6 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/AndSelector.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/AndSelector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -32,23 +32,24 @@ import java.util.List; */ public class AndSelector implements Selector { - private Selector selector1; - private Selector selector2; + private Selector[] selectors; - public AndSelector(Selector s1, Selector s2) { - this.selector1 = s1; - this.selector2 = s2; + public AndSelector(Selector[] selectors) { + this.selectors = selectors; } @Override public List
selected(Diagram d) { - List
l1 = selector1.selected(d); - List
l2 = selector2.selected(d); - List
result = new ArrayList<>(); - for (Figure f : l2) { - if (l1.contains(f)) { - result.add(f); + List
result = d.getFigures(); + for (Selector s : selectors) { + List
selected = s.selected(d); + List
newResult = new ArrayList<>(); + for (Figure f : result) { + if (selected.contains(f)) { + newResult.add(f); + } } + result = newResult; } return result; } diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index 2bdda123688..191996f2ee9 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -113,6 +113,14 @@ public class Diagram { } } + for (Figure f : figures) { + int i = 0; + for (InputSlot inputSlot : f.getInputSlots()) { + inputSlot.setOriginalIndex(i); + i++; + } + } + for (InputBlockEdge e : graph.getBlockEdges()) { Block p = getBlock(e.getFrom()); Block s = getBlock(e.getTo()); diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Figure.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Figure.java index 880d3931d46..9cc917dedcf 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Figure.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Figure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -41,6 +41,7 @@ public class Figure extends Properties.Entity implements Vertex { public static final int TOP_CFG_HEIGHT = 7; public static final int BOTTOM_CFG_HEIGHT = 6; public static final int WARNING_WIDTH = 16; + public static final double BOLD_LINE_FACTOR = 1.06; protected List inputSlots; protected List outputSlots; private final InputNode inputNode; @@ -71,6 +72,9 @@ public class Figure extends Properties.Entity implements Vertex { if (hasInputList() && lines > 1) { lines++; } + if (getProperties().get("extra_label") != null) { + lines++; + } heightCash = lines * metrics.getHeight() + INSET; if (diagram.isCFG()) { if (hasNamedInputSlot()) { @@ -120,7 +124,7 @@ public class Figure extends Properties.Entity implements Vertex { max = cur; } } - widthCash = max + INSET; + widthCash = (int)(max * BOLD_LINE_FACTOR) + INSET; if (getWarning() != null) { widthCash += WARNING_WIDTH; } @@ -164,7 +168,7 @@ public class Figure extends Properties.Entity implements Vertex { } public boolean hasInputList() { - return diagram.isCFG() && !getPredecessors().isEmpty(); + return diagram.isCFG() && !getInputSlots().isEmpty(); } public void setBlock(Block block) { @@ -320,8 +324,31 @@ public class Figure extends Properties.Entity implements Vertex { if (hasInputList()) { String inputList = " ← "; List inputs = new ArrayList<>(getPredecessors().size()); - for (Figure p : getPredecessors()) { - inputs.add(p.getProperties().resolveString(diagram.getTinyNodeText())); + for (InputSlot is : getInputSlots()) { + String inputLabel = null; + if (is.getConnections().isEmpty()) { + if (is.hasSourceNodes() && is.shouldShowName()) { + inputLabel = "[" + is.getShortName() + "]"; + } else { + inputLabel = "_"; + } + } else { + OutputSlot os = is.getConnections().get(0).getOutputSlot(); + Figure f = os.getFigure(); + String nodeTinyLabel = f.getProperties().resolveString(diagram.getTinyNodeText()); + if (os.hasSourceNodes() && os.shouldShowName()) { + nodeTinyLabel += ":" + os.getShortName(); + } + inputLabel = nodeTinyLabel; + } + assert(inputLabel != null); + int gapSize = is.gapSize(); + if (gapSize == 1) { + inputs.add("_"); + } else if (gapSize > 1) { + inputs.add("…"); + } + inputs.add(inputLabel); } inputList += String.join(" ", inputs); if (result.size() == 1) { @@ -333,6 +360,11 @@ public class Figure extends Properties.Entity implements Vertex { } } + String extraLabel = getProperties().get("extra_label"); + if (extraLabel != null) { + result.add(extraLabel); + } + lines = result.toArray(new String[0]); // Set the "label" property of the input node, so that by default // search is done on the node label (without line breaks). See also 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 ebdee9229e8..ac2c88f6913 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -106,7 +106,7 @@ public class FigureConnection implements Connection { builder.append(" → "); builder.append(getInputSlot().getFigure().getProperties().resolveString(shortNodeText)); builder.append(" [") - .append(getInputSlot().getPosition()) + .append(getInputSlot().getOriginalIndex()) .append("]"); return builder.toString(); } diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/InputSlot.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/InputSlot.java index cb1f3a5b5fd..71c29aa8db1 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/InputSlot.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/InputSlot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -32,8 +32,11 @@ import java.util.List; */ public class InputSlot extends Slot { + private int originalIndex; + protected InputSlot(Figure figure, int wantedIndex) { super(figure, wantedIndex); + this.originalIndex = -1; } @Override @@ -47,13 +50,34 @@ public class InputSlot extends Slot { InputSlot s = inputSlots.remove(position); inputSlots.add(position, s); } + + public int getOriginalIndex() { + return originalIndex; + } + + public void setOriginalIndex(int originalIndex) { + this.originalIndex = originalIndex; + } + + public int gapSize() { + int index = getPosition(); + int originalIndex = getOriginalIndex(); + InputSlot prevSlot = index > 0 ? getFigure().getInputSlots().get(index - 1) : null; + int prevOriginalIndex = index > 0 ? prevSlot.getOriginalIndex() : -1; + return originalIndex - prevOriginalIndex - 1; + } + @Override public Point getRelativePosition() { int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getInputSlots()); double gapRatio = (double)gap / (double)(getFigure().getInputSlots().size() + 1); int gapAmount = (int)((getPosition() + 1)*gapRatio); return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getInputSlots(), this)) + getWidth()/2, -Figure.SLOT_START); - //return new Point((getFigure().getWidth() / (getFigure().getInputSlots().size() * 2)) * (getPosition() * 2 + 1), -Figure.SLOT_START); + } + + @Override + public String getToolTipText() { + return super.getToolTipText() + " [" + originalIndex + "]"; } @Override diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/OrSelector.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/OrSelector.java index 1e7cb2446df..9c316806efb 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/OrSelector.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/OrSelector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -23,6 +23,7 @@ */ package com.sun.hotspot.igv.graph; +import java.util.ArrayList; import java.util.List; /** @@ -31,27 +32,22 @@ import java.util.List; */ public class OrSelector implements Selector { - private Selector selector1; - private Selector selector2; + private Selector[] selectors; - /** Creates a new instance of OrSelector */ - public OrSelector(Selector s1, Selector s2) { - this.selector1 = s1; - this.selector2 = s2; + public OrSelector(Selector[] selectors) { + this.selectors = selectors; } @Override public List
selected(Diagram d) { - - List
l1 = selector1.selected(d); - List
l2 = selector2.selected(d); - - for (Figure f : l2) { - if (!l1.contains(f)) { - l1.add(f); + List
result = new ArrayList<>(); + for (Selector s : selectors) { + for (Figure f : s.selected(d)) { + if (!result.contains(f)) { + result.add(f); + } } } - - return l1; + return result; } } diff --git a/src/utils/IdealGraphVisualizer/README.md b/src/utils/IdealGraphVisualizer/README.md index d507158fddd..2a364dc19e2 100644 --- a/src/utils/IdealGraphVisualizer/README.md +++ b/src/utils/IdealGraphVisualizer/README.md @@ -46,5 +46,15 @@ Alternatively the output can be sent to a file using with unique names being generated by adding a number onto the provided file name. +## Defining Custom Filters + +IGV has a powerful filter mechanism with which nodes and blocks can be colored, +hidden, updated, etc. according to user-defined rules. Filters are programmed in +JavaScript using a set of predefined primitives and auxiliary functions. For +more information, see the documentation in +`Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js` and the default +filters in +`ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters`. + More information about the tool is available at https://wiki.openjdk.org/display/HotSpot/IdealGraphVisualizer. diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/color.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/color.filter index a0e063a0c1b..39848506010 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/color.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/color.filter @@ -10,16 +10,16 @@ var otherEdgeColor = java.awt.Color.decode("#dfc025"); var dataEdgeColor = java.awt.Color.decode("#3178c2"); var memoryEdgeColor = java.awt.Color.decode("#828200"); -colorize("category", "data", dataNodeColor); -colorize("category", "memory", memoryNodeColor); -colorize("category", "mixed", mixedNodeColor); -colorize("category", "control", controlNodeColor); -colorize("category", "other", otherNodeColor); +colorize(matches("category", "data"), dataNodeColor); +colorize(matches("category", "memory"), memoryNodeColor); +colorize(matches("category", "mixed"), mixedNodeColor); +colorize(matches("category", "control"), controlNodeColor); +colorize(matches("category", "other"), otherNodeColor); var f = new ColorFilter("Line Style filter"); -f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "data")), null, dataEdgeColor, null)); -f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "memory")), null, memoryEdgeColor, null)); -f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "mixed")), null, mixedEdgeColor, null)); -f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "control")), null, controlEdgeColor, null)); -f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "other")), null, otherEdgeColor, null)); +f.addRule(new ColorFilter.ColorRule(matches("category", "data"), null, dataEdgeColor, null)); +f.addRule(new ColorFilter.ColorRule(matches("category", "memory"), null, memoryEdgeColor, null)); +f.addRule(new ColorFilter.ColorRule(matches("category", "mixed"), null, mixedEdgeColor, null)); +f.addRule(new ColorFilter.ColorRule(matches("category", "control"), null, controlEdgeColor, null)); +f.addRule(new ColorFilter.ColorRule(matches("category", "other"), null, otherEdgeColor, null)); f.apply(graph); \ No newline at end of file diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/condenseGraph.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/condenseGraph.filter new file mode 100644 index 00000000000..02232647a47 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/condenseGraph.filter @@ -0,0 +1,66 @@ +// Condense the graph without information loss and make the structure of the +// intermediate representation more explicit. This filter is most effective in +// combination with "Simplify graph". + +// Pretty-print Bool nodes to be shown as output slots. +function replaceComparisonWithSign(dump_spec) { + var comparison = dump_spec.replace('[','').replace(']','') + switch (comparison) { + case "eq": return "="; + case "gt": return ">"; + case "lt": return "<"; + case "ne": return "≠"; + case "le": return "≤"; + case "ge": return "≥"; + default: return comparison; + } +} +editSameProperty(matches("name", "Bool"), "dump_spec", replaceComparisonWithSign); + +// Add a more informative text for null-pointer input slots. +editSameProperty(and([matches("name", "ConP|ConN"), matches("dump_spec", "#.*NULL")]), + "short_name", + function(t) {return "null";}); + +// Pretty-print CatchProj nodes. +function catchProjShortText(con) { + switch (con) { + case "0": return "F"; // fall-through + case "1": return "T"; // throw + default: return "?"; + } +} +editProperty(matches("name", "CatchProj"), "con", "short_name", catchProjShortText); + +// Add short text to inlined Mach data parameters. +editProperty(and([matches("name", "MachProj"), + matches("category", "data"), + successorOf(matches("name", "Start"))]), + "dump_spec", "short_name", + function(dump_spec) {return dump_spec;}); + +// Condense inputs in all nodes. +var anyNode = matches("name", ".*"); +removeEmptySlots(anyNode); + +// Inline ("split") Parm and start MachProj nodes, except control ones. +split(and([matches("name", "Parm|MachProj"), + not(matches("category", "control")), + successorOf(matches("name", "Start"))]), + ["[short_name]"]); + +// Combine single-input nodes. +combine(anyNode, matches("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj|Parm")); +combine(anyNode, matches("name", "SCMemProj"), ["SCM"]); +combine(matches("name", "SubTypeCheck|Cmp.*"), matches("name", "Bool"), ["[dump_spec]"]); +combine(anyNode, matches("name", "Decode(N|NarrowPtr|NKlass)"), ["DC"]); +combine(anyNode, matches("name", "Conv2B"), ["2B"]); +combine(anyNode, matches("name", "Conv[LFD]2I"), ["2I"]); +combine(anyNode, matches("name", "Conv[IFD]2L"), ["2L"]); +combine(anyNode, matches("name", "Conv[ILD]2F"), ["2F"]); +combine(anyNode, matches("name", "Conv[ILF]2D"), ["2D"]); + +// Inline ("split") constant nodes. +split(matches("name", "MachTemp"), ["T"]); +split(matches("name", "ThreadLocal"), ["TL"]); +split(matches("name", "(Con[A-Z]?)|ConNKlass|(loadCon.*)"), ["[short_name]", "[name]"]); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter new file mode 100644 index 00000000000..a272b7420ca --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter @@ -0,0 +1,46 @@ +// This filter adds a new line to the label of selected nodes with custom +// information. This is achieved by adding a special property 'extra_label' to +// them with information extracted from other properties, typically 'dump_spec'. + +// Add extra line to method calls with callee information. +function callJavaInfo(dump_spec, regularPos, trapPos) { + dump_components = split_string(dump_spec); + if (dump_components.length < (trapPos + 1)) { + return null; + } + var tm = /(uncommon_trap\(reason=\'(\w*)\')/.exec(dump_components[trapPos]); + if (tm == null || typeof tm[2] == 'undefined') { + return dump_components[regularPos]; + } + return "trap: " + tm[2]; +} +editProperty(matches("name", "CallStaticJava|CallDynamicJava|CallJava"), "dump_spec", "extra_label", + function(dump_spec) {return callJavaInfo(dump_spec, 2, 2);}); +editProperty(matches("name", "CallStaticJavaDirect|CallDynamicJavaDirect"), "dump_spec", "extra_label", + function(dump_spec) {return callJavaInfo(dump_spec, 1, 3);}); + +function callLeafInfo(dump_spec, pos) { + dump_components = split_string(dump_spec); + if (dump_components.length < pos + 1) { + return null; + } + return dump_components[pos]; +} +editProperty(matches("name", "CallLeaf|CallLeafNoFP"), "dump_spec", "extra_label", + function(dump_spec) {return callLeafInfo(dump_spec, 1);}); +editProperty(matches("name", "CallLeafDirect|CallLeafDirectVector|CallLeafNoFPDirect"), "dump_spec", "extra_label", + function(dump_spec) {return callLeafInfo(dump_spec, 0);}); + +// Add extra line to exception creation nodes with the name of the exception. +function exceptionInfo(dump_spec) { + dump_spec2 = dump_spec.replace('#','') + dump_components = split_string(dump_spec2); + if (dump_components.length < 1) { + return null; + } + // dump_components[0] has a form like e.g. java/lang/NumberFormatException:NotNull, + // we want to return only the simple class name ("NumberFormatException"). + simple_classname = dump_components[0].split("/").pop(); + return simple_classname.split(":")[0]; +} +editProperty(matches("name", "CreateEx|CreateException"), "dump_spec", "extra_label", exceptionInfo); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControl.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControl.filter index f3c28c2e84d..cfa8bb4e115 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControl.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControl.filter @@ -1,3 +1 @@ -var f = new RemoveFilter("Hide control subgraph"); -f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "control")))); -f.apply(graph); +remove(matches("category", "control")); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControlEdges.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControlEdges.filter index f5f072156bf..915a0bdfcfd 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControlEdges.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideControlEdges.filter @@ -1,5 +1 @@ -var f = new ConnectionFilter("Hide control edges"); -f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "control")), - white, - Connection.ConnectionStyle.INVISIBLE)); -f.apply(graph); +styleOutputConnections(matches("category", "control"), white, invisibleConnection); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideData.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideData.filter index 0e1359f9908..3099b563560 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideData.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideData.filter @@ -1,3 +1 @@ -var f = new RemoveFilter("Hide data subgraph"); -f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "data")))); -f.apply(graph); +remove(matches("category", "data")); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideDataEdges.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideDataEdges.filter index 59842237ced..14b99dadf82 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideDataEdges.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideDataEdges.filter @@ -1,5 +1 @@ -var f = new ConnectionFilter("Hide data edges"); -f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "data")), - white, - Connection.ConnectionStyle.INVISIBLE)); -f.apply(graph); +styleOutputConnections(matches("category", "data"), white, invisibleConnection); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideExceptionBlocks.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideExceptionBlocks.filter index f9e0ae0ee21..0cc44035b4b 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideExceptionBlocks.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideExceptionBlocks.filter @@ -1,18 +1,2 @@ // Hide exception blocks. - -var f = new RemoveBlockFilter("Hide exception blocks"); -f.addRule( - new RemoveBlockFilter.RemoveBlockRule( - new AnySelector( - new OrSelector( - new MatcherSelector( - new Properties.StringPropertyMatcher("name", "Rethrow") - ), - new MatcherSelector( - new Properties.StringPropertyMatcher("name", "RethrowException") - ) - ) - ) - ) -); -f.apply(graph); +removeBlock(hasAnyNode(matches("name", "Rethrow|RethrowException"))); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemory.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemory.filter index d85e050bf4c..65aaad6d565 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemory.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemory.filter @@ -1,3 +1 @@ -var f = new RemoveFilter("Hide memory subgraph"); -f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "memory")))); -f.apply(graph); +remove(matches("category", "memory")); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemoryEdges.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemoryEdges.filter index 360533e74b8..4643f165eb5 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemoryEdges.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMemoryEdges.filter @@ -1,5 +1 @@ -var f = new ConnectionFilter("Hide memory edges"); -f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "memory")), - white, - Connection.ConnectionStyle.INVISIBLE)); -f.apply(graph); +styleOutputConnections(matches("category", "memory"), white, invisibleConnection); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixed.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixed.filter index a0693aeabf9..9fec2b20f36 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixed.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixed.filter @@ -1,3 +1 @@ -var f = new RemoveFilter("Hide mixed subgraph"); -f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "mixed")))); -f.apply(graph); +remove(matches("category", "mixed")); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixedEdges.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixedEdges.filter index 7e367d48019..b1684bff9a9 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixedEdges.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideMixedEdges.filter @@ -1,5 +1 @@ -var f = new ConnectionFilter("Hide mixed edges"); -f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "mixed")), - white, - Connection.ConnectionStyle.INVISIBLE)); -f.apply(graph); +styleOutputConnections(matches("category", "mixed"), white, invisibleConnection); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOther.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOther.filter index f345d2781a1..6663cf24154 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOther.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOther.filter @@ -1,3 +1 @@ -var f = new RemoveFilter("Hide other subgraph"); -f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "other")))); -f.apply(graph); +remove(matches("category", "other")); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOtherEdges.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOtherEdges.filter index bf6f7e86c5e..f5de662269f 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOtherEdges.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideOtherEdges.filter @@ -1,5 +1 @@ -var f = new ConnectionFilter("Hide other edges"); -f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "other")), - white, - Connection.ConnectionStyle.INVISIBLE)); -f.apply(graph); +styleOutputConnections(matches("category", "other"), white, invisibleConnection); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideRootBlock.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideRootBlock.filter index 5c78ed09403..ea77865f7ed 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideRootBlock.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideRootBlock.filter @@ -1,13 +1,2 @@ // Remove root block and all nodes in it (hopefully just the Root node). - -var f = new RemoveBlockFilter("Hide root block"); -f.addRule( - new RemoveBlockFilter.RemoveBlockRule( - new AnySelector( - new MatcherSelector( - new Properties.RegexpPropertyMatcher("name", "Root") - ) - ) - ) -); -f.apply(graph); +removeBlock(hasAnyNode(matches("name", "Root"))); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideUncommonTrapBlocks.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideUncommonTrapBlocks.filter index 10f91038ed7..1ab30f6701e 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideUncommonTrapBlocks.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/hideUncommonTrapBlocks.filter @@ -1,13 +1,2 @@ // Hide uncommon trap blocks. - -var f = new RemoveBlockFilter("Hide uncommon trap blocks"); -f.addRule( - new RemoveBlockFilter.RemoveBlockRule( - new AnySelector( - new MatcherSelector( - new Properties.RegexpPropertyMatcher("dump_spec", ".*uncommon_trap.*") - ) - ) - ) -); -f.apply(graph); +removeBlock(hasAnyNode(matches("dump_spec", ".*uncommon_trap.*"))); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter index b73668e9490..cb9e9c62521 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter @@ -1,27 +1,6 @@ // Remove all nodes except control, mixed, and nodes of 'bottom' type that are // successors of control nodes (typically 'Halt', 'Return', etc.). - -var f = new RemoveFilter("Show only control flow"); -f.addRule( - new RemoveFilter.RemoveRule( - new InvertSelector( - new OrSelector( - new MatcherSelector( - new Properties.RegexpPropertyMatcher("category", "control|mixed") - ), - new AndSelector( - new SuccessorSelector( - new MatcherSelector( - new Properties.RegexpPropertyMatcher("type", "control") - ) - ), - new MatcherSelector( - new Properties.RegexpPropertyMatcher("type", "bottom") - ) - ) - ) - ), - false - ) -); -f.apply(graph); \ No newline at end of file +remove(not(or([matches("name", "Root"), + matches("category", "control|mixed"), + and([matches("type", "bottom"), + successorOf(matches("type", "control"))])]))); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/simplifyGraph.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/simplifyGraph.filter new file mode 100644 index 00000000000..69da0575cc2 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/simplifyGraph.filter @@ -0,0 +1,16 @@ +// Hide graph elements that are typically (but not always) unnecessary to +// analyze the intermediate representation. This filter is most effective in +// combination with "Condense graph". + +// Remove self-loops (typical for region-like control nodes). +removeSelfLoops(); + +// Hide secondary edges. +remove(matches("short_name", "FP|RA|IO|RP")); + +// Remove back-edges to the Root node. +removeInputs(matches("name", "Root"), matches("name", ".*")); + +// Remove top inputs from call-like nodes. +removeInputs(matches("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect|Halt|Rethrow|ShouldNotReachHere|RethrowException|Return|Ret|MergeMem|Initialize|MemBarAcquire|MemBarRelease|Unlock|Lock|Allocate|AllocateArray"), + and([matches("name", "Con"), matches("type", "top")])); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/structural.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/structural.filter deleted file mode 100644 index 34d91b9f7da..00000000000 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/structural.filter +++ /dev/null @@ -1,19 +0,0 @@ -// Hide secondary edges. -remove("dump_spec", "FramePtr|ReturnAdr|I_O"); -removeInputs("name", "Root"); -var f = new RemoveSelfLoopsFilter("Remove Self-Loops"); -f.apply(graph); -removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5); -removeInputs("name", "Unlock|Lock", 7); -removeInputs("name", "Allocate", 7); -removeInputs("name", "AllocateArray", 9); - -// Combine projection nodes. -var f = new CombineFilter("Combine Filter"); -f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj"))); -f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool"))); -f.apply(graph); - -// Inline (split) constant nodes. -split("name", "BoxLock"); -split("name", "(Con.*)|(loadCon.*)", "[dump_spec]"); \ No newline at end of file diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml index 209aaab3926..6372b5a1e84 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml @@ -13,13 +13,21 @@ - + + + + + - + + + + + - + diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java index fe0156c5bbd..8bbc562a7d2 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java @@ -106,7 +106,7 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe middleWidget.setBackground(f.getColor()); middleWidget.setOpaque(true); middleWidget.getActions().addAction(new DoubleClickAction(this)); - middleWidget.setCheckClipping(true); + middleWidget.setCheckClipping(false); dummyTop = new Widget(scene); int extraTopHeight = @@ -137,6 +137,7 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe lw.setAlignment(LabelWidget.Alignment.CENTER); lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER); lw.setBorder(BorderFactory.createEmptyBorder()); + lw.setCheckClipping(false); } if (getFigure().getWarning() != null) { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java index 911567001e4..42bc7bb099f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -23,9 +23,16 @@ */ package com.sun.hotspot.igv.view.widgets; +import com.sun.hotspot.igv.graph.Diagram; import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.graph.FigureConnection; import com.sun.hotspot.igv.graph.InputSlot; import com.sun.hotspot.igv.view.DiagramScene; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; import java.util.List; import org.netbeans.api.visual.widget.Widget; @@ -36,10 +43,12 @@ import org.netbeans.api.visual.widget.Widget; public class InputSlotWidget extends SlotWidget { private InputSlot inputSlot; + private DiagramScene scene; public InputSlotWidget(InputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) { super(slot, scene, parent, fw); inputSlot = slot; + this.scene = scene; } public InputSlot getInputSlot() { @@ -58,4 +67,65 @@ public class InputSlotWidget extends SlotWidget { return getFigureWidget().getFigure().getDiagram().isCFG() ? calculateClientArea().height - 1 : Figure.SLOT_START; } + + @Override + protected void paintWidget() { + super.paintWidget(); + if (getScene().getZoomFactor() < TEXT_ZOOM_FACTOR) { + return; + } + // If there is a gap between the current slot and the previous one, and + // both are visible, draw a label in between signaling the gap. + int index = inputSlot.getPosition(); + int originalIndex = inputSlot.getOriginalIndex(); + InputSlot prevSlot = index > 0 ? inputSlot.getFigure().getInputSlots().get(index - 1) : null; + int prevOriginalIndex = index > 0 ? prevSlot.getOriginalIndex() : -1; + if (originalIndex > prevOriginalIndex + 1 && + hasVisibleConnection(inputSlot) && hasVisibleConnection(prevSlot) && + !scene.getModel().getShowCFG()) { + Graphics2D g = scene.getGraphics(); + String label = "..."; + g.setColor(Color.BLACK); + g.setFont(Diagram.SLOT_FONT.deriveFont(Font.BOLD)); + Rectangle2D labelRect = new Canvas().getFontMetrics(Diagram.SLOT_FONT).getStringBounds(label, g); + int slotWidth = this.calculateClientArea().width; + int xStart = this.getBounds().x + (inputSlot.hasSourceNodes() ? 0 : (slotWidth / 2)); + int prevXEnd; + if (index > 0) { + // Compute X coordinates of previous input slot comparing its + // calculateClientArea() with that of the current slot. + InputSlotWidget prevWidget = (InputSlotWidget)scene.findWidget(prevSlot); + int prevSlotWidth = prevWidget.calculateClientArea().width; + int xStartAbs = inputSlot.getRelativePosition().x - (slotWidth / 2); + int prevXStartAbs = prevSlot.getRelativePosition().x - (prevSlotWidth / 2); + int prevXStart = prevXStartAbs - xStartAbs; + prevXEnd = prevXStart + (prevSlot.hasSourceNodes() ? prevSlotWidth : (prevSlotWidth / 2)); + } else { + // No previous input slot, just set its position to the left of + // the current one. + prevXEnd = xStart - (int) (labelRect.getWidth()) - 4; + } + int midX = (prevXEnd + xStart) / 2; + g.drawString(label, midX - (int)(labelRect.getWidth() / 2), 3); + } + } + + // This method needs to be called at painting time, so that the right + // FigureWidget::isVisible() result is picked up. + private boolean hasVisibleConnection(InputSlot slot) { + if (slot == null) { + return true; + } + if (slot.hasSourceNodes()) { + return true; + } + for (FigureConnection c : slot.getConnections()) { + Figure f = c.getOutputSlot().getFigure(); + FigureWidget fw = (FigureWidget)scene.findWidget(f); + if (fw.isVisible()) { + return true; + } + } + return false; + } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/SlotWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/SlotWidget.java index e264329db1f..f6f7fa6b80b 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/SlotWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/SlotWidget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -46,8 +46,8 @@ public abstract class SlotWidget extends Widget implements DoubleClickHandler { private Slot slot; private FigureWidget figureWidget; - private static double TEXT_ZOOM_FACTOR = 0.9; - private static double ZOOM_FACTOR = 0.6; + protected static double TEXT_ZOOM_FACTOR = 0.9; + protected static double ZOOM_FACTOR = 0.6; private DiagramScene diagramScene; public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) { @@ -58,7 +58,8 @@ public abstract class SlotWidget extends Widget implements DoubleClickHandler { if (slot.hasSourceNodes()) { this.setToolTipText("" + slot.getToolTipText() + ""); } - this.setCheckClipping(true); + // No clipping, to let input slots draw gap markers outside their bounds. + this.setCheckClipping(false); parent.addChild(this); Point p = slot.getRelativePosition();