From fc50896434468bd26f485c71b0a0f4ab4f086d54 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:38 -0700 Subject: [PATCH 01/29] Trace total time in HierarchicalLayoutManager --- .../HierarchicalLayoutManager.java | 55 +++++-- ...ierarchicalLayoutManagerBenchmarkTest.java | 147 ++++++++++++++++++ 2 files changed, 193 insertions(+), 9 deletions(-) create mode 100644 visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerBenchmarkTest.java diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index 3aa2a7e98994..cf81786904bc 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -98,7 +98,7 @@ public class HierarchicalLayoutManager implements LayoutManager { private static final Logger LOG = Logger.getLogger(HierarchicalLayoutManager.class.getName()); - public static final boolean TRACE = false; + public static final boolean TRACE_DEFAULT = false; public static final boolean CHECK = false; public static final int SWEEP_ITERATIONS = 1; public static final int CROSSING_ITERATIONS = 2; @@ -111,6 +111,15 @@ public class HierarchicalLayoutManager implements LayoutManager { private final AtomicBoolean cancelled; + private boolean trace = TRACE_DEFAULT; + + /** + * Enable or disable tracing of time spent in each step of the algorithm. + */ + public void setTrace(boolean t) { + trace = t; + } + @Override public boolean cancel() { cancelled.set(true); @@ -322,22 +331,46 @@ public LayoutEdge(LayoutNode from, LayoutNode to, int relativeFrom, int relative } } + static final ThreadLocal indent = ThreadLocal.withInitial(() -> 0); + + private void traceEnd(long start, Class theClass) { + if (trace) { + for (int i = 0; i < indent.get(); i++) { + System.out.print(' '); + } + System.out.println("Timing for " + theClass.getName() + " is " + (System.currentTimeMillis() - start)); + } + } + + private long traceBegin(Class theClass) { + long start = 0; + if (trace) { + for (int i = 0; i < indent.get(); i++) { + System.out.print(' '); + } + System.out.println("Starting part " + theClass.getName()); + start = System.currentTimeMillis(); + } + return start; + } + private abstract class AlgorithmPart { + public void start() { if (CHECK) { preCheck(); } - long start = 0; - if (TRACE) { - System.out.println("##################################################"); - System.out.println("Starting part " + this.getClass().getName()); - start = System.currentTimeMillis(); + try { + indent.set(indent.get() + 2); + long start = traceBegin(getClass()); + run(); + traceEnd(start, getClass()); + } finally { + indent.set(indent.get() - 2); } - run(); - if (TRACE) { - System.out.println("Timing for " + this.getClass().getName() + " is " + (System.currentTimeMillis() - start)); + if (trace) { printStatistics(); } @@ -422,6 +455,8 @@ public void doLayout(LayoutGraph graph) { cleanup(); + long start = traceBegin(getClass()); + // ############################################################# // Step 1: Build up data structure new BuildDatastructure().start(); @@ -474,6 +509,8 @@ public void doLayout(LayoutGraph graph) { // ############################################################# // STEP 8: Write back to interface new WriteResult().start(); + + traceEnd(start, getClass()); } private class WriteResult extends AlgorithmPart { diff --git a/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerBenchmarkTest.java b/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerBenchmarkTest.java new file mode 100644 index 000000000000..9eb7c5a5bd02 --- /dev/null +++ b/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerBenchmarkTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2025, 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 org.graalvm.visualizer.view; + +import jdk.graal.compiler.graphio.parsing.BinaryReader; +import jdk.graal.compiler.graphio.parsing.BinarySource; +import jdk.graal.compiler.graphio.parsing.GraphParser; +import jdk.graal.compiler.graphio.parsing.ModelBuilder; +import jdk.graal.compiler.graphio.parsing.model.FolderElement; +import jdk.graal.compiler.graphio.parsing.model.GraphDocument; +import jdk.graal.compiler.graphio.parsing.model.Group; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; +import org.graalvm.visualizer.data.serialization.lazy.FileContent; +import org.graalvm.visualizer.graph.Connection; +import org.graalvm.visualizer.graph.Diagram; +import org.graalvm.visualizer.graph.Figure; +import org.graalvm.visualizer.hierarchicallayout.HierarchicalLayoutManager; +import org.graalvm.visualizer.layout.LayoutGraph; +import org.graalvm.visualizer.settings.layout.LayoutSettings; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openide.util.Exceptions; + +import java.awt.Dimension; +import java.io.File; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.StandardOpenOption; +import java.util.HashSet; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import static org.graalvm.visualizer.settings.layout.LayoutSettings.MAX_LAYER_LENGTH; + +/** + * This is a somewhat ad-hoc benchmark of layout performance. It's ad hoc because of the complexity of integrating + * JMH with maven since that seems to require having the benchmark in a separate pom.xml. The test can be launched with + * the following command line. + *
+ *     mvn test -Dtest=org.graalvm.visualizer.view.HierarchicalLayoutManagerBenchmarkTest -DfailIfNoTests=false -DenableAssertions=false -DHierarchicalLayoutManagerBenchmarkTest.file=<filename>
+ * 
+ */ +public class HierarchicalLayoutManagerBenchmarkTest { + + static final String BENCHMARK_TEST_FILE = "HierarchicalLayoutManagerBenchmarkTest.file"; + static final String BENCHMARK_TEST_ITERATIONS = "HierarchicalLayoutManagerBenchmarkTest.iterations"; + + private static Diagram diagram; + + protected static GraphDocument loadData(File f) { + try { + final FileChannel channel = FileChannel.open(f.toPath(), StandardOpenOption.READ); + FileContent content = new FileContent(f.toPath(), channel); + BinarySource src = new BinarySource(null, content); + + GraphDocument targetDocument = new GraphDocument(); + ModelBuilder bld = new ModelBuilder(targetDocument, null); + bld.setDocumentId(""); + GraphParser parser = new BinaryReader(src, bld); + return parser.parse(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static final LayoutSettings.LayoutSettingBean layoutSetting = LayoutSettings.getBean(); + + @BeforeClass + public static void beforeClass() { + // Create BinarySource and parse document + String pathname = System.getProperty(BENCHMARK_TEST_FILE); + Assume.assumeTrue("Must set " + BENCHMARK_TEST_FILE + " property to run benchmark", pathname != null); + GraphDocument doc = loadData(new File(pathname)); + + // Find first Group and first InputGraph in it + List elements = doc.getElements(); + Group group = (Group) elements.get(0); + InputGraph inputGraph = null; + for (FolderElement fe : group.getElements()) { + if (fe instanceof InputGraph) { + inputGraph = (InputGraph) fe; + break; + } + } + if (inputGraph == null) { + throw new IllegalStateException("No InputGraph found in BGV file"); + } + InputGraph g = inputGraph; + if (g instanceof Group.LazyContent) { + Group.LazyContent lg = (Group.LazyContent) g; + if (!lg.isComplete()) { + try { + lg.completeContents(null).get(); + } catch (InterruptedException | ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + } + } + diagram = Diagram.createDiagram(inputGraph, ""); + } + + + @Test + public void benchmarkHierarchicalLayout() { + int iterations = Integer.parseInt(System.getProperty(BENCHMARK_TEST_ITERATIONS, "3")); + + for (int i = 0; i < iterations; i++) { + // Prepare layout input + HashSet
figures = new HashSet<>(diagram.getFigures()); + figures.forEach(x -> x.setVisible(true)); + HashSet edges = new HashSet<>(diagram.getConnections()); + LayoutGraph layoutGraph = new LayoutGraph(edges, figures); + + HierarchicalLayoutManager mgr = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS, layoutSetting); + mgr.setTrace(true); + + mgr.setMaxLayerLength(layoutSetting.get(Integer.class, MAX_LAYER_LENGTH)); + mgr.doLayout(layoutGraph); + + Dimension size = layoutGraph.getSize(); + if (size == null) { + throw new RuntimeException("Layout produced no size."); + } + } + } +} From 586c60386226f5b8148357a36c0150ab6e9d2650 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 30 Oct 2025 08:54:59 -0700 Subject: [PATCH 02/29] Add stress test harness --- .../graphio/parsing/BinaryReader.java | 15 ++ .../parsing/model/GraphDocumentVisitor.java | 96 +++++++++++ .../HierarchicalLayoutManagerStressTest.java | 156 ++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java create mode 100644 visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java index 300ac259a2db..f59bbf9c1373 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java @@ -91,6 +91,8 @@ public class BinaryReader implements GraphParser, ModelControl { private static final Logger LOG = Logger.getLogger(BinaryReader.class.getName()); + static final boolean TRACE_PARSE_TIME = false; + private final Logger instLog; private final DataSource dataSource; @@ -808,6 +810,7 @@ public GraphDocument parse() throws IOException { hashStack.push(null); boolean restart = false; + long start = System.nanoTime(); try { while (true) { // TERMINATION ARGUMENT: finite length of data source will result in // EOFException eventually. @@ -831,6 +834,11 @@ public GraphDocument parse() throws IOException { } finally { // also terminates the builder closeDanglingGroups(); + long end = System.nanoTime(); + if (TRACE_PARSE_TIME) { + System.err.println((System.currentTimeMillis() - timeStart) + " Parsed file in " + ((end - start) / 1000000) + " ms"); + } + } return builder.rootDocument(); } @@ -990,7 +998,10 @@ private InputGraph parseGraph(String title, boolean toplevel) throws IOException } } + private static final long timeStart = System.currentTimeMillis(); + private InputGraph parseGraph(int dumpId, String format, Object[] args, boolean toplevel) throws IOException { + long start = System.nanoTime(); InputGraph g = builder.startGraph(dumpId, format, args); try { parseProperties(); @@ -1014,6 +1025,10 @@ private InputGraph parseGraph(int dumpId, String format, Object[] args, boolean // we have to finish the graph. reporter.popContext(); g = builder.endGraph(); + long end = System.nanoTime(); + if (TRACE_PARSE_TIME) { + System.err.println((System.currentTimeMillis() - timeStart) + " Parsed " + dumpId + " " + String.format(format, args) + " in " + ((end - start) / 1000000) + " ms"); + } } return g; } diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java new file mode 100644 index 000000000000..fa99503c576e --- /dev/null +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013, 2024, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.graal.compiler.graphio.parsing.model; + +import java.util.function.Consumer; + +/** + * Visitor interface to traverse the various elements of the {@link GraphDocument} tree. Traversal + * can be stopped early by returning {@code false} from any of the {@code visit} methods. + */ +public interface GraphDocumentVisitor { + + static void visitAll(GraphDocument doc, Consumer visit) { + GraphDocumentVisitor visitor = inputGraph -> { + visit.accept(inputGraph); + return true; + }; + visitor.visit(doc); + } + + /** + * Visits a {@link Folder} in the graph document, which could be the top-level + * {@link GraphDocument} or a nested {@link Group}. + *

+ * The default implementation visits all elements in order, stopping if + * {@link #visit(FolderElement)} returns false for any of them. + */ + default boolean visit(Folder folder) { + for (FolderElement elem : folder.getElements()) { + if (!visit(elem)) { + return false; + } + } + return true; + } + + /** + * Visits an {@link InputGraph}. Implementors can choose whether to stop at the outermost level + * or also consider nested subgraphs. + */ + boolean visit(InputGraph inputGraph); + + /** + * Visits a {@link Group}. The default implementation delegates to {@link #visit(Folder)}. + */ + default boolean visit(Group g) { + return visit((Folder) g); + } + + /** + * Visits a {@link GraphDocument}. The default implementation delegates to + * {@link #visit(Folder)}. + */ + default boolean visit(GraphDocument document) { + return visit((Folder) document); + } + + /** + * Visits a {@link FolderElement}. The default implementation delegates to the {@code visit} + * version corresponding to the concrete type of {@code element}. + */ + default boolean visit(FolderElement element) { + if (element instanceof Group group) { + return visit(group); + } + if (element instanceof InputGraph inputGraph) { + return visit(inputGraph); + } + if (element instanceof Folder folder) { + return visit(folder); + } + return true; + } +} diff --git a/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java b/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java new file mode 100644 index 000000000000..0f450b8bb686 --- /dev/null +++ b/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java @@ -0,0 +1,156 @@ +package org.graalvm.visualizer.view; + +import jdk.graal.compiler.graphio.parsing.BinaryReader; +import jdk.graal.compiler.graphio.parsing.BinarySource; +import jdk.graal.compiler.graphio.parsing.GraphParser; +import jdk.graal.compiler.graphio.parsing.ModelBuilder; +import jdk.graal.compiler.graphio.parsing.model.GraphDocument; +import jdk.graal.compiler.graphio.parsing.model.GraphDocumentVisitor; +import jdk.graal.compiler.graphio.parsing.model.Group; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; +import org.graalvm.visualizer.data.serialization.lazy.FileContent; +import org.graalvm.visualizer.data.serialization.lazy.LazyModelBuilder; +import org.graalvm.visualizer.data.serialization.lazy.ReaderErrors; +import org.graalvm.visualizer.graph.Block; +import org.graalvm.visualizer.graph.Connection; +import org.graalvm.visualizer.graph.Diagram; +import org.graalvm.visualizer.graph.Figure; +import org.graalvm.visualizer.hierarchicallayout.HierarchicalClusterLayoutManager; +import org.graalvm.visualizer.hierarchicallayout.HierarchicalLayoutManager; +import org.graalvm.visualizer.layout.LayoutGraph; +import org.graalvm.visualizer.settings.layout.LayoutSettings; +import org.junit.Assume; +import org.junit.Test; +import org.openide.util.Exceptions; + +import java.awt.Dimension; +import java.io.File; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.HashSet; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import static org.graalvm.visualizer.settings.layout.LayoutSettings.MAX_BLOCK_LAYER_LENGTH; +import static org.graalvm.visualizer.settings.layout.LayoutSettings.MAX_LAYER_LENGTH; + +public class HierarchicalLayoutManagerStressTest { + static final String STRESS_TEST_PATH = "HierarchicalLayoutManagerStressTest.path"; + static final String STRESS_TEST_VERBOSE = "HierarchicalLayoutManagerStressTest.verbose"; + + protected static GraphDocument loadData(File f) { + try { + final FileChannel channel = FileChannel.open(f.toPath(), StandardOpenOption.READ); + FileContent content = new FileContent(f.toPath(), channel); + BinarySource src = new BinarySource(null, content); + + GraphDocument targetDocument = new GraphDocument(); + ModelBuilder bld = new LazyModelBuilder(targetDocument, null); + bld.setDocumentId(""); + GraphParser parser = new BinaryReader(src, bld); + return parser.parse(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + LayoutSettings.LayoutSettingBean layoutSettings = LayoutSettings.getBean(); + boolean verbose = Boolean.getBoolean(STRESS_TEST_VERBOSE); + + @Test + public void stressHierarchicalLayout() throws IOException { + // Create BinarySource and parse document + String pathname = System.getProperty(STRESS_TEST_PATH); + Assume.assumeTrue("Must set " + STRESS_TEST_PATH + " property to run benchmark", pathname != null); + + Path path = new File(pathname).toPath(); + if (Files.isDirectory(path)) { + try (Stream walk = Files.walk(path, 1)) { + walk.forEach(this::layoutFile); + } + } else { + layoutFile(path); + } + } + + private void layoutFile(Path path) { + if (!path.toString().endsWith(".bgv")) { + return; + } + System.err.println("Processing " + path); + GraphDocument doc = loadData(path.toFile()); + GraphDocumentVisitor.visitAll(doc, this::doLayout); + } + + /** + * Resolve any lazy context. + */ + private static InputGraph completeGraph(InputGraph g) { + if (g instanceof Group.LazyContent) { + Group.LazyContent lg = (Group.LazyContent) g; + if (!lg.isComplete()) { + try { + lg.completeContents(null).get(); + } catch (InterruptedException | ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + } + } + return g; + } + + private void doLayout(InputGraph inputGraph) { + if (verbose) { + System.err.println("Laying out " + inputGraph.getName()); + } + + boolean hasError = ReaderErrors.containsError(inputGraph, false); + if (hasError) { + System.err.println("Skipping " + inputGraph.getName() + " because of loading errors"); + return; + } + InputGraph graph = completeGraph(inputGraph); + Diagram d = Diagram.createDiagram(graph, ""); + + LayoutGraph layoutGraph = getLayoutGraph(d); + + HierarchicalLayoutManager mgr = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS, layoutSettings); + mgr.setMaxLayerLength(layoutSettings.get(Integer.class, MAX_LAYER_LENGTH)); + mgr.doLayout(layoutGraph); + + Dimension size = layoutGraph.getSize(); + if (size == null) { + throw new RuntimeException("Layout produced no size."); + } + + layoutGraph = getLayoutGraph(d); + + HierarchicalClusterLayoutManager clusterManager = new HierarchicalClusterLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS, layoutSettings); + clusterManager.getManager().setMaxLayerLength(layoutSettings.get(Integer.class, MAX_BLOCK_LAYER_LENGTH)); + clusterManager.getSubManager().setMaxLayerLength(layoutSettings.get(Integer.class, MAX_LAYER_LENGTH)); + clusterManager.doLayout(layoutGraph); + + size = layoutGraph.getSize(); + if (size == null) { + throw new RuntimeException("Layout produced no size."); + } + } + + private static LayoutGraph getLayoutGraph(Diagram outputDiagram) { + // Prepare layout input + for (Figure f : outputDiagram.getFigures()) { + f.setVisible(true); + f.setBoundary(false); + } + for (Block b : outputDiagram.getBlocks()) { + b.setVisible(true); + } + HashSet

figures = new HashSet<>(outputDiagram.getFigures()); + HashSet edges = new HashSet<>(outputDiagram.getConnections()); + LayoutGraph layoutGraph = new LayoutGraph(edges, figures); + return layoutGraph; + } +} From 1dfa2e6636f4693e9ff538cf11ef73002cf8eee9 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 29 Oct 2025 11:53:55 -0700 Subject: [PATCH 03/29] Complain about $ in file names passed to the launcher --- .../src/main/launchers/bin/idealgraphvisualizer | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/visualizer/IdealGraphVisualizer/application/src/main/launchers/bin/idealgraphvisualizer b/visualizer/IdealGraphVisualizer/application/src/main/launchers/bin/idealgraphvisualizer index e9622683e452..8bd327ef04b5 100755 --- a/visualizer/IdealGraphVisualizer/application/src/main/launchers/bin/idealgraphvisualizer +++ b/visualizer/IdealGraphVisualizer/application/src/main/launchers/bin/idealgraphvisualizer @@ -75,7 +75,12 @@ while [ $# -gt 0 ] ; do case "$1" in --userdir) shift; if [ $# -gt 0 ] ; then userdir="$1"; fi ;; - *) args="$args \"$1\"" + *) + if [[ "$1" == *\$* ]]; then + echo "Error: Argument '$1' contains a \$ character which cannot be safely handled the launcher script" >&2 + exit 1 + fi + args="$args \"$1\"" ;; esac shift From ae2c7d041fc07fa72519bc502b522976d2b7ab1c Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:39 -0700 Subject: [PATCH 04/29] Add -g to build --- visualizer/IdealGraphVisualizer/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/visualizer/IdealGraphVisualizer/pom.xml b/visualizer/IdealGraphVisualizer/pom.xml index eae0c12566ac..ab34498ff584 100644 --- a/visualizer/IdealGraphVisualizer/pom.xml +++ b/visualizer/IdealGraphVisualizer/pom.xml @@ -31,6 +31,9 @@ 11 17 + + -g + From 30295893e2f0654583cee7316be3ac455c1a533a Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:39 -0700 Subject: [PATCH 05/29] Support bulk removal of figures --- .../graalvm/visualizer/graph/Connection.java | 17 ++++ .../org/graalvm/visualizer/graph/Diagram.java | 60 +++++++----- .../org/graalvm/visualizer/graph/Figure.java | 91 +++++++++++++++---- .../org/graalvm/visualizer/graph/Slot.java | 43 +++++++-- 4 files changed, 158 insertions(+), 53 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Connection.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Connection.java index 06707dc83664..35308e3b0f4d 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Connection.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Connection.java @@ -29,6 +29,7 @@ import java.awt.Point; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; public final class Connection implements Link { @@ -141,6 +142,22 @@ public void remove() { outputSlot.connections.remove(this); } + /** + * When removing large numbers of figures, repeatedly removing individual edges becomes n squared because + * of the use of ArrayList. If the {@code cleaned} map is passed in then the Figures to be removed have been marked + * with {@link Figure#isDeleted()}. The lists of successor, predecessors and connections are then just cleaned once. + */ + public void remove(HashSet cleaned) { + if (cleaned == null) { + remove(); + return; + } + + inputSlot.cleanDeletedFigures(cleaned); + outputSlot.cleanDeletedFigures(cleaned); + } + + public String getToolTipText() { StringBuilder builder = new StringBuilder(); if (label != null) { diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java index 238f619c268a..b79da311c5ef 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java @@ -22,24 +22,35 @@ */ package org.graalvm.visualizer.graph; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.NAME_ROOT; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.NAME_START; +import jdk.graal.compiler.graphio.parsing.model.InputBlock; +import jdk.graal.compiler.graphio.parsing.model.InputEdge; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; +import jdk.graal.compiler.graphio.parsing.model.InputNode; +import jdk.graal.compiler.graphio.parsing.model.Properties; +import jdk.graal.compiler.graphio.parsing.model.Properties.EqualityPropertyMatcher; +import org.graalvm.visualizer.data.Source; -import java.awt.*; -import java.util.*; +import java.awt.Dimension; +import java.awt.Font; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Stream; -import org.graalvm.visualizer.data.Source; - -import jdk.graal.compiler.graphio.parsing.model.*; -import jdk.graal.compiler.graphio.parsing.model.Properties; -import jdk.graal.compiler.graphio.parsing.model.Properties.EqualityPropertyMatcher; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.NAME_ROOT; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.NAME_START; /** * Visual model of an {@link InputGraph}. Captures positions, sizes, routing @@ -319,20 +330,18 @@ public static Diagram createDiagram(InputGraph graph, String nodeText) { return d; } - public void removeAllFigures(Collection
figuresToRemove) { - if (figuresToRemove instanceof Set) { - removeAllFigures(((Set) figuresToRemove)); - } - Set s = new HashSet<>(figuresToRemove); - removeAllFigures(s); - } - public void removeAllFigures(Set
figuresToRemove) { if (!figuresToRemove.isEmpty()) { invalidateSlotMap(); } + // First mark all Figures to be deleted + for (Figure f : figuresToRemove) { + f.setDeleted(); + } + // Now remove the edges associated with the deleted figures + HashSet cleaned = new HashSet<>(); for (Figure f : figuresToRemove) { - freeFigure(f); + freeFigure(f, cleaned); } for (Figure f : figuresToRemove) { @@ -348,16 +357,21 @@ private Set collectFigureIds(Figure succ) { return representedIds; } - private void freeFigure(Figure succ) { + private void freeFigure(Figure succ, HashSet cleaned) { Set representedIds = sourceMap == null ? null : collectFigureIds(succ); List inputSlots = new ArrayList<>(succ.getInputSlots()); for (InputSlot s : inputSlots) { - succ.removeInputSlot(s); + succ.removeInputSlot(s, cleaned); } List outputSlots = new ArrayList<>(succ.getOutputSlots()); for (OutputSlot s : outputSlots) { - succ.removeOutputSlot(s); + succ.removeOutputSlot(s, cleaned); + } + + if (cleaned != null) { + // When doing a bulk cleaning, the edges of deleted figures aren't directly updated so clear then here. + succ.clear(); } assert succ.getInputSlots().isEmpty(); @@ -372,7 +386,7 @@ private void freeFigure(Figure succ) { public void removeFigure(Figure succ) { assert this.figureMap.containsValue(succ); - freeFigure(succ); + freeFigure(succ, null); this.figureMap.remove(succ.getId()); invalidateSlotMap(); } diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java index e621c39350c2..f9a56af43632 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java @@ -22,22 +22,31 @@ */ package org.graalvm.visualizer.graph; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.NAME_ROOT; - -import java.awt.*; -import java.awt.image.BufferedImage; -import java.util.*; -import java.util.List; - -import org.graalvm.visualizer.data.Source; -import org.graalvm.visualizer.layout.Cluster; -import org.graalvm.visualizer.layout.Vertex; - import jdk.graal.compiler.graphio.parsing.model.InputBlock; import jdk.graal.compiler.graphio.parsing.model.InputGraph; import jdk.graal.compiler.graphio.parsing.model.InputNode; import jdk.graal.compiler.graphio.parsing.model.Properties; +import org.graalvm.visualizer.data.Source; +import org.graalvm.visualizer.layout.Cluster; +import org.graalvm.visualizer.layout.Vertex; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.NAME_ROOT; public class Figure extends Properties.Entity implements Source.Provider, Vertex, DiagramItem { public static final int INSET = 8; @@ -46,14 +55,14 @@ public class Figure extends Properties.Entity implements Source.Provider, Vertex public static final int SLOT_START = 4; public static final int SLOT_OFFSET = 8; - protected List inputSlots; + protected ArrayList inputSlots; private OutputSlot singleOutput; - private List outputSlots; + private ArrayList outputSlots; private final Source source; private final Diagram diagram; private Point position; - private final List
predecessors; - private final List
successors; + private final ArrayList
predecessors; + private final ArrayList
successors; private List subgraphs; private Color color; private final int id; @@ -64,6 +73,39 @@ public class Figure extends Properties.Entity implements Source.Provider, Vertex private final int hash; private boolean boundary; + /** + * Marked for bulk deletion. + */ + private boolean deleted; + + void setDeleted() { + this.deleted = true; + } + + boolean isDeleted() { + return deleted; + } + + /** + * Drop all edges when deleting a Figure. + */ + void clear() { + assert isDeleted() : this; + if (inputSlots != null) { + inputSlots.clear(); + } + if (outputSlots != null) { + outputSlots.clear(); + } + if (predecessors != null) { + predecessors.clear(); + } + if (successors != null) { + successors.clear(); + } + } + + /** * Visible flag */ @@ -213,6 +255,14 @@ protected void addSuccessor(Figure f) { this.successors.add(f); } + /** + * Clean up all edges which reference an {@link Figure#isDeleted()} figure. + */ + public void cleanDeletedFigures() { + predecessors.removeIf(Figure::isDeleted); + successors.removeIf(Figure::isDeleted); + } + protected void removePredecessor(Figure f) { assert predecessors.contains(f); predecessors.remove(f); @@ -372,13 +422,13 @@ public List getOutputSlots() { } } - void removeInputSlot(InputSlot s) { - s.removeAllConnections(); + void removeInputSlot(InputSlot s, HashSet cleaned) { + s.removeAllConnections(cleaned); inputSlots.remove(s); } - void removeOutputSlot(OutputSlot s) { - s.removeAllConnections(); + void removeOutputSlot(OutputSlot s, HashSet cleaned) { + s.removeAllConnections(cleaned); doRemoveOutputSlot(s); } @@ -545,4 +595,5 @@ private static void replaceFromTo(Figure from, Figure to) { public void replaceFrom(Figure source) { replaceFromTo(source, this); } + } diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Slot.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Slot.java index c74e334f3e65..cea3e3c99dca 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Slot.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Slot.java @@ -22,22 +22,27 @@ */ package org.graalvm.visualizer.graph; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.*; +import jdk.graal.compiler.graphio.parsing.model.InputNode; +import jdk.graal.compiler.graphio.parsing.model.Properties; +import org.graalvm.visualizer.data.Source; +import org.graalvm.visualizer.layout.Port; +import org.graalvm.visualizer.layout.Vertex; +import org.graalvm.visualizer.util.StringUtils; -import java.awt.*; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.List; -import org.graalvm.visualizer.data.Source; -import org.graalvm.visualizer.layout.Port; -import org.graalvm.visualizer.layout.Vertex; -import org.graalvm.visualizer.util.StringUtils; - -import jdk.graal.compiler.graphio.parsing.model.InputNode; -import jdk.graal.compiler.graphio.parsing.model.Properties; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_CONNECTION_COUNT; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_FIGURE; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; public abstract class Slot implements Port, Source.Provider, Properties.Provider { @@ -201,9 +206,13 @@ public List getConnections() { } public void removeAllConnections() { + removeAllConnections(null); + } + + public void removeAllConnections(HashSet cleaned) { List connectionsCopy = new ArrayList<>(this.connections); for (Connection c : connectionsCopy) { - c.remove(); + c.remove(cleaned); } } @@ -212,4 +221,18 @@ public Vertex getVertex() { return figure; } + /** + * Clean up all edges which reference an {@link Figure#isDeleted()} figure. + */ + void cleanDeletedFigures(HashSet cleaned) { + Figure input = getFigure(); + if (!input.isDeleted()) { + if (cleaned.add(input)) { + input.cleanDeletedFigures(); + } + } + if (cleaned.add(this)) { + this.connections.removeIf(x -> x.getInputSlot().getFigure().isDeleted() || x.getOutputSlot().getFigure().isDeleted()); + } + } } From 92c641d756ebe991024a9dd3941be8abf7d58c57 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:39 -0700 Subject: [PATCH 06/29] Allowing caching of filter creation and speed up colorize filter --- .../filter/CachedLanguageFilter.java | 59 ++++++++++++++ .../visualizer/filter/CustomFilter.java | 20 ++++- .../resources/defaultFilters.properties | 1 + .../graal/filters/PropertyColorFilter.java | 78 +++++++++++++++++++ .../visualizer/graal/filters/color.filter | 51 ++++++++---- .../graal/filters/graalFilters.properties | 1 + .../graal/filters/removeState.filter | 4 +- 7 files changed, 197 insertions(+), 17 deletions(-) create mode 100644 visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CachedLanguageFilter.java create mode 100644 visualizer/IdealGraphVisualizer/Graal/src/main/java/org/graalvm/visualizer/graal/filters/PropertyColorFilter.java diff --git a/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CachedLanguageFilter.java b/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CachedLanguageFilter.java new file mode 100644 index 000000000000..39d5b0c9a89a --- /dev/null +++ b/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CachedLanguageFilter.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025, 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 org.graalvm.visualizer.filter; + +import org.graalvm.visualizer.graph.Diagram; + +import java.util.ArrayList; + +/** + * This represents a cacheable filter generated by {@link CustomFilter}. It permits a {@link CustomFilter} to build the + * filter once instead of having to construct the filter for each invocation of the filter. + */ +public class CachedLanguageFilter extends AbstractFilter { + private final ArrayList filters = new ArrayList<>(); + private String name = "CachedLanguageFilter"; + + public CachedLanguageFilter() { + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public void apply(Diagram d) { + for (var filter : filters) { + filter.apply(d); + } + } + + public void add(AbstractFilter filter) { + filters.add(filter); + } +} diff --git a/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CustomFilter.java b/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CustomFilter.java index f6b5edc0d9f6..e6f6646b2a3d 100644 --- a/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CustomFilter.java +++ b/visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CustomFilter.java @@ -77,6 +77,13 @@ public class CustomFilter extends AbstractFilter { private String code; private String name; + /** + * A cached version of the filter chain built by the filter invocation. This permits reusing the filter instead of + * constructor it from scratch each time. If the filter invocation returns an instance of {@link CachedLanguageFilter} + * then that object is saved and used for all future invocations. + */ + private CachedLanguageFilter cachedFilter; + public CustomFilter(String name, String code) { this(name, code, MIME_JAVASCRIPT, Lookup.EMPTY); } @@ -113,6 +120,7 @@ public void setCode(String s) { return; } code = s; + cachedFilter = null; fireChangedEvent(); } @@ -265,6 +273,11 @@ private PreparedScript executeHelperScripts(FilterEnvironment env, Map> stringColorMap = new HashMap<>(); + + public PropertyColorFilter() { + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void apply(Diagram diagram) { + applyColorMap(diagram); + } + + private void applyColorMap(Diagram diagram) { + Set keys = stringColorMap.keySet(); + for (Figure f : diagram.getFigures()) { + for (String property : keys) { + Object value = f.getProperties().get(property); + if (value == null) { + continue; + } + Color color = stringColorMap.get(property).get(value.toString()); + if (color != null) { + f.setColor(color); + } + } + } + } + + /** + * Color any {@link Figure} with the {@code property} equals to {@code value} with the color {@code color}. + */ + public void addRule(String property, String value, Color color) { + stringColorMap.computeIfAbsent(property, x -> new HashMap<>()).put(value, color); + } +} diff --git a/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/color.filter b/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/color.filter index 62d498a7f3f4..e9426526099b 100644 --- a/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/color.filter +++ b/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/color.filter @@ -8,23 +8,44 @@ var gray = new Color(220, 220, 220); var violet = new Color(201, 148, 199); var black = new Color(0, 0, 0); -colorize("category", "controlSink", red); -colorize("category", "controlSplit", red); -colorize("category", "merge", red); -colorize("category", "begin", orange); -colorize("category", "end", orange); -colorize("category", "fixed", yellow); -colorize("category", "state", lightGreen); -colorize("category", "phi", middleBlue); -colorize("category", "proxy", middleBlue); -colorize("category", "floating", lightBlue); -colorize("class", ".*\\.nodes\\..*ParameterNode$", gray); -colorize("class", ".*\\.nodes\\..*ConstantNode$", gray); -colorize("class", ".*\\.nodes\\..*GuardNode$", violet); -colorize("class", ".*\\.nodes\\.debug\\.BlackholeNode$", black); +var cachedFilter = new CachedLanguageFilter(); + +var f = new PropertyColorFilter(); +f.addRule("category", "controlSink", red); +f.addRule("category", "controlSplit", red); +f.addRule("category", "merge", red); +f.addRule("category", "begin", orange); +f.addRule("category", "end", orange); +f.addRule("category", "fixed", yellow); +f.addRule("category", "state", lightGreen); +f.addRule("category", "phi", middleBlue); +f.addRule("category", "proxy", middleBlue); +f.addRule("category", "floating", lightBlue); + +f.addRule("class", "com.oracle.graal.nodes.ParameterNode", gray); +f.addRule("class", "jdk.graal.compiler.nodes.ParameterNode", gray); +f.addRule("class", "org.graalvm.compiler.nodes.ParameterNode", gray); + +f.addRule("class", "com.oracle.graal.nodes.ConstantNode", gray); +f.addRule("class", "jdk.graal.compiler.nodes.ConstantNode", gray); +f.addRule("class", "org.graalvm.compiler.nodes.ConstantNode", gray); + +f.addRule("class", "com.oracle.graal.nodes.GuardNode", violet); +f.addRule("class", "jdk.graal.compiler.nodes.GuardNode", violet); +f.addRule("class", "org.graalvm.compiler.nodes.GuardNode", violet); + +f.addRule("class", "com.oracle.graal.nodes.debug.BlackholeNode", black); +f.addRule("class", "jdk.graal.compiler.nodes.debug.BlackholeNode", black); +f.addRule("class", "org.graalvm.compiler.nodes.debug.BlackholeNode", black); + +cachedFilter.add(f); var f = new GraalEdgeColorFilter(); f.setUsageColor("Successor", red); f.setUsageColor("Value", blue); f.setUsageColor("Memory", new Color(0, 128, 0)); -f.apply(graph); + +cachedFilter.add(f); + +// return the cached filter +cachedFilter diff --git a/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/graalFilters.properties b/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/graalFilters.properties index 7a4660ff1915..aa206c09d917 100644 --- a/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/graalFilters.properties +++ b/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/graalFilters.properties @@ -4,3 +4,4 @@ GraalCFGFilter=org.graalvm.visualizer.graal.filters.GraalCFGFilter GraalColoringFilter=org.graalvm.visualizer.graal.filters.GraalColoringFilter GraalEdgeColorFilter=org.graalvm.visualizer.graal.filters.GraalEdgeColorFilter +PropertyColorFilter=org.graalvm.visualizer.graal.filters.PropertyColorFilter \ No newline at end of file diff --git a/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/removeState.filter b/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/removeState.filter index 5990b13b19fc..1d2e3397076c 100644 --- a/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/removeState.filter +++ b/visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/removeState.filter @@ -1 +1,3 @@ -remove("category", "state"); \ No newline at end of file +// Removing orphans also removes any nodes which no longer have any uses. +// This cleans up Constants which were only referenced by FrameStates +removeIncludingOrphans("category", "state") \ No newline at end of file From 3b4721211e90839afa05136b6ce766767906b4ce Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:40 -0700 Subject: [PATCH 07/29] Reduce use of TreeSet --- .../HierarchicalLayoutManager.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index cf81786904bc..87a41f152c65 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -173,6 +173,10 @@ private class LayoutNode { public final List succs = new ArrayList<>(); public int pos = -1; // Position within layer + public int getPos() { + return pos; + } + public float crossingNumber = 0; public void loadCrossingNumber(boolean up) { @@ -1414,11 +1418,12 @@ public void refresh() { private class NodeRow { - private final TreeSet treeSet; + private final ArrayList positions; private final int[] space; + static final Comparator COMPARATOR = Comparator.comparingInt(LayoutNode::getPos); public NodeRow(int[] space) { - treeSet = new TreeSet<>(NODE_POSITION_COMPARATOR); + this.positions = new ArrayList<>(); this.space = space; } @@ -1429,22 +1434,24 @@ public int offset(LayoutNode n1, LayoutNode n2) { } public void insert(LayoutNode n, int pos) { - SortedSet headSet = treeSet.headSet(n); LayoutNode leftNeighbor; int minX = Integer.MIN_VALUE; - if (!headSet.isEmpty()) { - leftNeighbor = headSet.last(); + int idx = Collections.binarySearch(positions, n, COMPARATOR); + if (idx > 0) { + throw new IllegalArgumentException("already in list"); + } + int insertPos = -idx - 1; // where you would insert + leftNeighbor = insertPos > 0 ? positions.get(insertPos - 1) : null; + LayoutNode rightNeighbor = insertPos < positions.size() ? positions.get(insertPos) : null; + if (leftNeighbor != null) { minX = leftNeighbor.getRightSide() + offset(leftNeighbor, n); } if (pos < minX) { n.x = minX; } else { - LayoutNode rightNeighbor; - SortedSet tailSet = treeSet.tailSet(n); int maxX = Integer.MAX_VALUE; - if (!tailSet.isEmpty()) { - rightNeighbor = tailSet.first(); + if (rightNeighbor != null) { maxX = rightNeighbor.x - offset(n, rightNeighbor) - n.getWholeWidth(); } @@ -1455,7 +1462,7 @@ public void insert(LayoutNode n, int pos) { } assert minX <= maxX : minX + " vs " + maxX; } - treeSet.add(n); + positions.add(insertPos, n); } } From 33a595f0e9d42aa9d8c865d9ad206bc19bbe97de Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:40 -0700 Subject: [PATCH 08/29] Track vip edges on insertion --- .../HierarchicalLayoutManager.java | 263 ++++++++++++------ 1 file changed, 185 insertions(+), 78 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index 87a41f152c65..a8e89b74103b 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -157,6 +157,41 @@ public enum Combine { private final boolean isDelayDanglingNodes; private final boolean isDrawLongEdges; + /** + * Helper class to track the number of VIP edges. + */ + static class VIPArrayList extends ArrayList { + int vips; + + public int getVips() { + return vips; + } + + VIPArrayList() { + } + + public boolean add(LayoutEdge e) { + super.add(e); + if (e.vip) { + vips++; + } + return true; + } + + public boolean remove(Object object) { + boolean remove = super.remove(object); + if (remove && ((LayoutEdge) object).vip) { + vips--; + } + return remove; + } + + public void clear() { + super.clear(); + vips = 0; + } + } + private class LayoutNode { public int x; @@ -169,14 +204,42 @@ private class LayoutNode { public int bottomYOffset; public final Vertex vertex; // Only used for non-dummy nodes, otherwise null - public final List preds = new ArrayList<>(); - public final List succs = new ArrayList<>(); + public final VIPArrayList preds = new VIPArrayList(); + public final VIPArrayList succs = new VIPArrayList(); public int pos = -1; // Position within layer + NodeRow dangling; + + boolean isDangling() { + return dangling != null; + } + + private NodeRow getDanglingRow() { + return this.dangling; + } + + private void setDangling(NodeRow r) { + assert this.dangling == null : this.dangling; + this.dangling = r; + } + + private void removeDangling() { + assert this.dangling != null : this; + this.dangling = null; + } + public int getPos() { return pos; } + public int getPredsVips() { + return preds.getVips(); + } + + public int getSuccsVips() { + return succs.getVips(); + } + public float crossingNumber = 0; public void loadCrossingNumber(boolean up) { @@ -282,7 +345,7 @@ private class LayoutEdge { public int relativeFrom; public int relativeTo; public Link link; - public boolean vip; + public final boolean vip; public int loadCrossingNumber(boolean up, LayoutNode source) { if (isDefaultLayout || !isDummyCrossing || !(up ? to.isDummy() : from.isDummy())) { @@ -320,14 +383,10 @@ public int getEndPoint() { return relativeTo + to.getLeftSide(); } - public LayoutEdge(LayoutNode from, LayoutNode to) { + public LayoutEdge(LayoutNode from, LayoutNode to, int relativeFrom, int relativeTo, Link link, boolean vip) { assert from != null && to != null : "Dangling LayoutEdge."; this.from = from; this.to = to; - } - - public LayoutEdge(LayoutNode from, LayoutNode to, int relativeFrom, int relativeTo, Link link, boolean vip) { - this(from, to); this.relativeFrom = relativeFrom; this.relativeTo = relativeTo; this.link = link; @@ -1031,15 +1090,12 @@ private class AssignXCoordinates extends AlgorithmPart { private LayoutNode[][] upProcessingOrder; private LayoutNode[][] bothProcessingOrder; - private Map dangling = new HashMap<>(); - private void initialPositions() { for (LayoutNode n : nodes) { n.x = space[n.layer][n.pos]; } } - @SuppressWarnings({"rawtypes", "unchecked"}) private void createArrays() { space = new int[layers.length][]; if (isDefaultLayout || !setting.get(Boolean.class, BOTH_SORT)) { @@ -1130,43 +1186,42 @@ private int getVisibleLayer(int start, boolean up) { return -1; } - public List getOptimalPositions(LayoutEdge edge, int layer, List vals, int correction, boolean up) { + public void getOptimalPositions(LayoutEdge edge, int layer, List vals, int correction, boolean up, boolean hasNoDangling) { if (up) { if (edge.from.layer <= layer) { - if (!dangling.containsKey(edge.from)) { + if (!edge.from.isDangling()) { vals.add(edge.getStartPoint() - correction); } } else if (edge.from.isDummy()) { - edge.from.preds.forEach(x -> getOptimalPositions(x, layer, vals, correction, up)); + edge.from.preds.forEach(x -> getOptimalPositions(x, layer, vals, correction, up, hasNoDangling)); } } else { if (edge.to.layer >= layer) { - if (!dangling.containsKey(edge.to)) { + if (!edge.to.isDangling()) { vals.add(edge.getEndPoint() - correction); } } else if (edge.to.isDummy()) { - edge.to.succs.forEach(x -> getOptimalPositions(x, layer, vals, correction, up)); + edge.to.succs.forEach(x -> getOptimalPositions(x, layer, vals, correction, up, hasNoDangling)); } } - return vals; } - private int calculateOptimalDown(LayoutNode n, LayoutNode last) { - List values = new ArrayList<>(); + private int calculateOptimalDown(LayoutNode n, LayoutNode last, boolean hasNoDangling) { + ArrayList values = new ArrayList<>(n.preds.size()); int layer = getVisibleLayer(n.layer, true); - if (n.preds.stream().anyMatch(x -> x.vip)) { + if (n.getPredsVips() != 0) { for (LayoutEdge e : n.preds) { if (e.vip) { - values = getOptimalPositions(e, layer, values, e.relativeTo, true); + getOptimalPositions(e, layer, values, e.relativeTo, true, hasNoDangling); } } } else { for (LayoutEdge e : n.preds) { - values = getOptimalPositions(e, layer, values, e.relativeTo, true); + getOptimalPositions(e, layer, values, e.relativeTo, true, hasNoDangling); } } - return median(values, n, last, true); + return median(values, n, last, true, hasNoDangling); } private int calcLayerCenter(LayoutLayer layer) { @@ -1174,9 +1229,9 @@ private int calcLayerCenter(LayoutLayer layer) { return (layer.get(0).x + last.getRightSide()) / 2; } - private int calcClosestPosition(LayoutNode n, LayoutNode last, boolean up) { + private int calcClosestPosition(LayoutNode n, LayoutNode last, boolean up, boolean hasNoDangling) { assert n != null; - return last == null ? calcLastLayerCenter(n, up) : last.x; + return last == null ? calcLastLayerCenter(n, up, hasNoDangling) : last.x; } public int getExpectedRelativePosition(LayoutLayer layer, LayoutNode n) { @@ -1188,16 +1243,16 @@ public int getExpectedRelativePosition(LayoutLayer layer, LayoutNode n) { return x; } - private int calcLastLayerCenter(LayoutNode n, boolean up) { + private int calcLastLayerCenter(LayoutNode n, boolean up, boolean hasNoDangling) { if (up) { for (int i = n.layer - 1; i >= 0; --i) { - if (layers[i].isVisible() && (dangling.isEmpty() || layers[i].stream().allMatch(node -> !dangling.containsKey(node)))) { + if (layers[i].isVisible() && (hasNoDangling || layers[i].stream().noneMatch(LayoutNode::isDangling))) { return (calcLayerCenter(layers[i]) - layers[n.layer].getMinimalWidth() / 2) + getExpectedRelativePosition(layers[n.layer], n); } } } else { for (int i = n.layer + 1; i < layers.length; ++i) { - if (layers[i].isVisible() && (dangling.isEmpty() || layers[i].stream().allMatch(node -> !dangling.containsKey(node)))) { + if (layers[i].isVisible() && (hasNoDangling || layers[i].stream().noneMatch(LayoutNode::isDangling))) { return (calcLayerCenter(layers[i]) - layers[n.layer].getMinimalWidth() / 2) + getExpectedRelativePosition(layers[n.layer], n); } } @@ -1205,40 +1260,40 @@ private int calcLastLayerCenter(LayoutNode n, boolean up) { return n.x; } - private int calculateOptimalUp(LayoutNode n, LayoutNode last) { - List values = new ArrayList<>(); + private int calculateOptimalUp(LayoutNode n, LayoutNode last, boolean hasNoDangling) { + ArrayList values = new ArrayList<>(n.succs.size()); int layer = getVisibleLayer(n.layer, false); if (isDefaultLayout || !setting.get(Boolean.class, OPTIMAL_UP_VIP)) { for (LayoutEdge e : n.succs) { if (e.vip) { - values = getOptimalPositions(e, layer, new ArrayList<>(), e.relativeFrom, false); + getOptimalPositions(e, layer, new ArrayList<>(), e.relativeFrom, false, hasNoDangling); break; } - values = getOptimalPositions(e, layer, values, e.relativeFrom, false); + getOptimalPositions(e, layer, values, e.relativeFrom, false, hasNoDangling); } } else { - if (n.succs.stream().anyMatch(x -> x.vip)) { + if (n.getSuccsVips() != 0) { for (LayoutEdge e : n.succs) { if (e.vip) { - values = getOptimalPositions(e, layer, values, e.relativeFrom, false); + getOptimalPositions(e, layer, values, e.relativeFrom, false, hasNoDangling); } } } else { for (LayoutEdge e : n.succs) { - values = getOptimalPositions(e, layer, values, e.relativeFrom, false); + getOptimalPositions(e, layer, values, e.relativeFrom, false, hasNoDangling); } } } - return median(values, n, last, false); + return median(values, n, last, false, hasNoDangling); } - private int median(List values, LayoutNode n, LayoutNode last, boolean up) { + private int median(ArrayList values, LayoutNode n, LayoutNode last, boolean up, boolean hasNoDangling) { if (values.isEmpty()) { if (isDefaultLayout || !setting.get(Boolean.class, SQUASH_POSITION)) { return n.x; } else { - return calcClosestPosition(n, last, up); + return calcClosestPosition(n, last, up, hasNoDangling); } } if (setting.get(Boolean.class, CENTER_SIMPLE_NODES) && !n.isDummy() && values.size() == 1 && (up ? n.preds.size() == 1 : n.succs.size() == 1) && !(n.vertex instanceof ClusterSlotNode)) { @@ -1270,20 +1325,42 @@ private void sweepUp() { } else { chosenOrder = bothProcessingOrder; } + + List dangling = new ArrayList<>(); for (int i = layers.length - 2; i >= 0; i--) { - NodeRow r = new NodeRow(space[i]); + NodeRow r = new NodeRow(space[i], chosenOrder[i].length); LayoutNode last = null; for (LayoutNode n : chosenOrder[i]) { - if (!isDefaultLayout && isDelayDanglingNodes && ((n.succs.isEmpty() && !n.preds.isEmpty()) || (!n.succs.isEmpty() && n.succs.stream().allMatch(e -> dangling.containsKey(e.to))))) { - dangling.put(n, r); + if (!isDefaultLayout && isDelayDanglingNodes && ((n.succs.isEmpty() && !n.preds.isEmpty()) || (!n.succs.isEmpty() && isAllDanglingSuccs(n)))) { + n.setDangling(r); + dangling.add(n); } else { - int optimal = calculateOptimalUp(n, last); + int optimal = calculateOptimalUp(n, last, dangling.isEmpty()); r.insert(n, optimal); last = n; } } } - resolveDanglingNodes(true); + resolveDanglingNodes(true, dangling); + } + + private boolean isAllDanglingPreds(LayoutNode n) { + for (LayoutEdge e : n.preds) { + if (!e.from.isDangling()) { + return false; + } + } + return true; + } + + private boolean isAllDanglingSuccs(LayoutNode n) { + if (n.succs.isEmpty()) return false; + for (LayoutEdge e : n.succs) { + if (!e.to.isDangling()) { + return false; + } + } + return true; } private void sweepDown() { @@ -1293,57 +1370,87 @@ private void sweepDown() { } else { chosenOrder = bothProcessingOrder; } + boolean noDefaultAndDelay = !isDefaultLayout && isDelayDanglingNodes; + ArrayList dangling = new ArrayList<>(); for (int i = 1; i < layers.length; i++) { - NodeRow r = new NodeRow(space[i]); + NodeRow r = new NodeRow(space[i], chosenOrder[i].length); LayoutNode last = null; for (LayoutNode n : chosenOrder[i]) { - if (!isDefaultLayout && isDelayDanglingNodes && ((n.preds.isEmpty() && !n.succs.isEmpty()) || (!n.preds.isEmpty() && n.preds.stream().allMatch(e -> dangling.containsKey(e.from))))) { - dangling.put(n, r); + boolean predsIsEmpty = n.preds.isEmpty(); + if (noDefaultAndDelay && (predsIsEmpty ? !n.succs.isEmpty() : !dangling.isEmpty() && isAllDanglingPreds(n))) { + n.setDangling(r); + dangling.add(n); } else { - int optimal = calculateOptimalDown(n, last); + int optimal = calculateOptimalDown(n, last, dangling.isEmpty()); r.insert(n, optimal); last = n; } } } - resolveDanglingNodes(false); + resolveDanglingNodes(false, dangling); + } + + public static void reverse(Object[] array, int size) { + for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) { + Object tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; + } } - private void resolveDanglingNodes(boolean up) { + private void resolveDanglingNodes(boolean up, List dangling) { boolean dir = up; boolean force = false; - while (!dangling.isEmpty()) { + LayoutNode[] nodes = dangling.toArray(new LayoutNode[0]); + Arrays.parallelSort(nodes, up ? DANGLING_UP_NODE_COMPARATOR : DANGLING_DOWN_NODE_COMPARATOR); + int length = nodes.length; + /* + * The nodes array can be quite large so it's best to use an array to support efficient sorting but + * removing elements from the array requires shifting elements down repeatedly. Instead elements are + * shifted down into the empty slot as nodes visited. + */ + while (length > 0) { int newResolved = 0; - List nodes = new ArrayList<>(dangling.keySet()); - if (up) { - nodes.sort(DANGLING_UP_NODE_COMPARATOR); - for (LayoutNode n : nodes) { - NodeRow r = dangling.get(n); - if (r != null && (!(n.preds.isEmpty() || n.preds.stream().allMatch(e -> dangling.containsKey(e.from))) || (force && n.preds.isEmpty()))) { - int optimal = calculateOptimalDown(n, null); - r.insert(n, optimal); - dangling.remove(n); - newResolved++; + int emptySlot = -1; + for (int i = 0; i < length; i++) { + var n = nodes[i]; + NodeRow r = n.getDanglingRow(); + int optimal = -1; + boolean hasOptimal = false; + if (up) { + if (!n.preds.isEmpty() && !isAllDanglingPreds(n) || force && n.preds.isEmpty()) { + optimal = calculateOptimalDown(n, null, false); + hasOptimal = true; + } + } else { + if (!(n.succs.isEmpty() || isAllDanglingSuccs(n)) || force && n.succs.isEmpty()) { + optimal = calculateOptimalUp(n, null, false); + hasOptimal = true; } } - } else { - nodes.sort(DANGLING_DOWN_NODE_COMPARATOR); - for (LayoutNode n : nodes) { - NodeRow r = dangling.get(n); - if (r != null && (!(n.succs.isEmpty() || n.succs.stream().allMatch(e -> dangling.containsKey(e.to))) || (force && n.succs.isEmpty()))) { - int optimal = calculateOptimalUp(n, null); - r.insert(n, optimal); - dangling.remove(n); - newResolved++; + if (hasOptimal) { + r.insert(n, optimal); + nodes[i] = null; + if (emptySlot == -1) { + emptySlot = i; } + n.removeDangling(); + newResolved++; + } else if (emptySlot != -1) { + nodes[emptySlot++] = nodes[i]; + nodes[i] = null; } } - if (newResolved == 0 && !dangling.isEmpty()) { + length -= newResolved; + if (emptySlot != -1 && length != emptySlot) { + throw new InternalError("Incorrect packing"); + } + if (newResolved == 0 && length != 0) { + reverse(nodes, length); up = !up; force = up == dir; } } - assert dangling.isEmpty() : "dangling size: " + dangling.size(); } } @@ -1422,7 +1529,7 @@ private class NodeRow { private final int[] space; static final Comparator COMPARATOR = Comparator.comparingInt(LayoutNode::getPos); - public NodeRow(int[] space) { + public NodeRow(int[] space, int length) { this.positions = new ArrayList<>(); this.space = space; } @@ -2780,24 +2887,24 @@ public int compare(T o1, T o2) { private static final Comparator NODE_POSITION_COMPARATOR = (n1, n2) -> n1.pos - n2.pos; private static final PartialComparator NODE_BOTHVIP = (n1, n2) -> { - long n1VIP = n1.preds.stream().filter(x -> x.vip).count() + n1.succs.stream().filter(x -> x.vip).count(); - long n2VIP = n2.preds.stream().filter(x -> x.vip).count() + n2.succs.stream().filter(x -> x.vip).count(); + long n1VIP = n1.getPredsVips() + n1.getSuccsVips(); + long n2VIP = n2.getPredsVips() + n2.getSuccsVips(); if (n1VIP != n2VIP) { return (int) (n2VIP - n1VIP); } return null; }; private static final PartialComparator NODE_DOWNVIP = (n1, n2) -> { - long n1VIP = n1.preds.stream().filter(x -> x.vip).count(); - long n2VIP = n2.preds.stream().filter(x -> x.vip).count(); + long n1VIP = n1.getPredsVips(); + long n2VIP = n2.getPredsVips(); if (n1VIP != n2VIP) { return (int) (n2VIP - n1VIP); } return null; }; private static final PartialComparator NODE_UPVIP = (n1, n2) -> { - long n1VIP = n1.succs.stream().filter(x -> x.vip).count(); - long n2VIP = n2.succs.stream().filter(x -> x.vip).count(); + long n1VIP = n1.getSuccsVips(); + long n2VIP = n2.getSuccsVips(); if (n1VIP != n2VIP) { return (int) (n2VIP - n1VIP); } From 2eab8b4ea125e12548e0da018f6c0b50f1a60b52 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:41 -0700 Subject: [PATCH 09/29] Iterate connections instead of duplicating thems --- .../org/graalvm/visualizer/graph/Diagram.java | 54 +++++++++++++++++++ .../view/impl/DiagramCacheTask.java | 2 +- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java index b79da311c5ef..203c46e4da3c 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Diagram.java @@ -37,15 +37,18 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Consumer; import java.util.stream.Stream; import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; @@ -399,6 +402,57 @@ public InputGraph getGraph() { return graph; } + + public Iterable iterateConnections() { + return new Iterable<>() { + @Override + public Iterator iterator() { + return new Iterator<>() { + + final Iterator
figureMapIterator = figureMap.values().iterator(); + Iterator inputSlotIterator = Collections.emptyIterator(); + Iterator connectionIterator = Collections.emptyIterator(); + + @Override + public boolean hasNext() { + while (true) { + if (connectionIterator.hasNext()) { + return true; + } + if (inputSlotIterator.hasNext()) { + connectionIterator = inputSlotIterator.next().getConnections().iterator(); + continue; + } + if (figureMapIterator.hasNext()) { + inputSlotIterator = figureMapIterator.next().getInputSlots().iterator(); + continue; + } + return false; + } + } + + @Override + public Connection next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return connectionIterator.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void forEachRemaining(Consumer action) { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + public Set getConnections() { Set connections = new HashSet<>(); diff --git a/visualizer/IdealGraphVisualizer/View/src/main/java/org/graalvm/visualizer/view/impl/DiagramCacheTask.java b/visualizer/IdealGraphVisualizer/View/src/main/java/org/graalvm/visualizer/view/impl/DiagramCacheTask.java index 22678efe6bc5..0583bf60a311 100644 --- a/visualizer/IdealGraphVisualizer/View/src/main/java/org/graalvm/visualizer/view/impl/DiagramCacheTask.java +++ b/visualizer/IdealGraphVisualizer/View/src/main/java/org/graalvm/visualizer/view/impl/DiagramCacheTask.java @@ -314,7 +314,7 @@ protected void execute() { figures.add(f); } } - for (Connection c : outputDiagram.getConnections()) { + for (Connection c : outputDiagram.iterateConnections()) { Figure f1 = c.getOutputSlot().getFigure(); Figure f2 = c.getInputSlot().getFigure(); if (f1.isVisible() && f2.isVisible()) { From 5bc2a52939a571c3a451ae92ed532bdc66df7d38 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:41 -0700 Subject: [PATCH 10/29] reverse the array instead of sorting again in reverse order --- .../HierarchicalLayoutManager.java | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index a8e89b74103b..4af9747ed86a 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -1143,17 +1143,44 @@ private void createArrays() { } if (isDefaultLayout || !setting.get(Boolean.class, BOTH_SORT)) { - downProcessingOrder[i] = layer.toArray(new LayoutNode[layer.size()]); - upProcessingOrder[i] = layer.toArray(new LayoutNode[layer.size()]); + downProcessingOrder[i] = layer.toArray(new LayoutNode[0]); Arrays.sort(downProcessingOrder[i], downComparer); - Arrays.sort(upProcessingOrder[i], upComparer); + upProcessingOrder[i] = reverseSort(downProcessingOrder[i], upComparer); } else { - bothProcessingOrder[i] = layer.toArray(new LayoutNode[layer.size()]); + bothProcessingOrder[i] = layer.toArray(new LayoutNode[0]); Arrays.sort(bothProcessingOrder[i], bothComparer); } } } + /** + * Instead of sorting again in reverse order, just reverse the array. Assert that this produces the same order as sorting . + */ + private static LayoutNode[] reverseSort(LayoutNode[] source, Comparator upComparer) { + LayoutNode[] array = source.clone(); + int left = 0, right = array.length - 1; + while (left < right) { + LayoutNode temp = array[left]; + array[left] = array[right]; + array[right] = temp; + left++; + right--; + } + assert verifySort(array, upComparer); + return array; + } + + /** + * Ensure that the reversed array is sorted in the same order. + */ + private static boolean verifySort(LayoutNode[] array, Comparator upComparer) { + LayoutNode[] copy = array.clone(); + Arrays.sort(copy, upComparer); + assert Arrays.equals(array, copy); + return true; + } + + @Override protected void run() { createArrays(); From 50b2bb7acbbe05ae9f66d2d06346754d62b54933 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:42 -0700 Subject: [PATCH 11/29] Cache isRoot computation --- .../java/org/graalvm/visualizer/graph/Figure.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java index f9a56af43632..c5d236371e92 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java @@ -509,11 +509,16 @@ public Cluster getCluster() { } } + Boolean isRoot; + @Override public boolean isRoot() { - List sourceNodes = source.getSourceNodes(); - //Get property value just once - return sourceNodes.size() > 0 && NAME_ROOT.equals(sourceNodes.get(0).getProperties().get(PROPNAME_NAME, String.class)); + if (isRoot == null) { + List sourceNodes = source.getSourceNodes(); + // Get property value just once + isRoot = !sourceNodes.isEmpty() && NAME_ROOT.equals(sourceNodes.get(0).getProperties().get(PROPNAME_NAME, String.class)); + } + return isRoot; } @Override @@ -528,6 +533,7 @@ public Rectangle getBounds() { void sourcesChanged(Source s) { diagram.invalidateSlotMap(); + isRoot = null; } @Override From f002da436caa3f46278207e751c3286eb4198ee1 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:42 -0700 Subject: [PATCH 12/29] Avoid wrapping inputs and outputs when computing widths --- .../org/graalvm/visualizer/graph/Figure.java | 26 +++++++++++++++++++ .../graalvm/visualizer/graph/InputSlot.java | 4 +-- .../graalvm/visualizer/graph/OutputSlot.java | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java index c5d236371e92..55a273825f1a 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/Figure.java @@ -152,6 +152,17 @@ public static int getSlotsWidth(Collection slots) { return result; } + public int getSlotsWidthBefore(InputSlot inputSlot) { + int result = Figure.SLOT_OFFSET; + for (Slot s : inputSlots) { + if (s == inputSlot) { + return result; + } + result += s.getWidth() + Figure.SLOT_OFFSET; + } + return result; + } + public static int getSlotsWidth(Slot s) { if (s == null) { return Figure.SLOT_OFFSET; @@ -405,6 +416,10 @@ public List getInputSlots() { return Collections.unmodifiableList(inputSlots); } + int getInputSlotsWidth() { + return Figure.getSlotsWidth(inputSlots); + } + public Set getSlots() { Set result = new HashSet<>(); result.addAll(getInputSlots()); @@ -422,6 +437,17 @@ public List getOutputSlots() { } } + + public int getOutputSlotsWidth() { + if (outputSlots != null) { + return Figure.getSlotsWidth(outputSlots); + } else if (singleOutput != null) { + return Figure.getSlotsWidth(Collections.singletonList(singleOutput)); + } else { + return 0; + } + } + void removeInputSlot(InputSlot s, HashSet cleaned) { s.removeAllConnections(cleaned); inputSlots.remove(s); diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/InputSlot.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/InputSlot.java index 5fd91347f267..77c404d41089 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/InputSlot.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/InputSlot.java @@ -43,13 +43,13 @@ protected Slot copyInto(Figure f) { @Override public Point getRelativePosition() { - int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getInputSlots()); + int gap = getFigure().getWidth() - getFigure().getInputSlotsWidth(); if (gap < 0) { gap = 0; } 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(gapAmount + getFigure().getSlotsWidthBefore(this) + getWidth() / 2, -Figure.SLOT_START); } @Override diff --git a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/OutputSlot.java b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/OutputSlot.java index 89b162b7b77a..65adb755490c 100644 --- a/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/OutputSlot.java +++ b/visualizer/IdealGraphVisualizer/Graph/src/main/java/org/graalvm/visualizer/graph/OutputSlot.java @@ -42,7 +42,7 @@ protected Slot copyInto(Figure f) { @Override public Point getRelativePosition() { - int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getOutputSlots()); + int gap = getFigure().getWidth() - getFigure().getOutputSlotsWidth(); if (gap < 0) { gap = 0; } From b02ade1a361476c48955cf22574eb7a08187e280 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:42 -0700 Subject: [PATCH 13/29] Cache preference settings --- .../HierarchicalLayoutManager.java | 210 ++++++++++++------ 1 file changed, 138 insertions(+), 72 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index 4af9747ed86a..f3e5df147b57 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -110,6 +110,7 @@ public class HierarchicalLayoutManager implements LayoutManager { public static final int VIP_BONUS = 10; private final AtomicBoolean cancelled; + private final LayoutSettingBean settings; private boolean trace = TRACE_DEFAULT; @@ -132,17 +133,51 @@ public enum Combine { SAME_OUTPUTS } - private final LayoutSettingBean setting; + // Cached settings fields + private boolean bothSort; + private boolean centerCrossingX; + private boolean centerSimpleNodes; + private boolean crossingSort; + private boolean crossPositionDuring; + private boolean crossReduceRouting; + private boolean crossResetXFromMiddle; + private boolean crossResetXFromNode; + private boolean decreaseLayerWidthDeviation; + private boolean decreaseLayerWidthDeviationQuick; + private boolean decreaseLayerWidthDeviationUp; + private boolean dummyFirstSort; + private boolean edgeBending; + private boolean irrelevantLayoutCode; + private boolean lastDownSweep; + private boolean lastUpCrossingSweep; + private boolean meanNotMedian; + private boolean noCrossingLayerReassign; + private boolean noDummyLongEdges; + private boolean noVip; + private boolean optimalUpVip; + private boolean properCrossingClosestNode; + private boolean reverseSort; + private boolean spanByAngle; + private boolean squashPosition; + private boolean standalones; + private boolean unreverseVips; + private boolean unknownCrossingNumber; + + private int xAssignSweepCount; + private int crossingSweepCount; + private int minEdgeAngle; + private float crossFactor; + // Options private final Combine combine; private final int dummyWidth; private final int offset; private int maxLayerLength; // Algorithm global datastructures - private final Set reversedLinks; - private final Set longEdges; - private final List nodes; - private final List standAlones; + private final HashSet reversedLinks; + private final HashSet longEdges; + private final ArrayList nodes; + private final ArrayList standAlones; private final HashMap vertexToLayoutNode; private final HashMap> reversedLinkStartPoints; private final HashMap> reversedLinkEndPoints; @@ -454,20 +489,8 @@ protected void preCheck() { } } - public HierarchicalLayoutManager() { - this(Combine.NONE, LayoutSettings.getBean()); - } - - public HierarchicalLayoutManager(Combine b) { - this(b, LayoutSettings.getBean()); - } - - public HierarchicalLayoutManager(LayoutSettingBean layoutSetting) { - this(Combine.NONE, layoutSetting); - } + public HierarchicalLayoutManager(Combine b, LayoutSettingBean setting) { - public HierarchicalLayoutManager(Combine b, LayoutSettingBean layoutSetting) { - setting = layoutSetting; isDefaultLayout = setting.get(Boolean.class, DEFAULT_LAYOUT); isDummyCrossing = setting.get(Boolean.class, DUMMY_CROSSING); isCrossingByConnDiff = setting.get(Boolean.class, CROSS_BY_CONN_DIFF); @@ -482,7 +505,10 @@ public HierarchicalLayoutManager(Combine b, LayoutSettingBean layoutSetting) { } else { this.dummyWidth = setting.get(Integer.class, LayoutSettings.DUMMY_WIDTH); } - this.maxLayerLength = MAX_LAYER_LENGTH; + + this.settings = setting; + + maxLayerLength = MAX_LAYER_LENGTH; offset = X_OFFSET + dummyWidth; vertexToLayoutNode = new HashMap<>(); @@ -495,6 +521,45 @@ public HierarchicalLayoutManager(Combine b, LayoutSettingBean layoutSetting) { cancelled = new AtomicBoolean(false); } + private void initSettings(LayoutSettingBean setting) { + // Boolean settings (cached once per instance) + bothSort = setting.get(Boolean.class, BOTH_SORT); + reverseSort = setting.get(Boolean.class, REVERSE_SORT); + dummyFirstSort = setting.get(Boolean.class, DUMMY_FIRST_SORT); + lastDownSweep = setting.get(Boolean.class, LAST_DOWN_SWEEP); + optimalUpVip = setting.get(Boolean.class, OPTIMAL_UP_VIP); + squashPosition = setting.get(Boolean.class, SQUASH_POSITION); + centerSimpleNodes = setting.get(Boolean.class, CENTER_SIMPLE_NODES); + meanNotMedian = setting.get(Boolean.class, MEAN_NOT_MEDIAN); + crossingSort = setting.get(Boolean.class, CROSSING_SORT); + noCrossingLayerReassign = setting.get(Boolean.class, NO_CROSSING_LAYER_REASSIGN); + lastUpCrossingSweep = setting.get(Boolean.class, LAST_UP_CROSSING_SWEEP); + irrelevantLayoutCode = setting.get(Boolean.class, IRRELEVANT_LAYOUT_CODE); + centerCrossingX = setting.get(Boolean.class, CENTER_CROSSING_X); + crossResetXFromNode = setting.get(Boolean.class, CROSS_RESET_X_FROM_NODE); + crossResetXFromMiddle = setting.get(Boolean.class, CROSS_RESET_X_FROM_MIDDLE); + spanByAngle = setting.get(Boolean.class, SPAN_BY_ANGLE); + noDummyLongEdges = setting.get(Boolean.class, NO_DUMMY_LONG_EDGES); + standalones = setting.get(Boolean.class, STANDALONES); + edgeBending = setting.get(Boolean.class, EDGE_BENDING); + decreaseLayerWidthDeviation = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION); + decreaseLayerWidthDeviationQuick = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_QUICK); + decreaseLayerWidthDeviationUp = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_UP); + unreverseVips = setting.get(Boolean.class, UNREVERSE_VIPS); + noVip = setting.get(Boolean.class, NO_VIP); + crossReduceRouting = setting.get(Boolean.class, CROSS_REDUCE_ROUTING); + crossPositionDuring = setting.get(Boolean.class, CROSS_POSITION_DURING); + properCrossingClosestNode = setting.get(Boolean.class, PROPER_CROSSING_CLOSEST_NODE); + unknownCrossingNumber = setting.get(Boolean.class, UNKNOWN_CROSSING_NUMBER); + + // int and float settings + + xAssignSweepCount = setting.get(Integer.class, X_ASSIGN_SWEEP_COUNT); + crossingSweepCount = setting.get(Integer.class, CROSSING_SWEEP_COUNT); + minEdgeAngle = setting.get(Integer.class, MIN_EDGE_ANGLE); + crossFactor = setting.get(Float.class, CROSS_FACTOR); + } + public int getMaxLayerLength() { return maxLayerLength; } @@ -510,6 +575,8 @@ private void cleanup() { reversedLinkEndPoints.clear(); nodes.clear(); longEdges.clear(); + + initSettings(settings); } @Override @@ -593,7 +660,7 @@ protected void run() { HashMap> linkPositions = new HashMap<>(); for (Vertex v : graph.getVertices()) { LayoutNode n = vertexToLayoutNode.get(v); - if (!(setting.get(Boolean.class, STANDALONES) && standAlones.contains(n))) { + if (!(standalones && standAlones.contains(n))) { assert !vertexPositions.containsKey(v); vertexPositions.put(v, new Point(n.getLeftSide(), n.y)); } @@ -773,7 +840,7 @@ protected void run() { } } Dimension dim; - if (setting.get(Boolean.class, STANDALONES)) { + if (standalones) { dim = setStandAlones(new Rectangle(minX, minY, maxX - minX, maxY - minY), vertexPositions); minY -= dim.height - maxY + minY; } else { @@ -792,7 +859,7 @@ protected void run() { linkPositions.put(e.link, makeLongEnding(e)); } - if (!setting.get(Boolean.class, EDGE_BENDING)) { + if (!edgeBending) { for (List points : linkPositions.values()) { points.remove(points.size() - 2); points.remove(1); @@ -1098,7 +1165,7 @@ private void initialPositions() { private void createArrays() { space = new int[layers.length][]; - if (isDefaultLayout || !setting.get(Boolean.class, BOTH_SORT)) { + if (isDefaultLayout || !bothSort) { downProcessingOrder = new LayoutNode[layers.length][]; upProcessingOrder = new LayoutNode[layers.length][]; } else { @@ -1110,8 +1177,8 @@ private void createArrays() { bothComparer = NODE_PROCESSING_DUMMY_BOTH_COMPARATOR; if (isDefaultLayout) { //leave default sort - } else if (setting.get(Boolean.class, REVERSE_SORT)) { - if (setting.get(Boolean.class, DUMMY_FIRST_SORT)) { + } else if (reverseSort) { + if (dummyFirstSort) { upComparer = NODE_PROCESSING_DUMMY_UP_REVERSE_COMPARATOR; downComparer = NODE_PROCESSING_DUMMY_DOWN_REVERSE_COMPARATOR; bothComparer = NODE_PROCESSING_DUMMY_BOTH_REVERSE_COMPARATOR; @@ -1120,7 +1187,7 @@ private void createArrays() { downComparer = NODE_PROCESSING_DOWN_REVERSE_COMPARATOR; bothComparer = NODE_PROCESSING_BOTH_REVERSE_COMPARATOR; } - } else if (!setting.get(Boolean.class, DUMMY_FIRST_SORT)) { + } else if (!dummyFirstSort) { upComparer = NODE_PROCESSING_UP_COMPARATOR; downComparer = NODE_PROCESSING_DOWN_COMPARATOR; bothComparer = NODE_PROCESSING_BOTH_COMPARATOR; @@ -1142,7 +1209,7 @@ private void createArrays() { } } - if (isDefaultLayout || !setting.get(Boolean.class, BOTH_SORT)) { + if (isDefaultLayout || !bothSort) { downProcessingOrder[i] = layer.toArray(new LayoutNode[0]); Arrays.sort(downProcessingOrder[i], downComparer); upProcessingOrder[i] = reverseSort(downProcessingOrder[i], upComparer); @@ -1186,12 +1253,12 @@ protected void run() { createArrays(); initialPositions(); - for (int i = 0; i < (isDefaultLayout ? SWEEP_ITERATIONS : setting.get(Integer.class, X_ASSIGN_SWEEP_COUNT)); i++) { + for (int i = 0; i < (isDefaultLayout ? SWEEP_ITERATIONS : xAssignSweepCount); i++) { sweepDown(); sweepUp(); } sweepDown(); - if (isDefaultLayout || !setting.get(Boolean.class, LAST_DOWN_SWEEP)) { + if (isDefaultLayout || !lastDownSweep) { sweepUp(); } } @@ -1291,7 +1358,7 @@ private int calculateOptimalUp(LayoutNode n, LayoutNode last, boolean hasNoDangl ArrayList values = new ArrayList<>(n.succs.size()); int layer = getVisibleLayer(n.layer, false); - if (isDefaultLayout || !setting.get(Boolean.class, OPTIMAL_UP_VIP)) { + if (isDefaultLayout || !optimalUpVip) { for (LayoutEdge e : n.succs) { if (e.vip) { getOptimalPositions(e, layer, new ArrayList<>(), e.relativeFrom, false, hasNoDangling); @@ -1317,13 +1384,13 @@ private int calculateOptimalUp(LayoutNode n, LayoutNode last, boolean hasNoDangl private int median(ArrayList values, LayoutNode n, LayoutNode last, boolean up, boolean hasNoDangling) { if (values.isEmpty()) { - if (isDefaultLayout || !setting.get(Boolean.class, SQUASH_POSITION)) { + if (isDefaultLayout || !squashPosition) { return n.x; } else { return calcClosestPosition(n, last, up, hasNoDangling); } } - if (setting.get(Boolean.class, CENTER_SIMPLE_NODES) && !n.isDummy() && values.size() == 1 && (up ? n.preds.size() == 1 : n.succs.size() == 1) && !(n.vertex instanceof ClusterSlotNode)) { + if (centerSimpleNodes && !n.isDummy() && values.size() == 1 && (up ? n.preds.size() == 1 : n.succs.size() == 1) && !(n.vertex instanceof ClusterSlotNode)) { LayoutNode node; if (up) { node = n.preds.get(0).from; @@ -1334,7 +1401,7 @@ private int median(ArrayList values, LayoutNode n, LayoutNode last, boo return node.x + ((node.getWholeWidth() - n.getWholeWidth()) / 2); } } - if (!isDefaultLayout && setting.get(Boolean.class, MEAN_NOT_MEDIAN)) { + if (!isDefaultLayout && meanNotMedian) { return values.stream().reduce(0, Integer::sum) / values.size(); } values.sort(Integer::compare); @@ -1347,7 +1414,7 @@ private int median(ArrayList values, LayoutNode n, LayoutNode last, boo private void sweepUp() { LayoutNode[][] chosenOrder; - if (isDefaultLayout || !setting.get(Boolean.class, BOTH_SORT)) { + if (isDefaultLayout || !bothSort) { chosenOrder = upProcessingOrder; } else { chosenOrder = bothProcessingOrder; @@ -1392,7 +1459,7 @@ private boolean isAllDanglingSuccs(LayoutNode n) { private void sweepDown() { LayoutNode[][] chosenOrder; - if (isDefaultLayout || !setting.get(Boolean.class, BOTH_SORT)) { + if (isDefaultLayout || !bothSort) { chosenOrder = downProcessingOrder; } else { chosenOrder = bothProcessingOrder; @@ -1625,7 +1692,7 @@ public void preCheck() { @SuppressWarnings({"unchecked", "rawtypes"}) private void createLayers() { - if (!isDefaultLayout && setting.get(Boolean.class, CROSSING_SORT) && !isCrossingByConnDiff) { + if (!isDefaultLayout && crossingSort && !isCrossingByConnDiff) { upCrossing = new ArrayList[layerCount]; downCrossing = new ArrayList[layerCount]; } @@ -1634,7 +1701,7 @@ private void createLayers() { for (int i = 0; i < layerCount; i++) { layers[i] = new LayoutLayer(); } - if (!isDefaultLayout && setting.get(Boolean.class, NO_CROSSING_LAYER_REASSIGN)) { + if (!isDefaultLayout && noCrossingLayerReassign) { for (LayoutNode n : nodes) { layers[n.layer].add(n); } @@ -1665,7 +1732,7 @@ private void createLayers() { } } toMove = !routingCrossing ? layers : Arrays.stream(layers).map(l -> l.stream().filter(n -> n.isDummy()).collect(LayoutLayer::new, LayoutLayer::add, LayoutLayer::addAll)).toArray(LayoutLayer[]::new); - if (!isDefaultLayout && setting.get(Boolean.class, CROSSING_SORT) && !isCrossingByConnDiff) { + if (!isDefaultLayout && crossingSort && !isCrossingByConnDiff) { for (int i = 0; i < layerCount; ++i) { upCrossing[i] = new ArrayList<>(layers[i]); downCrossing[i] = new ArrayList<>(layers[i]); @@ -1678,28 +1745,28 @@ private void createLayers() { @Override protected void run() { createLayers(); - if (setting.get(Boolean.class, IRRELEVANT_LAYOUT_CODE)) { + if (irrelevantLayoutCode) { updatePositions(); } //will be reassigned initX(); // Optimize - int sweepCount = isDefaultLayout ? CROSSING_ITERATIONS : setting.get(Integer.class, CROSSING_SWEEP_COUNT); + int sweepCount = isDefaultLayout ? CROSSING_ITERATIONS : crossingSweepCount; for (int i = 0; i < sweepCount; i++) { downSweep(); upSweep(); } - if (isDefaultLayout || !setting.get(Boolean.class, LAST_UP_CROSSING_SWEEP)) { + if (isDefaultLayout || !lastUpCrossingSweep) { downSweep(); } - if (setting.get(Boolean.class, IRRELEVANT_LAYOUT_CODE)) { + if (irrelevantLayoutCode) { initX(); } updatePositions(); } private void initX() { - if (!isDefaultLayout && setting.get(Boolean.class, CENTER_CROSSING_X)) { + if (!isDefaultLayout && centerCrossingX) { createCenterDiffs(); } for (int i = 0; i < layers.length; i++) { @@ -1727,14 +1794,14 @@ private void createCenterDiffs() { } private void updateXOfLayer(int index) { - if (!isDefaultLayout && setting.get(Boolean.class, CROSS_RESET_X_FROM_NODE)) { - if (setting.get(Boolean.class, CROSS_RESET_X_FROM_MIDDLE)) { + if (!isDefaultLayout && crossResetXFromNode) { + if (crossResetXFromMiddle) { updateFromMiddle(index); } else { updateFromLeft(index); } } else { - int x = (isDefaultLayout || !setting.get(Boolean.class, CENTER_CROSSING_X)) ? 0 : centerDiffs[index]; + int x = (isDefaultLayout || !centerCrossingX) ? 0 : centerDiffs[index]; for (LayoutNode n : layers[index]) { n.x = x; x += n.getWholeWidth() + offset; @@ -1746,7 +1813,7 @@ private void updateFromMiddle(int index) { LayoutLayer layer = layers[index]; int middleIndex = layer.size() / 2; LayoutNode n = layer.get(middleIndex); - int add = (isDefaultLayout || !setting.get(Boolean.class, CENTER_CROSSING_X)) ? 0 : (centerDiffs[index] / (layer.size() + 1)); + int add = (isDefaultLayout || !centerCrossingX) ? 0 : (centerDiffs[index] / (layer.size() + 1)); int x = n.x; for (int i = middleIndex - 1; i >= 0; --i) { n = layer.get(i); @@ -1764,7 +1831,7 @@ private void updateFromMiddle(int index) { private void updateFromLeft(int index) { LayoutLayer layer = layers[index]; LayoutNode n = layer.get(0); - int add = (isDefaultLayout || !setting.get(Boolean.class, CENTER_CROSSING_X)) ? 0 : (centerDiffs[index] / (layer.size() + 1)); + int add = (isDefaultLayout || !centerCrossingX) ? 0 : (centerDiffs[index] / (layer.size() + 1)); int x = n.getRightSide() + offset; for (int i = 0; i < layer.size(); ++i) { n = layer.get(i); @@ -1788,14 +1855,14 @@ private void updateLayerPositions(int index) { } private void changeXOfLayer(int index) { - float factor = !isDefaultLayout && setting.get(Boolean.class, CROSS_RESET_X_FROM_MIDDLE) ? setting.get(Float.class, CROSS_FACTOR) : 1; + float factor = !isDefaultLayout && crossResetXFromMiddle ? crossFactor : 1; for (LayoutNode n : toMove[index]) { n.x += n.crossingNumber * factor; } } private void downSweep() { - if (!isDefaultLayout && setting.get(Boolean.class, CROSS_POSITION_DURING)) { + if (!isDefaultLayout && crossPositionDuring) { updatePositions(); new AssignXCoordinates().start(); } @@ -1813,14 +1880,14 @@ private void downSweep() { layers[i].sort(CROSSING_NODE_COMPARATOR); updateXOfLayer(i); } - if (setting.get(Boolean.class, IRRELEVANT_LAYOUT_CODE)) { + if (irrelevantLayoutCode) { updateLayerPositions(i); } } } private void upSweep() { - if (!isDefaultLayout && setting.get(Boolean.class, CROSS_POSITION_DURING)) { + if (!isDefaultLayout && crossPositionDuring) { updatePositions(); new AssignXCoordinates().start(); } @@ -1839,7 +1906,7 @@ private void upSweep() { layers[i].sort(CROSSING_NODE_COMPARATOR); updateXOfLayer(i); } - if (setting.get(Boolean.class, IRRELEVANT_LAYOUT_CODE)) { + if (irrelevantLayoutCode) { updateLayerPositions(i); } } @@ -1847,13 +1914,13 @@ private void upSweep() { private void updateCrossingNumbers(int index, boolean down) { List layer; - if (!isDefaultLayout && setting.get(Boolean.class, CROSSING_SORT)) { + if (!isDefaultLayout && crossingSort) { layer = down ? downCrossing[index] : upCrossing[index]; } else { layer = layers[index]; } - boolean properCrossing = !isDefaultLayout && setting.get(Boolean.class, PROPER_CROSSING_CLOSEST_NODE); - int diff = (!isDefaultLayout && setting.get(Boolean.class, UNKNOWN_CROSSING_NUMBER)) ? 1 : 0; + boolean properCrossing = !isDefaultLayout && properCrossingClosestNode; + int diff = (!isDefaultLayout && unknownCrossingNumber) ? 1 : 0; LayoutNode prev; LayoutNode next; for (int i = 0; i < layer.size(); i++) { @@ -1930,10 +1997,10 @@ private class AssignYCoordinates extends AlgorithmPart { @Override protected void run() { final IntUnaryOperator layerDiff; - if (isDefaultLayout || !setting.get(Boolean.class, SPAN_BY_ANGLE)) { + if (isDefaultLayout || !spanByAngle) { layerDiff = (in) -> (int) (Math.sqrt(in) * 2); } else { - final double coef = Math.tan(Math.toRadians(setting.get(Integer.class, MIN_EDGE_ANGLE))); + final double coef = Math.tan(Math.toRadians(minEdgeAngle)); layerDiff = (in) -> (int) (in * coef); } int curY = 0; @@ -1990,7 +2057,6 @@ protected void run() { oldNodeCount = nodes.size(); if (combine == Combine.SAME_OUTPUTS) { - final boolean noDummyLongEdges = setting.get(Boolean.class, NO_DUMMY_LONG_EDGES); HashMap> portHash = new HashMap<>(); ArrayList currentNodes = new ArrayList<>(nodes); for (LayoutNode n : currentNodes) { @@ -2002,7 +2068,7 @@ protected void run() { for (LayoutEdge e : succs) { assert e.from.layer < e.to.layer; if (e.from.layer != e.to.layer - 1) { - if (maxLayerLength != -1 && e.to.layer - e.from.layer > maxLayerLength && !setting.get(Boolean.class, DRAW_LONG_EDGES) /* && e.to.preds.size() > 1 && e.from.succs.size() > 1 */) { + if (maxLayerLength != -1 && e.to.layer - e.from.layer > maxLayerLength && !isDrawLongEdges /* && e.to.preds.size() > 1 && e.from.succs.size() > 1 */) { assert maxLayerLength > 2; e.to.preds.remove(e); e.from.succs.remove(e); @@ -2090,7 +2156,7 @@ protected void run() { curEdge.relativeFrom = anchor.width / 2; n.succs.remove(curEdge); } - if (!isDefaultLayout && setting.get(Boolean.class, NO_CROSSING_LAYER_REASSIGN)) { + if (!isDefaultLayout && noCrossingLayerReassign) { HierarchicalLayoutManager.this.nodes.addAll(Arrays.asList(nodes)); } } @@ -2161,7 +2227,7 @@ protected void run() { assignLayerDownwards(); assignLayerUpwards(); reassignInOutBlockNodes(); - if (!isDefaultLayout && setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION)) { + if (!isDefaultLayout && decreaseLayerWidthDeviation) { reassignLayers(); } } @@ -2306,7 +2372,7 @@ private void reassignLayers() { double avg = lay.stream().mapToInt(l -> l.getMinimalWidth()).sum() / layerCount; boolean up, down; LayoutNode node = null; - final boolean isQuick = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_QUICK); + final boolean isQuick = decreaseLayerWidthDeviationQuick; while (!lay.isEmpty()) { if (cancelled.get()) { return; @@ -2318,7 +2384,7 @@ private void reassignLayers() { break; } layer.sort(NODE_WIDTH_COMPARATOR); - if (!setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_UP)) { + if (!decreaseLayerWidthDeviationUp) { for (LayoutNode n : layer) { if ((down = canMoveDown(n)) || (up = canMoveUp(n))) { break; @@ -2578,7 +2644,7 @@ protected void run() { } } } - if (setting.get(Boolean.class, STANDALONES)) { + if (standalones) { for (Iterator it = nodes.iterator(); it.hasNext(); ) { LayoutNode n = it.next(); if (n.succs.isEmpty() && n.preds.isEmpty()) { @@ -2616,7 +2682,7 @@ private void DFS(LayoutNode startNode, boolean vip) { return; } - final boolean sortSuccs = vip && !isDefaultLayout && setting.get(Boolean.class, UNREVERSE_VIPS); + final boolean sortSuccs = vip && !isDefaultLayout && unreverseVips; Stack stack = new Stack<>(); stack.push(startNode); @@ -2653,8 +2719,8 @@ private void DFS(LayoutNode startNode, boolean vip) { } private void DFS() { - if (isDefaultLayout || !setting.get(Boolean.class, UNREVERSE_VIPS)) { - nodes.forEach(n -> DFS(n, false)); + nodes.forEach(n -> DFS(n, false)); + if (isDefaultLayout || !unreverseVips) { } else { //first search from vip starting nodes nodes.stream().filter((n) -> n.preds.stream().allMatch((e) -> !e.vip) && n.succs.stream().anyMatch((e) -> e.vip)) @@ -2840,7 +2906,7 @@ protected void run() { // Set up edges List links = new ArrayList<>(graph.getLinks()); - final boolean VIP = !setting.get(Boolean.class, NO_VIP); + final boolean VIP = !noVip; if (VIP) { Collections.sort(links, LINK_COMPARATOR); } else { @@ -3066,7 +3132,7 @@ public void doRouting(LayoutGraph graph) { return; } - if (setting.get(Boolean.class, CROSS_REDUCE_ROUTING)) { + if (crossReduceRouting) { new CrossingReduction(true).start(); } if (cancelled.get()) { @@ -3184,11 +3250,11 @@ private void resolveDummyNodes(LayoutNode n, List succs) { int invisibleLayers = getInvisible(n.layer, e.to.layer); assert e.from.layer <= e.to.layer : e.from + "=" + e.from.layer + "; " + e.to + "=" + e.to.layer; if (e.from.layer != e.to.layer - 1 - invisibleLayers) { - if ((maxLayerLength != -1 && e.to.layer - invisibleLayers - e.from.layer > maxLayerLength && !setting.get(Boolean.class, DRAW_LONG_EDGES)) || e.from.layer == e.to.layer) { + if ((maxLayerLength != -1 && e.to.layer - invisibleLayers - e.from.layer > maxLayerLength && !isDrawLongEdges) || e.from.layer == e.to.layer) { assert maxLayerLength > 2; e.to.preds.remove(e); e.from.succs.remove(e); - if ((isDefaultLayout || !setting.get(Boolean.class, NO_DUMMY_LONG_EDGES)) && e.from.layer != e.to.layer) { + if ((isDefaultLayout || !noDummyLongEdges) && e.from.layer != e.to.layer) { LayoutEdge topEdge; LayoutNode topNode = topNodeHash.get(e.relativeFrom); From 44e86643fc57d564bc4dfda3f02efd7e71e978db Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:43 -0700 Subject: [PATCH 14/29] Collection cleanups, stream removal and other minor cleanups --- .../HierarchicalLayoutManager.java | 113 ++++++++++-------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index f3e5df147b57..1637cff9c241 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -54,7 +54,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.IntUnaryOperator; import java.util.logging.Logger; -import java.util.stream.Collectors; import static org.graalvm.visualizer.settings.layout.LayoutSettings.BOTH_SORT; import static org.graalvm.visualizer.settings.layout.LayoutSettings.CENTER_CROSSING_X; @@ -177,7 +176,7 @@ public enum Combine { private final HashSet reversedLinks; private final HashSet longEdges; private final ArrayList nodes; - private final ArrayList standAlones; + private final HashSet standAlones; private final HashMap vertexToLayoutNode; private final HashMap> reversedLinkStartPoints; private final HashMap> reversedLinkEndPoints; @@ -290,9 +289,13 @@ public void loadCrossingNumber(boolean up) { public int loadCrossingNumber(boolean up, LayoutNode source) { int count = 0; if (up) { - count = succs.stream().map((e) -> e.loadCrossingNumber(up, source)).reduce(count, Integer::sum); + for (LayoutEdge e : succs) { + count = count + e.loadCrossingNumber(true, source); + } } else { - count = preds.stream().map((e) -> e.loadCrossingNumber(up, source)).reduce(count, Integer::sum); + for (LayoutEdge e : preds) { + count = count + e.loadCrossingNumber(false, source); + } } return count; } @@ -516,7 +519,7 @@ public HierarchicalLayoutManager(Combine b, LayoutSettingBean setting) { reversedLinkStartPoints = new HashMap<>(); reversedLinkEndPoints = new HashMap<>(); nodes = new ArrayList<>(); - standAlones = new ArrayList<>(); + standAlones = new HashSet<>(); longEdges = new HashSet<>(); cancelled = new AtomicBoolean(false); } @@ -645,16 +648,14 @@ public void doLayout(LayoutGraph graph) { private class WriteResult extends AlgorithmPart { - private HashMap> splitStartPoints; - private HashMap> splitEndPoints; private HashMap pointsIdentity; private int pointCount; private final int addition = LAYER_OFFSET / 2; @Override protected void run() { - splitStartPoints = new HashMap<>(); - splitEndPoints = new HashMap<>(); + HashMap> splitStartPoints = new HashMap<>(); + HashMap> splitEndPoints = new HashMap<>(); pointsIdentity = new HashMap<>(); HashMap vertexPositions = new HashMap<>(); HashMap> linkPositions = new HashMap<>(); @@ -934,7 +935,7 @@ private boolean allLinksSet() { return graph.getLinks().stream().filter(l -> l.getFrom().getVertex() != l.getTo().getVertex() && l.getTo().getVertex().isVisible() && l.getFrom().getVertex().isVisible()).map(l -> l.getControlPoints().size()).allMatch(s -> s > 1); } - private class ReductionEntry { + private static class ReductionEntry { final Point lastPoint; final int nextPointIndex; @@ -1013,10 +1014,11 @@ private List makeReductionEntries(List 1; - return nexts.entrySet().stream().map(e - -> new ReductionEntry(lastPoint, nextIndex, e.getKey(), e.getValue(), - branching ? new ArrayList<>(reducedPoints) : reducedPoints)) - .collect(Collectors.toList()); + List list = new ArrayList<>(); + for (Map.Entry>>> e : nexts.entrySet()) { + list.add(new ReductionEntry(lastPoint, nextIndex, e.getKey(), e.getValue(), branching ? new ArrayList<>(reducedPoints) : reducedPoints)); + } + return list; } /** @@ -1402,7 +1404,11 @@ private int median(ArrayList values, LayoutNode n, LayoutNode last, boo } } if (!isDefaultLayout && meanNotMedian) { - return values.stream().reduce(0, Integer::sum) / values.size(); + int sum = 0; + for (int v : values) { + sum += v; + } + return sum / values.size(); } values.sort(Integer::compare); if (values.size() % 2 == 0) { @@ -1564,7 +1570,7 @@ public boolean isVisible() { @Override public boolean addAll(Collection c) { - c.forEach((n) -> add0(n)); + c.forEach(this::add0); return super.addAll(c); } @@ -1656,11 +1662,7 @@ public void insert(LayoutNode n, int pos) { maxX = rightNeighbor.x - offset(n, rightNeighbor) - n.getWholeWidth(); } - if (pos > maxX) { - n.x = maxX; - } else { - n.x = pos; - } + n.x = Math.min(pos, maxX); assert minX <= maxX : minX + " vs " + maxX; } positions.add(insertPos, n); @@ -1690,7 +1692,7 @@ public void preCheck() { } } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"unchecked"}) private void createLayers() { if (!isDefaultLayout && crossingSort && !isCrossingByConnDiff) { upCrossing = new ArrayList[layerCount]; @@ -1731,7 +1733,7 @@ private void createLayers() { } } } - toMove = !routingCrossing ? layers : Arrays.stream(layers).map(l -> l.stream().filter(n -> n.isDummy()).collect(LayoutLayer::new, LayoutLayer::add, LayoutLayer::addAll)).toArray(LayoutLayer[]::new); + toMove = !routingCrossing ? layers : Arrays.stream(layers).map(l -> l.stream().filter(LayoutNode::isDummy).collect(LayoutLayer::new, LayoutLayer::add, LayoutLayer::addAll)).toArray(LayoutLayer[]::new); if (!isDefaultLayout && crossingSort && !isCrossingByConnDiff) { for (int i = 0; i < layerCount; ++i) { upCrossing[i] = new ArrayList<>(layers[i]); @@ -1873,7 +1875,7 @@ private void downSweep() { } if (!isDefaultLayout && isCrossingByConnDiff) { changeXOfLayer(i); - layers[i].sort((n1, n2) -> Integer.compare(n1.getCenterX(), n2.getCenterX())); + layers[i].sort(Comparator.comparingInt(LayoutNode::getCenterX)); updateXOfLayer(i); } else { updateCrossingNumbers(i, true); @@ -1899,7 +1901,7 @@ private void upSweep() { if (!isDefaultLayout && isCrossingByConnDiff) { changeXOfLayer(i); - layers[i].sort((n1, n2) -> Integer.compare(n1.getCenterX(), n2.getCenterX())); + layers[i].sort(Comparator.comparingInt(LayoutNode::getCenterX)); updateXOfLayer(i); } else { updateCrossingNumbers(i, false); @@ -2120,7 +2122,7 @@ protected void run() { if (portHash.containsKey(i)) { List list = portHash.get(i); - Collections.sort(list, LAYER_COMPARATOR); + list.sort(LAYER_COMPARATOR); if (list.size() == 1) { processSingleEdge(list.get(0)); @@ -2213,7 +2215,7 @@ public void postCheck() { private class AssignLayers extends AlgorithmPart { - Set checked = new HashSet<>(); + HashSet checked = new HashSet<>(); @Override public void preCheck() { @@ -2371,7 +2373,6 @@ private void reassignLayers() { lay.addAll(Arrays.asList(HierarchicalLayoutManager.this.layers)); double avg = lay.stream().mapToInt(l -> l.getMinimalWidth()).sum() / layerCount; boolean up, down; - LayoutNode node = null; final boolean isQuick = decreaseLayerWidthDeviationQuick; while (!lay.isEmpty()) { if (cancelled.get()) { @@ -2444,9 +2445,7 @@ private void moveUp() { al.add(node); --node.layer; } - for (LayoutLayer l : reassign) { - lay.add(l); - } + lay.addAll(reassign); } private void moveDown() { @@ -2462,9 +2461,7 @@ private void moveDown() { al.add(node); ++node.layer; } - for (LayoutLayer l : reassign) { - lay.add(l); - } + lay.addAll(reassign); } private boolean canMoveUp(LayoutNode node) { @@ -2573,7 +2570,7 @@ private boolean canMoveDown(LayoutNode node) { private void getSizesDown(List sizes) { assert !checked.isEmpty(); List nodes = new ArrayList<>(checked); - nodes.sort((n1, n2) -> Integer.compare(n1.layer, n2.layer)); + nodes.sort(Comparator.comparingInt(n -> n.layer)); int first = nodes.get(0).layer; for (LayoutNode node : nodes) { int index = node.layer - first; @@ -2671,7 +2668,7 @@ protected void run() { } // Start DFS and reverse back edges - visited = new HashSet<>(); + visited = new HashSet<>(nodes.size()); active = new HashSet<>(); DFS(); resolveInsOuts(); @@ -2704,7 +2701,7 @@ private void DFS(LayoutNode startNode, boolean vip) { ArrayList succs = new ArrayList<>(node.succs); if (sortSuccs) { //VIPs are first to follow - Collections.sort(succs, (e1, e2) -> Integer.compare(e1.vip ? e2.to.preds.size() : 0, e2.vip ? e1.to.preds.size() : 0)); + succs.sort((e1, e2) -> Integer.compare(e1.vip ? e2.to.preds.size() : 0, e2.vip ? e1.to.preds.size() : 0)); } for (LayoutEdge e : succs) { if (active.contains(e.to)) { @@ -2719,17 +2716,29 @@ private void DFS(LayoutNode startNode, boolean vip) { } private void DFS() { - nodes.forEach(n -> DFS(n, false)); if (isDefaultLayout || !unreverseVips) { + for (LayoutNode n : nodes) { + DFS(n, false); + } } else { //first search from vip starting nodes - nodes.stream().filter((n) -> n.preds.stream().allMatch((e) -> !e.vip) && n.succs.stream().anyMatch((e) -> e.vip)) - .forEach(n -> DFS(n, true)); + for (LayoutNode node : nodes) { + if (node.preds.getVips() == 0 && node.succs.getVips() != 0) { + DFS(node, true); + } + } if (visited.size() < nodes.size()) { //second look from leftover nodes - nodes.stream().filter((n) -> !visited.contains(n)) - .sorted((n1, n2) -> Integer.compare(n1.preds.size(), n2.preds.size())) - .forEach(n -> DFS(n, false)); + List toSort = new ArrayList<>(); + for (LayoutNode n : nodes) { + if (!visited.contains(n)) { + toSort.add(n); + } + } + toSort.sort(Comparator.comparingInt(n -> n.preds.size())); + for (LayoutNode n : toSort) { + DFS(n, false); + } } } } @@ -3305,7 +3314,7 @@ private void resolveDummyNodes(LayoutNode n, List succs) { if (list.size() == 1) { resolveDummyNodes(list.get(0)); } else { - Collections.sort(list, LAYER_COMPARATOR); + list.sort(LAYER_COMPARATOR); int maxLayer = list.get(list.size() - 1).to.layer; int cnt = maxLayer - n.layer - 1; LayoutEdge[] edges = new LayoutEdge[cnt]; @@ -3367,7 +3376,7 @@ private void reassignInOutBlockNodes() { lay.add(l); } } - layers = lay.toArray(new LayoutLayer[lay.size()]); + layers = lay.toArray(new LayoutLayer[0]); layerCount = layers.length; } @@ -3442,7 +3451,13 @@ private List resolveEdgePoints(List edges) { } private List resolveUnconnectedEdges(List positions, List edges) { - edges = edges.stream().filter(e -> e.link.getControlPoints().contains(null) || e.link.getControlPoints().isEmpty()).collect(Collectors.toList()); + List list = new ArrayList<>(); + for (LayoutEdge edge : edges) { + if (edge.link.getControlPoints().contains(null) || edge.link.getControlPoints().isEmpty()) { + list.add(edge); + } + } + edges = list; if (edges.isEmpty()) { return positions; } @@ -3523,7 +3538,7 @@ private void recreateLayers() { int nodeHeight = n.getWholeHeight(); if (n.vertex instanceof ClusterNode) { //we need to calculate with old height of clusternode, because they could grow a lot - nodeHeight = ((ClusterNode) n.vertex).getCluster().getBounds().height; + nodeHeight = n.vertex.getCluster().getBounds().height; } boolean assigned = false; int avgPos = n.y + (nodeHeight / 2); @@ -3548,8 +3563,8 @@ private void recreateLayers() { for (LayoutLayer l : layers) { l.refresh(); } - layers.sort((l1, l2) -> Integer.compare(l1.y, l2.y)); - HierarchicalLayoutManager.this.layers = layers.toArray(new LayoutLayer[layers.size()]); + layers.sort(Comparator.comparingInt(l -> l.y)); + HierarchicalLayoutManager.this.layers = layers.toArray(new LayoutLayer[0]); layerCount = layers.size(); } From 6f52a8f6de50211c89ee4eace44b268de6058225 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:43 -0700 Subject: [PATCH 15/29] Use parallelSort for links --- .../hierarchicallayout/HierarchicalLayoutManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index 1637cff9c241..d2d058b8a881 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -2914,12 +2914,12 @@ protected void run() { } // Set up edges - List links = new ArrayList<>(graph.getLinks()); + Link[] links = graph.getLinks().toArray(new Link[0]); final boolean VIP = !noVip; if (VIP) { - Collections.sort(links, LINK_COMPARATOR); + Arrays.parallelSort(links, LINK_COMPARATOR); } else { - Collections.sort(links, LINK_NOVIP_COMPARATOR); + Arrays.parallelSort(links, LINK_NOVIP_COMPARATOR); } for (Link l : links) { From 2ccb529e6fafe21630db5dbb87165915caa7cf7e Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:44 -0700 Subject: [PATCH 16/29] Comparator cleanup --- .../HierarchicalLayoutManager.java | 328 ++++++++++++------ 1 file changed, 227 insertions(+), 101 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index d2d058b8a881..d3798dec9bf0 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -2917,9 +2917,9 @@ protected void run() { Link[] links = graph.getLinks().toArray(new Link[0]); final boolean VIP = !noVip; if (VIP) { - Arrays.parallelSort(links, LINK_COMPARATOR); + Arrays.parallelSort(links, HierarchicalLayoutManager::compareLink); } else { - Arrays.parallelSort(links, LINK_NOVIP_COMPARATOR); + Arrays.parallelSort(links, HierarchicalLayoutManager::compareLinkNoVip); } for (Link l : links) { @@ -2958,130 +2958,251 @@ public void postCheck() { } } - private static interface PartialComparator { - - Integer partiallyCompare(T o1, T o2); + /** + * Compare by sum of VIP predecessors and successors, highest first. + * Returns 0 if equal. + */ + private static int nodeBothVipCompare(LayoutNode n1, LayoutNode n2) { + int n1VIP = n1.getPredsVips() + n1.getSuccsVips(); + int n2VIP = n2.getPredsVips() + n2.getSuccsVips(); + return Integer.compare(n2VIP, n1VIP); } - private static class NestedComparator implements Comparator { + /** + * Compare by number of VIP predecessor edges, highest first. + * Returns 0 if equal. + */ + private static int compareNodeDownVIP(LayoutNode n1, LayoutNode n2) { + int n1VIP = n1.getPredsVips(); + int n2VIP = n2.getPredsVips(); + return Integer.compare(n2VIP, n1VIP); + } - private final PartialComparator[] partials; - private final Comparator nested; + /** + * Compare by number of VIP successor edges, highest first. + * Returns 0 if equal. + */ + private static int compareNodeUpVIP(LayoutNode n1, LayoutNode n2) { + int n1VIP = n1.getSuccsVips(); + int n2VIP = n2.getSuccsVips(); + return Integer.compare(n2VIP, n1VIP); + } - public NestedComparator(Comparator comparator, PartialComparator... partials) { - this.partials = partials; - nested = comparator; + /** + * Compare dummy status: dummy nodes sort after real nodes. + * Returns 1 if n1 is dummy and n2 isn't, -1 if n2 is dummy and n1 isn't, 0 if equal. + */ + private static int compareNodeDummy(LayoutNode n1, LayoutNode n2) { + if (n1.isDummy()) { + return n2.isDummy() ? 0 : 1; } + return n2.isDummy() ? -1 : 0; + } - @Override - public int compare(T o1, T o2) { - Integer part; - for (PartialComparator partial : partials) { - part = partial.partiallyCompare(o1, o2); - if (part != null) { - return part; - } - } - return nested.compare(o1, o2); + /** + * Reversed dummy comparison: dummy nodes sort before real nodes. + * Returns -1 if n1 is dummy and n2 isn't, 1 if n2 is dummy and n1 isn't, 0 if equal. + */ + private static int compareNodeRDummy(LayoutNode n1, LayoutNode n2) { + if (n1.isDummy()) { + return n2.isDummy() ? 0 : -1; } + return n2.isDummy() ? 1 : 0; } - private static final Comparator NODE_POSITION_COMPARATOR = (n1, n2) -> n1.pos - n2.pos; + private static int compareNodeBoth(LayoutNode n1, LayoutNode n2) { + return Integer.compare(n1.preds.size() + n1.succs.size(), n2.preds.size() + n2.succs.size()); + } + + private static int compareNodeBothReverse(LayoutNode n1, LayoutNode n2) { + return Integer.compare(n2.preds.size() + n2.succs.size(), n1.preds.size() + n1.succs.size()); + } + + private static int compareNodeDown(LayoutNode n1, LayoutNode n2) { + return Integer.compare(n1.preds.size(), n2.preds.size()); + } + + private static int compareNodeDownReverse(LayoutNode n1, LayoutNode n2) { + return Integer.compare(n2.preds.size(), n1.preds.size()); + } + + private static int compareNodeUp(LayoutNode n1, LayoutNode n2) { + return Integer.compare(n1.succs.size(), n2.succs.size()); + } + + private static int compareNodeUpReverse(LayoutNode n1, LayoutNode n2) { + return Integer.compare(n2.succs.size(), n1.succs.size()); + } - private static final PartialComparator NODE_BOTHVIP = (n1, n2) -> { - long n1VIP = n1.getPredsVips() + n1.getSuccsVips(); - long n2VIP = n2.getPredsVips() + n2.getSuccsVips(); - if (n1VIP != n2VIP) { - return (int) (n2VIP - n1VIP); + private static final Comparator NODE_PROCESSING_BOTH_COMPARATOR = (n1, n2) -> { + int part = nodeBothVipCompare(n1, n2); + if (part != 0) { + return part; } - return null; - }; - private static final PartialComparator NODE_DOWNVIP = (n1, n2) -> { - long n1VIP = n1.getPredsVips(); - long n2VIP = n2.getPredsVips(); - if (n1VIP != n2VIP) { - return (int) (n2VIP - n1VIP); + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; } - return null; + return compareNodeBoth(n1, n2); }; - private static final PartialComparator NODE_UPVIP = (n1, n2) -> { - long n1VIP = n1.getSuccsVips(); - long n2VIP = n2.getSuccsVips(); - if (n1VIP != n2VIP) { - return (int) (n2VIP - n1VIP); + + private static final Comparator NODE_PROCESSING_BOTH_REVERSE_COMPARATOR = (n1, n2) -> { + int part = nodeBothVipCompare(n1, n2); + if (part != 0) { + return part; } - return null; - }; - private static final PartialComparator NODE_DUMMY = (n1, n2) -> { - if (n1.isDummy()) { - return n2.isDummy() ? 0 : 1; + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; } - return n2.isDummy() ? -1 : null; + return compareNodeBothReverse(n1, n2); }; - private static final PartialComparator NODE_RDUMMY = (n1, n2) -> { - if (n1.isDummy()) { - return n2.isDummy() ? 0 : -1; + + private static final Comparator NODE_PROCESSING_DOWN_COMPARATOR = (n1, n2) -> { + int part = compareNodeDownVIP(n1, n2); + if (part != 0) { + return part; } - return n2.isDummy() ? 1 : null; + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeDown(n1, n2); }; - private static final Comparator NODE_BOTH = (n1, n2) -> (n1.preds.size() + n1.succs.size()) - (n2.preds.size() + n2.succs.size()); - private static final Comparator NODE_BOTH_REVERSE = (n1, n2) -> (n2.preds.size() + n2.succs.size()) - (n1.preds.size() + n1.succs.size()); - private static final Comparator NODE_DOWN = (n1, n2) -> n1.preds.size() - n2.preds.size(); - private static final Comparator NODE_DOWN_REVERSE = (n1, n2) -> n2.preds.size() - n1.preds.size(); - private static final Comparator NODE_UP = (n1, n2) -> n1.succs.size() - n2.succs.size(); - private static final Comparator NODE_UP_REVERSE = (n1, n2) -> n2.succs.size() - n1.succs.size(); - - private static final Comparator NODE_PROCESSING_BOTH_COMPARATOR = new NestedComparator( - NODE_BOTH, NODE_BOTHVIP, NODE_DUMMY); - - private static final Comparator NODE_PROCESSING_BOTH_REVERSE_COMPARATOR = new NestedComparator( - NODE_BOTH_REVERSE, NODE_BOTHVIP, NODE_DUMMY); - - private static final Comparator NODE_PROCESSING_DOWN_COMPARATOR = new NestedComparator( - NODE_DOWN, NODE_DOWNVIP, NODE_DUMMY); - - private static final Comparator NODE_PROCESSING_DOWN_REVERSE_COMPARATOR = new NestedComparator( - NODE_DOWN_REVERSE, NODE_DOWNVIP, NODE_DUMMY); + private static final Comparator NODE_PROCESSING_DOWN_REVERSE_COMPARATOR = (n1, n2) -> { + int part = compareNodeDownVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeDownReverse(n1, n2); + }; - private static final Comparator NODE_PROCESSING_UP_COMPARATOR = new NestedComparator( - NODE_UP, NODE_UPVIP, NODE_DUMMY); + private static final Comparator NODE_PROCESSING_UP_COMPARATOR = (n1, n2) -> { + int part = compareNodeUpVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeUp(n1, n2); + }; - private static final Comparator NODE_PROCESSING_UP_REVERSE_COMPARATOR = new NestedComparator( - NODE_UP_REVERSE, NODE_UPVIP, NODE_DUMMY); + private static final Comparator NODE_PROCESSING_UP_REVERSE_COMPARATOR = (n1, n2) -> { + int part = compareNodeUpVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeUpReverse(n1, n2); + }; - private static final Comparator NODE_PROCESSING_DUMMY_BOTH_COMPARATOR = new NestedComparator( - NODE_BOTH, NODE_BOTHVIP, NODE_RDUMMY); + private static final Comparator NODE_PROCESSING_DUMMY_BOTH_COMPARATOR = (n1, n2) -> { + int part = nodeBothVipCompare(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeRDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeBoth(n1, n2); + }; - private static final Comparator NODE_PROCESSING_DUMMY_BOTH_REVERSE_COMPARATOR = new NestedComparator( - NODE_BOTH_REVERSE, NODE_BOTHVIP, NODE_RDUMMY); + private static final Comparator NODE_PROCESSING_DUMMY_BOTH_REVERSE_COMPARATOR = (n1, n2) -> { + int part = nodeBothVipCompare(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeRDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeBothReverse(n1, n2); + }; - private static final Comparator NODE_PROCESSING_DUMMY_DOWN_COMPARATOR = new NestedComparator( - NODE_DOWN, NODE_DOWNVIP, NODE_RDUMMY); + private static final Comparator NODE_PROCESSING_DUMMY_DOWN_COMPARATOR = (n1, n2) -> { + int part = compareNodeDownVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeRDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeDown(n1, n2); + }; - private static final Comparator NODE_PROCESSING_DUMMY_DOWN_REVERSE_COMPARATOR = new NestedComparator( - NODE_DOWN_REVERSE, NODE_DOWNVIP, NODE_RDUMMY); + private static final Comparator NODE_PROCESSING_DUMMY_DOWN_REVERSE_COMPARATOR = (n1, n2) -> { + int part = compareNodeDownVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeRDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeDownReverse(n1, n2); + }; - private static final Comparator NODE_PROCESSING_DUMMY_UP_COMPARATOR = new NestedComparator( - NODE_UP, NODE_UPVIP, NODE_RDUMMY); + private static final Comparator NODE_PROCESSING_DUMMY_UP_COMPARATOR = (n1, n2) -> { + int part = compareNodeUpVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeRDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeUp(n1, n2); + }; - private static final Comparator NODE_PROCESSING_DUMMY_UP_REVERSE_COMPARATOR = new NestedComparator( - NODE_UP_REVERSE, NODE_UPVIP, NODE_RDUMMY); + private static final Comparator NODE_PROCESSING_DUMMY_UP_REVERSE_COMPARATOR = (n1, n2) -> { + int part = compareNodeUpVIP(n1, n2); + if (part != 0) { + return part; + } + part = compareNodeRDummy(n1, n2); + if (part != 0) { + return part; + } + return compareNodeUpReverse(n1, n2); + }; private static final Comparator CROSSING_NODE_COMPARATOR = (n1, n2) -> Float.compare(n1.crossingNumber, n2.crossingNumber); - private static final Comparator DOWN_CROSSING_COMPARATOR = (n1, n2) -> n1.succs.size() - n2.succs.size(); - private static final Comparator UP_CROSSING_COMPARATOR = (n1, n2) -> n1.preds.size() - n2.preds.size(); + private static final Comparator DOWN_CROSSING_COMPARATOR = Comparator.comparingInt(n -> n.succs.size()); + private static final Comparator UP_CROSSING_COMPARATOR = Comparator.comparingInt(n -> n.preds.size()); private static final Comparator DANGLING_UP_NODE_COMPARATOR = (n1, n2) -> { int ret = Integer.compare(n1.layer, n2.layer); if (ret != 0) { return ret; } - ret = NODE_PROCESSING_UP_COMPARATOR.compare(n1, n2); - if (ret != 0) { - return ret; + // Inline NODE_PROCESSING_UP_COMPARATOR logic + int part = compareNodeUpVIP(n1, n2); + if (part != 0) { + return part; + } else { + part = compareNodeDummy(n1, n2); + if (part != 0) { + return part; + } else { + ret = Integer.compare(n1.succs.size(), n2.succs.size()); + if (ret != 0) { + return ret; + } + } } - return NODE_POSITION_COMPARATOR.compare(n1, n2); + return n1.pos - n2.pos; }; private static final Comparator DANGLING_DOWN_NODE_COMPARATOR = (n1, n2) -> { @@ -3093,28 +3214,33 @@ public int compare(T o1, T o2) { if (ret != 0) { return ret; } - return NODE_POSITION_COMPARATOR.compare(n1, n2); + return n1.pos - n2.pos; }; - private static final Comparator LAYER_COMPARATOR = (e1, e2) -> e1.to.layer - e2.to.layer; + private static final Comparator LAYER_COMPARATOR = Comparator.comparingInt(e -> e.to.layer); - private static final Comparator LINK_NOVIP_COMPARATOR = (l1, l2) -> { - int result = l1.getFrom().getVertex().compareTo(l2.getFrom().getVertex()); + private static int compareLinkNoVip(Link l1, Link l2) { + Port l1From = l1.getFrom(); + Port l2From = l2.getFrom(); + int result = l1From.getVertex().compareTo(l2From.getVertex()); if (result != 0) { return result; } - result = l1.getTo().getVertex().compareTo(l2.getTo().getVertex()); + Port l1To = l1.getTo(); + Port l2To = l2.getTo(); + result = l1To.getVertex().compareTo(l2To.getVertex()); if (result != 0) { return result; } - result = l1.getFrom().getRelativePosition().x - l2.getFrom().getRelativePosition().x; + result = l1From.getRelativePosition().x - l2From.getRelativePosition().x; if (result != 0) { return result; } - result = l1.getTo().getRelativePosition().x - l2.getTo().getRelativePosition().x; + result = l1To.getRelativePosition().x - l2To.getRelativePosition().x; return result; - }; - private static final Comparator LINK_COMPARATOR = (l1, l2) -> { + } + + private static int compareLink(Link l1, Link l2) { if (l1.isVIP() && !l2.isVIP()) { return -1; } @@ -3122,8 +3248,8 @@ public int compare(T o1, T o2) { if (!l1.isVIP() && l2.isVIP()) { return 1; } - return LINK_NOVIP_COMPARATOR.compare(l1, l2); - }; + return compareLinkNoVip(l1, l2); + } @Override public void doRouting(LayoutGraph graph) { From 4501ea21ea963ced3937c73e414f93f794c872fa Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 27 Oct 2025 10:58:44 -0700 Subject: [PATCH 17/29] add enable-native-access --- .../application/src/main/resources/idealgraphvisualizer.conf | 2 +- visualizer/IdealGraphVisualizer/pom.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf b/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf index f31418972ebd..162739f95945 100644 --- a/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf +++ b/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf @@ -26,7 +26,7 @@ default_cachedir="${DEFAULT_CACHEDIR_ROOT}/0.31" # options used by the launcher by default, can be overridden by explicit # command line switches -default_options="--branding idealgraphvisualizer -J-XX:+UseStringDeduplication -J-DRepositoryUpdate.increasedLogLevel=800 -J-client -J-Xss2m -J-Xms32m -J-Dnetbeans.logger.console=false -J-Djdk.gtk.version=2.2 -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.base/java.security=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.text=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/java.awt=ALL-UNNAMED -J--add-opens=java.desktop/java.awt.event=ALL-UNNAMED -J--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED -J--add-opens=jdk.jshell/jdk.jshell=ALL-UNNAMED -J--add-modules=jdk.jshell -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED -J--add-exports=java.desktop/com.sun.beans.editors=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.management/sun.management=ALL-UNNAMED -J--add-exports=java.base/sun.reflect.annotation=ALL-UNNAMED -J--add-exports=jdk.javadoc/com.sun.tools.javadoc.main=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions" +default_options="--branding idealgraphvisualizer -J-XX:+UseStringDeduplication -J-DRepositoryUpdate.increasedLogLevel=800 -J-client -J-Xss2m -J-Xms32m -J-Dnetbeans.logger.console=false -J-Djdk.gtk.version=2.2 -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.base/java.security=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.text=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/java.awt=ALL-UNNAMED -J--add-opens=java.desktop/java.awt.event=ALL-UNNAMED -J--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED -J--add-opens=jdk.jshell/jdk.jshell=ALL-UNNAMED -J--add-modules=jdk.jshell -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED -J--add-exports=java.desktop/com.sun.beans.editors=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.management/sun.management=ALL-UNNAMED -J--add-exports=java.base/sun.reflect.annotation=ALL-UNNAMED -J--add-exports=jdk.javadoc/com.sun.tools.javadoc.main=ALL-UNNAMED -J--enable-native-access=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions" # for development purposes you may wish to append: -J-Dnetbeans.logger.console=true -J-ea diff --git a/visualizer/IdealGraphVisualizer/pom.xml b/visualizer/IdealGraphVisualizer/pom.xml index ab34498ff584..e93d3352439d 100644 --- a/visualizer/IdealGraphVisualizer/pom.xml +++ b/visualizer/IdealGraphVisualizer/pom.xml @@ -50,6 +50,7 @@ true + --enable-native-access=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-exports=java.desktop/sun.awt=ALL-UNNAMED -Dpolyglot.engine.WarnInterpreterOnly=false From b215a733a74e20f9deb5a337a4ce8e4a92755a84 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 29 Oct 2025 11:51:25 -0700 Subject: [PATCH 18/29] Parser speeedups --- .../graphio/parsing/BinaryReader.java | 72 +++++++----- .../compiler/graphio/parsing/Builder.java | 37 +++++-- .../graphio/parsing/ModelBuilder.java | 104 ++++++++---------- .../graphio/parsing/TemplateParser.java | 64 +++++++++++ .../graphio/parsing/model/Properties.java | 21 +++- 5 files changed, 197 insertions(+), 101 deletions(-) create mode 100644 visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java index f59bbf9c1373..9af593eb0ebd 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java @@ -24,6 +24,31 @@ */ package jdk.graal.compiler.graphio.parsing; +import jdk.graal.compiler.graphio.parsing.Builder.Length; +import jdk.graal.compiler.graphio.parsing.Builder.LengthToString; +import jdk.graal.compiler.graphio.parsing.Builder.ModelControl; +import jdk.graal.compiler.graphio.parsing.Builder.Node; +import jdk.graal.compiler.graphio.parsing.Builder.NodeClass; +import jdk.graal.compiler.graphio.parsing.Builder.Port; +import jdk.graal.compiler.graphio.parsing.Builder.TypedPort; +import jdk.graal.compiler.graphio.parsing.model.GraphDocument; +import jdk.graal.compiler.graphio.parsing.model.Group; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; + +import java.io.EOFException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; + import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.BEGIN_GRAPH; import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.BEGIN_GROUP; import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.CLOSE_GROUP; @@ -51,31 +76,6 @@ import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.PROPERTY_TRUE; import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.STREAM_PROPERTIES; -import java.io.EOFException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - -import jdk.graal.compiler.graphio.parsing.Builder.Length; -import jdk.graal.compiler.graphio.parsing.Builder.LengthToString; -import jdk.graal.compiler.graphio.parsing.Builder.ModelControl; -import jdk.graal.compiler.graphio.parsing.Builder.Node; -import jdk.graal.compiler.graphio.parsing.Builder.NodeClass; -import jdk.graal.compiler.graphio.parsing.Builder.Port; -import jdk.graal.compiler.graphio.parsing.Builder.TypedPort; -import jdk.graal.compiler.graphio.parsing.model.GraphDocument; -import jdk.graal.compiler.graphio.parsing.model.Group; -import jdk.graal.compiler.graphio.parsing.model.InputGraph; - /** * The class reads the Graal binary dump format. All model object creation or property value * computation / logic is delegated to the {@link ModelBuilder} class. While the BinaryReader should @@ -474,15 +474,33 @@ public boolean equals(Object obj) { public static final class EnumKlass extends Klass { public final String[] values; + public final EnumValue[] enums; + private volatile int hashCode = 0; public EnumKlass(String name, String[] values) { super(name); this.values = values; + this.enums = new EnumValue[values.length]; + for (int i = 0; i < values.length; i++) { + this.enums[i] = new EnumValue(this, i); + } + } + + EnumValue get(int ordinal) { + if (ordinal >= 0 && ordinal < enums.length) { + return enums[ordinal]; + } + return new EnumValue(this, ordinal); } @Override public int hashCode() { - return super.hash * 31 + Arrays.hashCode(values); + int h = hashCode; + if (h == 0) { + h = Objects.hash(super.hashCode(), Arrays.hashCode(values)); + hashCode = h; + } + return h; } @Override @@ -648,7 +666,7 @@ private Object addPoolEntry(Class klass) throws IOException { case POOL_ENUM: { EnumKlass enumClass = readPoolObject(EnumKlass.class); int ordinal = dataSource.readInt(); - obj = new EnumValue(enumClass, ordinal); + obj = enumClass.get(ordinal); break; } case POOL_NODE_CLASS: { diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java index 2e1e46713004..e329b370c176 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java @@ -25,20 +25,21 @@ package jdk.graal.compiler.graphio.parsing; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; +import jdk.graal.compiler.graphio.parsing.TemplateParser.TemplatePart; import jdk.graal.compiler.graphio.parsing.model.GraphDocument; import jdk.graal.compiler.graphio.parsing.model.Group; import jdk.graal.compiler.graphio.parsing.model.InputBlock; import jdk.graal.compiler.graphio.parsing.model.InputGraph; import jdk.graal.compiler.graphio.parsing.model.Properties; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; + /** * Interface for building IGV data from the stream. */ @@ -219,16 +220,23 @@ public String toString() { final class NodeClass { public final String className; public final String nameTemplate; + private final List templateParts; public final List inputs; public final List sux; + private String shortString; NodeClass(String className, String nameTemplate, List inputs, List sux) { this.className = className; this.nameTemplate = nameTemplate; + this.templateParts = jdk.graal.compiler.graphio.parsing.TemplateParser.parseTemplate(nameTemplate); this.inputs = inputs; this.sux = sux; } + public List getTemplateParts() { + return templateParts; + } + @Override public String toString() { return className; @@ -265,13 +273,18 @@ public boolean equals(Object obj) { } String toShortString() { - int lastDot = className.lastIndexOf('.'); - String localShortName = className.substring(lastDot + 1); - if (localShortName.endsWith("Node") && !localShortName.equals("StartNode") && !localShortName.equals(CLASS_ENDNODE)) { - return localShortName.substring(0, localShortName.length() - 4); - } else { - return localShortName; + String s = shortString; + if (s == null) { + int lastDot = className.lastIndexOf('.'); + String localShortName = className.substring(lastDot + 1); + if (localShortName.endsWith("Node") && !localShortName.equals("StartNode") && !localShortName.equals(CLASS_ENDNODE)) { + s = localShortName.substring(0, localShortName.length() - 4); + } else { + s = localShortName; + } + shortString = s; } + return shortString; } } } diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java index d13062bdf003..5472520af940 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java @@ -25,15 +25,19 @@ package jdk.graal.compiler.graphio.parsing; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_BLOCK; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_CLASS; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_DUPLICATE; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_HAS_PREDECESSOR; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_ID; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_IDX; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_SHORT_NAME; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; +import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; +import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; +import jdk.graal.compiler.graphio.parsing.model.Folder; +import jdk.graal.compiler.graphio.parsing.model.FolderElement; +import jdk.graal.compiler.graphio.parsing.model.GraphClassifier; +import jdk.graal.compiler.graphio.parsing.model.GraphDocument; +import jdk.graal.compiler.graphio.parsing.model.Group; +import jdk.graal.compiler.graphio.parsing.model.InputBlock; +import jdk.graal.compiler.graphio.parsing.model.InputEdge; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; +import jdk.graal.compiler.graphio.parsing.model.InputMethod; +import jdk.graal.compiler.graphio.parsing.model.InputNode; +import jdk.graal.compiler.graphio.parsing.model.Properties; import java.util.ArrayDeque; import java.util.ArrayList; @@ -47,22 +51,16 @@ import java.util.Objects; import java.util.Set; import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; -import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; -import jdk.graal.compiler.graphio.parsing.model.Folder; -import jdk.graal.compiler.graphio.parsing.model.FolderElement; -import jdk.graal.compiler.graphio.parsing.model.GraphClassifier; -import jdk.graal.compiler.graphio.parsing.model.GraphDocument; -import jdk.graal.compiler.graphio.parsing.model.Group; -import jdk.graal.compiler.graphio.parsing.model.InputBlock; -import jdk.graal.compiler.graphio.parsing.model.InputEdge; -import jdk.graal.compiler.graphio.parsing.model.InputGraph; -import jdk.graal.compiler.graphio.parsing.model.InputMethod; -import jdk.graal.compiler.graphio.parsing.model.InputNode; -import jdk.graal.compiler.graphio.parsing.model.Properties; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_BLOCK; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_CLASS; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_DUPLICATE; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_HAS_PREDECESSOR; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_ID; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_IDX; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_SHORT_NAME; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; /** * Builds a model based on SAX-like events. The expected sequence of events is: @@ -684,7 +682,7 @@ protected final void reportProgress() { @Override public void setNodeName(NodeClass nodeClass) { assert currentNode != null; - getProperties().setProperty(PROPNAME_NAME, createName(nodeClass, nodeEdges, nodeClass.nameTemplate)); + getProperties().setProperty(PROPNAME_NAME, createName(nodeClass, nodeEdges)); getProperties().setProperty(PROPNAME_CLASS, nodeClass.className); switch (nodeClass.className) { case "BeginNode": @@ -696,35 +694,38 @@ public void setNodeName(NodeClass nodeClass) { } } - static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\{([pi])#([a-zA-Z0-9$_]+)(/([lms]))?}"); - - private String createName(NodeClass nodeClass, List edges, String template) { - if (template.isEmpty()) { + private String createName(NodeClass nodeClass, List edges) { + if (nodeClass.nameTemplate.isEmpty()) { return nodeClass.toShortString(); } - Matcher m = TEMPLATE_PATTERN.matcher(template); - StringBuilder sb = new StringBuilder(); + + StringBuilder sb = new StringBuilder(nodeClass.nameTemplate.length()); Properties p = getProperties(); - while (m.find()) { - String name = m.group(2); - String type = m.group(1); - String result; + List templateParts = nodeClass.getTemplateParts(); + for (TemplateParser.TemplatePart template : templateParts) { + if (!template.isReplacement) { + sb.append(template.value); + continue; + } + String name = template.name; + String type = template.type; switch (type) { case "i": - StringBuilder inputString = new StringBuilder(); + boolean first = true; for (EdgeInfo edge : edges) { if (edge.label.startsWith(name) && (name.length() == edge.label.length() || edge.label.charAt(name.length()) == '[')) { - if (inputString.length() > 0) { - inputString.append(", "); + if (!first) { + sb.append(", "); } - inputString.append(edge.from); + first = false; + sb.append(edge.from); } } - result = inputString.toString(); break; case "p": Object prop = p.get(name); - String length = m.group(4); + String length = template.length; + String result; if (prop == null) { result = "?"; } else if (length != null && prop instanceof LengthToString lengthProp) { @@ -735,36 +736,21 @@ private String createName(NodeClass nodeClass, List edges, String temp case "m": result = lengthProp.toString(Length.M); break; - default: case "l": + default: result = lengthProp.toString(Length.L); break; } } else { result = prop.toString(); } + sb.append(result); break; default: - result = "#?#"; + sb.append("#?#"); break; } - - // Escape '\' and '$' to not interfere with the regular expression. - StringBuilder newResult = new StringBuilder(); - for (int i = 0; i < result.length(); ++i) { - char c = result.charAt(i); - if (c == '\\') { - newResult.append("\\\\"); - } else if (c == '$') { - newResult.append("\\$"); - } else { - newResult.append(c); - } - } - result = newResult.toString(); - m.appendReplacement(sb, result); } - m.appendTail(sb); return sb.toString(); } diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java new file mode 100644 index 000000000000..7e9e4f3dc39a --- /dev/null +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java @@ -0,0 +1,64 @@ +package jdk.graal.compiler.graphio.parsing; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TemplateParser { + private static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\{([pi])#([a-zA-Z0-9$_]+)(/([lms]))?}"); + + public static List parseTemplate(String template) { + List parts = new ArrayList<>(); + Matcher m = TEMPLATE_PATTERN.matcher(template); + int lastEnd = 0; + while (m.find()) { + if (m.start() > lastEnd) { + parts.add(new TemplatePart(template.substring(lastEnd, m.start()))); + } + String name = m.group(2); + String type = m.group(1); + switch (type) { + case "i": + parts.add(new TemplatePart(name, type, null)); + break; + case "p": + String length = m.group(4); + parts.add(new TemplatePart(name, type, length)); + break; + default: + parts.add(new TemplatePart("#?#")); + break; + } + lastEnd = m.end(); + } + if (lastEnd < template.length()) { + parts.add(new TemplatePart(template.substring(lastEnd))); + } + return parts; + } + + public static class TemplatePart { + public final String value; + public final boolean isReplacement; + public final String name; + public final String type; + public final String length; + + public TemplatePart(String name, String type, String length) { + this.name = name; + this.type = type; + this.length = length; + this.value = null; + this.isReplacement = true; + } + + public TemplatePart(String value) { + this.value = value; + this.isReplacement = false; + name = null; + type = null; + length = null; + } + } +} diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java index 654daab68feb..f46f6aa7bed5 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java @@ -288,9 +288,13 @@ public LinkedHashMapProperties() { } public LinkedHashMapProperties(Properties p) { - this(p.size()); - for (Property prop : p) { - map.put(prop.getName(), prop.getValue()); + if (p instanceof LinkedHashMapProperties hash) { + map = new LinkedHashMap<>(hash.map); + } else { + map = new LinkedHashMap<>(p.size()); + for (Property prop : p) { + map.put(prop.getName(), prop.getValue()); + } } } @@ -303,6 +307,17 @@ public int size() { return map.size(); } + @Override + public boolean equals(Object o) { + if (o instanceof LinkedHashMapProperties hash) { + if (size() != hash.size()) { + return false; + } + return map.equals(hash.map); + } + return super.equals(o); + } + @Override public Property atIndex(int index) { if (index >= size() || index < 0) { From e4f6c1361e4f1edda68cbb91cfd98c3c8376022b Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 30 Oct 2025 08:55:43 -0700 Subject: [PATCH 19/29] faster check for reserved property names --- .../graal/compiler/graphio/parsing/ModelBuilder.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java index 5472520af940..704fe64572d2 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java @@ -660,6 +660,14 @@ public void endNode(int nodeId) { PROPNAME_ID, PROPNAME_IDX, PROPNAME_BLOCK))); + private static boolean isSystemProperty(String key) { + return switch (key) { + case PROPNAME_HAS_PREDECESSOR, PROPNAME_NAME, PROPNAME_CLASS, PROPNAME_ID, PROPNAME_IDX, PROPNAME_BLOCK -> + true; + default -> false; + }; + } + @Override public void setGroupName(String name, String shortName) { assert folder instanceof Group; @@ -761,7 +769,7 @@ public void setNodeProperty(String key, Object value) { assert currentNode != null; String k = key; if (!(value instanceof InputGraph)) { - if (SYSTEM_PROPERTIES.contains(key)) { + if (isSystemProperty(key)) { k = NOT_DATA + k; } setProperty(k, value); From 69d91a60b717f0f390a6b1b06ad47bb42536f11d Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 30 Oct 2025 08:59:09 -0700 Subject: [PATCH 20/29] slightly faster Properties comparison --- .../graphio/parsing/model/Properties.java | 42 +++++++++++++++ .../graphio/parsing/model/Properties.java | 54 +++++++++++++++---- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java index 654daab68feb..71b78465613c 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java @@ -303,6 +303,48 @@ public int size() { return map.size(); } + @Override + public boolean equals(Object o) { + if (o instanceof LinkedHashMapProperties hash) { + if (size() != hash.size()) { + return false; + } + /* + * Most Properties comparisons are for cases where they are the same or very similar + * so efficiency is fairly important to loading speed. They are commonly ordered in + * the same fashion so take advantage of that in the comparison + */ + Set> set1 = map.entrySet(); + Iterator> iter1 = set1.iterator(); + + Set> set2 = hash.map.entrySet(); + Iterator> iter2 = set2.iterator(); + while (iter1.hasNext()) { + var entry = iter1.next(); + // They are the same length so hasNext must be true + Map.Entry next = iter2.next(); + if (entry.getKey().equals(next.getKey())) { + if (!Objects.deepEquals(entry.getValue(), next.getValue())) { + return false; + } + continue; + } + // Different key encountered so must resort to contains for all following values + if (!Objects.deepEquals(entry.getValue(), hash.map.get(entry.getKey()))) { + return false; + } + while (iter1.hasNext()) { + entry = iter1.next(); + if (!Objects.deepEquals(entry.getValue(), hash.map.get(entry.getKey()))) { + return false; + } + } + } + return true; + } + return super.equals(o); + } + @Override public Property atIndex(int index) { if (index >= size() || index < 0) { diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java index f46f6aa7bed5..b26c9c8ceb89 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java @@ -114,7 +114,8 @@ public Map toMap(Map props, Set excludeN props.put(names[i], values[i]); } } else { - P: for (int i = 0; i < size; ++i) { + P: + for (int i = 0; i < size; ++i) { String n = names[i]; if (!excludes.contains(n)) { for (String p : excludePrefixes) { @@ -313,7 +314,37 @@ public boolean equals(Object o) { if (size() != hash.size()) { return false; } - return map.equals(hash.map); + // Most Properties comparisons are for cases where they are the same or very similar + // so efficiency is fairly important to loading speed. They are commonly ordered in the + // same fashion so take advantage of that in the comparison + Set> set1 = map.entrySet(); + Iterator> iter1 = set1.iterator(); + + Set> set2 = hash.map.entrySet(); + Iterator> iter2 = set2.iterator(); + while (iter1.hasNext()) { + var entry = iter1.next(); + // They are the same length so hasNext must be true + Map.Entry next = iter2.next(); + if (entry.getKey().equals(next.getKey())) { + if (!Objects.deepEquals(entry.getValue(), next.getValue())) { + return false; + } + continue; + } + // Different key encountered so must resort to contains for all following values + if (!Objects.deepEquals(entry.getValue(), hash.map.get(entry.getKey()))) { + return false; + } + while (iter1.hasNext()) { + entry = iter1.next(); + if (!Objects.deepEquals(entry.getValue(), hash.map.get(entry.getKey()))) { + return false; + } + } + return true; + } + return true; } return super.equals(o); } @@ -347,7 +378,8 @@ public Map toMap(Map props, Set excludeN if (excludes.isEmpty() && excludePrefixes.length == 0) { props.putAll(map); } else { - P: for (Map.Entry entry : map.entrySet()) { + P: + for (Map.Entry entry : map.entrySet()) { String n = entry.getKey(); if (!excludes.contains(n)) { for (String p : excludePrefixes) { @@ -484,10 +516,10 @@ protected final int makeHash() { int hash = 5; for (Property prop : this) { hash = hash ^ (Property.makeHash(prop.getName(), prop.getValue())); // position affected - // hash would - // violate - // equal/hash - // contract + // hash would + // violate + // equal/hash + // contract } return hash; } @@ -737,10 +769,10 @@ public RegexpPropertyMatcher(String name, String value) { /** * Constructs a regular expression based matcher. * - * @param name name of the property to search - * @param value pattern + * @param name name of the property to search + * @param value pattern * @param entireMatch whether the matcher should only accept full matches - * @param flags flags to use to compile the pattern defined by {@code value} + * @param flags flags to use to compile the pattern defined by {@code value} */ public RegexpPropertyMatcher(String name, String value, boolean entireMatch, int flags) { if (name == null) { @@ -857,7 +889,7 @@ public T get(String key, Class clazz) { * {@link #get(java.lang.String, java.lang.Class)} will throw an exception/assertion on * non-String values. * - * @param key property key + * @param key property key * @param defValue value to be returned if the property is not defined or is {@code null} * @return String representation */ From 86dea0466bdab4eec7d063feb161703e80a4f11a Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 3 Nov 2025 13:26:38 -0800 Subject: [PATCH 21/29] Remove unnecessary add-export --- .../application/src/main/resources/idealgraphvisualizer.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf b/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf index 162739f95945..96f50a440749 100644 --- a/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf +++ b/visualizer/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf @@ -26,7 +26,7 @@ default_cachedir="${DEFAULT_CACHEDIR_ROOT}/0.31" # options used by the launcher by default, can be overridden by explicit # command line switches -default_options="--branding idealgraphvisualizer -J-XX:+UseStringDeduplication -J-DRepositoryUpdate.increasedLogLevel=800 -J-client -J-Xss2m -J-Xms32m -J-Dnetbeans.logger.console=false -J-Djdk.gtk.version=2.2 -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.base/java.security=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.text=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/java.awt=ALL-UNNAMED -J--add-opens=java.desktop/java.awt.event=ALL-UNNAMED -J--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED -J--add-opens=jdk.jshell/jdk.jshell=ALL-UNNAMED -J--add-modules=jdk.jshell -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED -J--add-exports=java.desktop/com.sun.beans.editors=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.management/sun.management=ALL-UNNAMED -J--add-exports=java.base/sun.reflect.annotation=ALL-UNNAMED -J--add-exports=jdk.javadoc/com.sun.tools.javadoc.main=ALL-UNNAMED -J--enable-native-access=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions" +default_options="--branding idealgraphvisualizer -J-XX:+UseStringDeduplication -J-DRepositoryUpdate.increasedLogLevel=800 -J-client -J-Xss2m -J-Xms32m -J-Dnetbeans.logger.console=false -J-Djdk.gtk.version=2.2 -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.base/java.security=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.text=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/java.awt=ALL-UNNAMED -J--add-opens=java.desktop/java.awt.event=ALL-UNNAMED -J--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED -J--add-opens=jdk.jshell/jdk.jshell=ALL-UNNAMED -J--add-modules=jdk.jshell -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED -J--add-exports=java.desktop/com.sun.beans.editors=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.management/sun.management=ALL-UNNAMED -J--add-exports=java.base/sun.reflect.annotation=ALL-UNNAMED -J--enable-native-access=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions" # for development purposes you may wish to append: -J-Dnetbeans.logger.console=true -J-ea From 6bac7d5a0c92f898f04dabb4fe61e018c144fe1b Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 3 Nov 2025 13:30:58 -0800 Subject: [PATCH 22/29] remove argument --- .../HierarchicalLayoutManager.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index d3798dec9bf0..807ef2f8e25c 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -524,43 +524,43 @@ public HierarchicalLayoutManager(Combine b, LayoutSettingBean setting) { cancelled = new AtomicBoolean(false); } - private void initSettings(LayoutSettingBean setting) { + private void initSettings() { // Boolean settings (cached once per instance) - bothSort = setting.get(Boolean.class, BOTH_SORT); - reverseSort = setting.get(Boolean.class, REVERSE_SORT); - dummyFirstSort = setting.get(Boolean.class, DUMMY_FIRST_SORT); - lastDownSweep = setting.get(Boolean.class, LAST_DOWN_SWEEP); - optimalUpVip = setting.get(Boolean.class, OPTIMAL_UP_VIP); - squashPosition = setting.get(Boolean.class, SQUASH_POSITION); - centerSimpleNodes = setting.get(Boolean.class, CENTER_SIMPLE_NODES); - meanNotMedian = setting.get(Boolean.class, MEAN_NOT_MEDIAN); - crossingSort = setting.get(Boolean.class, CROSSING_SORT); - noCrossingLayerReassign = setting.get(Boolean.class, NO_CROSSING_LAYER_REASSIGN); - lastUpCrossingSweep = setting.get(Boolean.class, LAST_UP_CROSSING_SWEEP); - irrelevantLayoutCode = setting.get(Boolean.class, IRRELEVANT_LAYOUT_CODE); - centerCrossingX = setting.get(Boolean.class, CENTER_CROSSING_X); - crossResetXFromNode = setting.get(Boolean.class, CROSS_RESET_X_FROM_NODE); - crossResetXFromMiddle = setting.get(Boolean.class, CROSS_RESET_X_FROM_MIDDLE); - spanByAngle = setting.get(Boolean.class, SPAN_BY_ANGLE); - noDummyLongEdges = setting.get(Boolean.class, NO_DUMMY_LONG_EDGES); - standalones = setting.get(Boolean.class, STANDALONES); - edgeBending = setting.get(Boolean.class, EDGE_BENDING); - decreaseLayerWidthDeviation = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION); - decreaseLayerWidthDeviationQuick = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_QUICK); - decreaseLayerWidthDeviationUp = setting.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_UP); - unreverseVips = setting.get(Boolean.class, UNREVERSE_VIPS); - noVip = setting.get(Boolean.class, NO_VIP); - crossReduceRouting = setting.get(Boolean.class, CROSS_REDUCE_ROUTING); - crossPositionDuring = setting.get(Boolean.class, CROSS_POSITION_DURING); - properCrossingClosestNode = setting.get(Boolean.class, PROPER_CROSSING_CLOSEST_NODE); - unknownCrossingNumber = setting.get(Boolean.class, UNKNOWN_CROSSING_NUMBER); + bothSort = settings.get(Boolean.class, BOTH_SORT); + reverseSort = settings.get(Boolean.class, REVERSE_SORT); + dummyFirstSort = settings.get(Boolean.class, DUMMY_FIRST_SORT); + lastDownSweep = settings.get(Boolean.class, LAST_DOWN_SWEEP); + optimalUpVip = settings.get(Boolean.class, OPTIMAL_UP_VIP); + squashPosition = settings.get(Boolean.class, SQUASH_POSITION); + centerSimpleNodes = settings.get(Boolean.class, CENTER_SIMPLE_NODES); + meanNotMedian = settings.get(Boolean.class, MEAN_NOT_MEDIAN); + crossingSort = settings.get(Boolean.class, CROSSING_SORT); + noCrossingLayerReassign = settings.get(Boolean.class, NO_CROSSING_LAYER_REASSIGN); + lastUpCrossingSweep = settings.get(Boolean.class, LAST_UP_CROSSING_SWEEP); + irrelevantLayoutCode = settings.get(Boolean.class, IRRELEVANT_LAYOUT_CODE); + centerCrossingX = settings.get(Boolean.class, CENTER_CROSSING_X); + crossResetXFromNode = settings.get(Boolean.class, CROSS_RESET_X_FROM_NODE); + crossResetXFromMiddle = settings.get(Boolean.class, CROSS_RESET_X_FROM_MIDDLE); + spanByAngle = settings.get(Boolean.class, SPAN_BY_ANGLE); + noDummyLongEdges = settings.get(Boolean.class, NO_DUMMY_LONG_EDGES); + standalones = settings.get(Boolean.class, STANDALONES); + edgeBending = settings.get(Boolean.class, EDGE_BENDING); + decreaseLayerWidthDeviation = settings.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION); + decreaseLayerWidthDeviationQuick = settings.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_QUICK); + decreaseLayerWidthDeviationUp = settings.get(Boolean.class, DECREASE_LAYER_WIDTH_DEVIATION_UP); + unreverseVips = settings.get(Boolean.class, UNREVERSE_VIPS); + noVip = settings.get(Boolean.class, NO_VIP); + crossReduceRouting = settings.get(Boolean.class, CROSS_REDUCE_ROUTING); + crossPositionDuring = settings.get(Boolean.class, CROSS_POSITION_DURING); + properCrossingClosestNode = settings.get(Boolean.class, PROPER_CROSSING_CLOSEST_NODE); + unknownCrossingNumber = settings.get(Boolean.class, UNKNOWN_CROSSING_NUMBER); // int and float settings - xAssignSweepCount = setting.get(Integer.class, X_ASSIGN_SWEEP_COUNT); - crossingSweepCount = setting.get(Integer.class, CROSSING_SWEEP_COUNT); - minEdgeAngle = setting.get(Integer.class, MIN_EDGE_ANGLE); - crossFactor = setting.get(Float.class, CROSS_FACTOR); + xAssignSweepCount = settings.get(Integer.class, X_ASSIGN_SWEEP_COUNT); + crossingSweepCount = settings.get(Integer.class, CROSSING_SWEEP_COUNT); + minEdgeAngle = settings.get(Integer.class, MIN_EDGE_ANGLE); + crossFactor = settings.get(Float.class, CROSS_FACTOR); } public int getMaxLayerLength() { @@ -579,7 +579,7 @@ private void cleanup() { nodes.clear(); longEdges.clear(); - initSettings(settings); + initSettings(); } @Override From 9f73c7011ee40ddacf9c9a8ff49cb0a38a424656 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 3 Nov 2025 13:31:01 -0800 Subject: [PATCH 23/29] AssignLayers may not converge for some cases so bail out after excessive iterations --- .../hierarchicallayout/HierarchicalLayoutManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java index 807ef2f8e25c..e1f8cdb61f87 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/src/main/java/org/graalvm/visualizer/hierarchicallayout/HierarchicalLayoutManager.java @@ -53,6 +53,7 @@ import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.IntUnaryOperator; +import java.util.logging.Level; import java.util.logging.Logger; import static org.graalvm.visualizer.settings.layout.LayoutSettings.BOTH_SORT; @@ -2360,6 +2361,7 @@ private void assignLayerUpwards() { private final SortedSet lay = new TreeSet<>(LAYER_WIDTH_COMPARATOR); private void reassignLayers() { + int iterations = 0; layers = new LayoutLayer[layerCount]; if (layerCount == 0) { return; @@ -2384,6 +2386,13 @@ private void reassignLayers() { if (layer.getMinimalWidth() < avg) { break; } + if (++iterations > 20000) { + // This algorithm is not guaranteed to converge so limit the number of iterations. Thie value + // was picked based on processing some very large graphs. The max number of iterations seen + // for a successful layout was around 1500 so 20000 was chosen as a high bound. + LOG.log(Level.INFO, "Too many iterations in assignLayers so giving up"); + break; + } layer.sort(NODE_WIDTH_COMPARATOR); if (!decreaseLayerWidthDeviationUp) { for (LayoutNode n : layer) { From 120e2795b4b3ef6a2d0ccd61cb1181208cdb54bf Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Tue, 4 Nov 2025 07:46:43 -0800 Subject: [PATCH 24/29] Fix licenses --- .../graphio/parsing/TemplateParser.java | 24 +++++++++++++++++++ .../HierarchicalLayoutManagerStressTest.java | 24 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java index 7e9e4f3dc39a..91757ac91cb4 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/TemplateParser.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2025, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.graal.compiler.graphio.parsing; import java.util.ArrayList; diff --git a/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java b/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java index 0f450b8bb686..a6b7f013c04c 100644 --- a/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java +++ b/visualizer/IdealGraphVisualizer/View/src/test/java/org/graalvm/visualizer/view/HierarchicalLayoutManagerStressTest.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2025, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 org.graalvm.visualizer.view; import jdk.graal.compiler.graphio.parsing.BinaryReader; From d6984936702b418b9c06233928df317af513d276 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Tue, 4 Nov 2025 10:21:44 -0800 Subject: [PATCH 25/29] reduce output from visualizer task --- visualizer/ci/ci.jsonnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualizer/ci/ci.jsonnet b/visualizer/ci/ci.jsonnet index 8258e32153f2..a441e78a7493 100644 --- a/visualizer/ci/ci.jsonnet +++ b/visualizer/ci/ci.jsonnet @@ -27,7 +27,7 @@ run: [ ["cd", "./compiler"], ["mx", "build" ], - ["mx", "benchmark", "dacapo:fop", "--", "-Djdk.graal.Dump=:1", "-Djdk.graal.PrintGraph=File", "-Djdk.graal.DumpPath=../IGV_Dumps"], + ["mx", "benchmark", "dacapo:fop", "--", "-Djdk.graal.Dump=:1", "-Djdk.graal.PrintGraph=File", "-Djdk.graal.DumpPath=../IGV_Dumps", "-Djdk.graal.ShowDumpFiles=false"], ["cd", "../visualizer"], ["mx", "--java-home=$TOOLS_JAVA_HOME", "build" ], ["mx", "--java-home=$TOOLS_JAVA_HOME", "igv", "-J-Digv.openfile.onstartup.and.close=../compiler/IGV_Dumps", "--nosplash"], From 2711928dff8e4d3e06a39ec33e7aba169056a5bd Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 5 Nov 2025 10:32:09 -0800 Subject: [PATCH 26/29] Sync jdk.graal.compiler.graphio.parsing --- .../graphio/parsing/BinaryReader.java | 37 ++++++- .../compiler/graphio/parsing/Builder.java | 25 +++-- .../graphio/parsing/ModelBuilder.java | 70 +++++++------- .../graphio/parsing/TemplateParser.java | 88 +++++++++++++++++ .../parsing/model/GraphDocumentVisitor.java | 96 +++++++++++++++++++ .../graphio/parsing/model/Properties.java | 19 ++-- .../graphio/parsing/BinaryReader.java | 60 ++++++------ .../compiler/graphio/parsing/Builder.java | 12 +-- .../graphio/parsing/ModelBuilder.java | 46 ++++----- .../graphio/parsing/model/Properties.java | 22 ++--- 10 files changed, 352 insertions(+), 123 deletions(-) create mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/TemplateParser.java create mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/BinaryReader.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/BinaryReader.java index 300ac259a2db..accdfb8370c8 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/BinaryReader.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/BinaryReader.java @@ -91,6 +91,8 @@ public class BinaryReader implements GraphParser, ModelControl { private static final Logger LOG = Logger.getLogger(BinaryReader.class.getName()); + static final boolean TRACE_PARSE_TIME = false; + private final Logger instLog; private final DataSource dataSource; @@ -472,15 +474,33 @@ public boolean equals(Object obj) { public static final class EnumKlass extends Klass { public final String[] values; + public final EnumValue[] enums; + private volatile int hashCode = 0; public EnumKlass(String name, String[] values) { super(name); this.values = values; + this.enums = new EnumValue[values.length]; + for (int i = 0; i < values.length; i++) { + this.enums[i] = new EnumValue(this, i); + } + } + + EnumValue get(int ordinal) { + if (ordinal >= 0 && ordinal < enums.length) { + return enums[ordinal]; + } + return new EnumValue(this, ordinal); } @Override public int hashCode() { - return super.hash * 31 + Arrays.hashCode(values); + int h = hashCode; + if (h == 0) { + h = Objects.hash(super.hashCode(), Arrays.hashCode(values)); + hashCode = h; + } + return h; } @Override @@ -646,7 +666,7 @@ private Object addPoolEntry(Class klass) throws IOException { case POOL_ENUM: { EnumKlass enumClass = readPoolObject(EnumKlass.class); int ordinal = dataSource.readInt(); - obj = new EnumValue(enumClass, ordinal); + obj = enumClass.get(ordinal); break; } case POOL_NODE_CLASS: { @@ -808,6 +828,7 @@ public GraphDocument parse() throws IOException { hashStack.push(null); boolean restart = false; + long start = System.nanoTime(); try { while (true) { // TERMINATION ARGUMENT: finite length of data source will result in // EOFException eventually. @@ -831,6 +852,11 @@ public GraphDocument parse() throws IOException { } finally { // also terminates the builder closeDanglingGroups(); + if (TRACE_PARSE_TIME) { + long end = System.nanoTime(); + System.err.println(((System.nanoTime() - timeStart) / 1_000_000) + " Parsed file in " + ((end - start) / 1_000_000) + " ms"); + } + } return builder.rootDocument(); } @@ -990,7 +1016,10 @@ private InputGraph parseGraph(String title, boolean toplevel) throws IOException } } + private static final long timeStart = System.nanoTime(); + private InputGraph parseGraph(int dumpId, String format, Object[] args, boolean toplevel) throws IOException { + long start = System.nanoTime(); InputGraph g = builder.startGraph(dumpId, format, args); try { parseProperties(); @@ -1014,6 +1043,10 @@ private InputGraph parseGraph(int dumpId, String format, Object[] args, boolean // we have to finish the graph. reporter.popContext(); g = builder.endGraph(); + if (TRACE_PARSE_TIME) { + long end = System.nanoTime(); + System.err.println(((System.nanoTime() - timeStart) / 1_000_000) + " Parsed " + dumpId + " " + String.format(format, args) + " in " + ((end - start) / 1000000) + " ms"); + } } return g; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/Builder.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/Builder.java index 2e1e46713004..ef760bf76c0f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/Builder.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/Builder.java @@ -33,6 +33,7 @@ import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; +import jdk.graal.compiler.graphio.parsing.TemplateParser.TemplatePart; import jdk.graal.compiler.graphio.parsing.model.GraphDocument; import jdk.graal.compiler.graphio.parsing.model.Group; import jdk.graal.compiler.graphio.parsing.model.InputBlock; @@ -219,16 +220,23 @@ public String toString() { final class NodeClass { public final String className; public final String nameTemplate; + private final List templateParts; public final List inputs; public final List sux; + private String shortString; NodeClass(String className, String nameTemplate, List inputs, List sux) { this.className = className; this.nameTemplate = nameTemplate; + this.templateParts = jdk.graal.compiler.graphio.parsing.TemplateParser.parseTemplate(nameTemplate); this.inputs = inputs; this.sux = sux; } + public List getTemplateParts() { + return templateParts; + } + @Override public String toString() { return className; @@ -265,13 +273,18 @@ public boolean equals(Object obj) { } String toShortString() { - int lastDot = className.lastIndexOf('.'); - String localShortName = className.substring(lastDot + 1); - if (localShortName.endsWith("Node") && !localShortName.equals("StartNode") && !localShortName.equals(CLASS_ENDNODE)) { - return localShortName.substring(0, localShortName.length() - 4); - } else { - return localShortName; + String s = shortString; + if (s == null) { + int lastDot = className.lastIndexOf('.'); + String localShortName = className.substring(lastDot + 1); + if (localShortName.endsWith("Node") && !localShortName.equals("StartNode") && !localShortName.equals(CLASS_ENDNODE)) { + s = localShortName.substring(0, localShortName.length() - 4); + } else { + s = localShortName; + } + shortString = s; } + return shortString; } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/ModelBuilder.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/ModelBuilder.java index d13062bdf003..1b590b2b5b72 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/ModelBuilder.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/ModelBuilder.java @@ -47,8 +47,6 @@ import java.util.Objects; import java.util.Set; import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; @@ -662,6 +660,14 @@ public void endNode(int nodeId) { PROPNAME_ID, PROPNAME_IDX, PROPNAME_BLOCK))); + private static boolean isSystemProperty(String key) { + return switch (key) { + case PROPNAME_HAS_PREDECESSOR, PROPNAME_NAME, PROPNAME_CLASS, PROPNAME_ID, PROPNAME_IDX, PROPNAME_BLOCK -> + true; + default -> false; + }; + } + @Override public void setGroupName(String name, String shortName) { assert folder instanceof Group; @@ -684,7 +690,7 @@ protected final void reportProgress() { @Override public void setNodeName(NodeClass nodeClass) { assert currentNode != null; - getProperties().setProperty(PROPNAME_NAME, createName(nodeClass, nodeEdges, nodeClass.nameTemplate)); + getProperties().setProperty(PROPNAME_NAME, createName(nodeClass, nodeEdges)); getProperties().setProperty(PROPNAME_CLASS, nodeClass.className); switch (nodeClass.className) { case "BeginNode": @@ -696,35 +702,38 @@ public void setNodeName(NodeClass nodeClass) { } } - static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\{([pi])#([a-zA-Z0-9$_]+)(/([lms]))?}"); - - private String createName(NodeClass nodeClass, List edges, String template) { - if (template.isEmpty()) { + private String createName(NodeClass nodeClass, List edges) { + if (nodeClass.nameTemplate.isEmpty()) { return nodeClass.toShortString(); } - Matcher m = TEMPLATE_PATTERN.matcher(template); - StringBuilder sb = new StringBuilder(); + + StringBuilder sb = new StringBuilder(nodeClass.nameTemplate.length()); Properties p = getProperties(); - while (m.find()) { - String name = m.group(2); - String type = m.group(1); - String result; + List templateParts = nodeClass.getTemplateParts(); + for (TemplateParser.TemplatePart template : templateParts) { + if (!template.isReplacement) { + sb.append(template.value); + continue; + } + String name = template.name; + String type = template.type; switch (type) { case "i": - StringBuilder inputString = new StringBuilder(); + boolean first = true; for (EdgeInfo edge : edges) { if (edge.label.startsWith(name) && (name.length() == edge.label.length() || edge.label.charAt(name.length()) == '[')) { - if (inputString.length() > 0) { - inputString.append(", "); + if (!first) { + sb.append(", "); } - inputString.append(edge.from); + first = false; + sb.append(edge.from); } } - result = inputString.toString(); break; case "p": Object prop = p.get(name); - String length = m.group(4); + String length = template.length; + String result; if (prop == null) { result = "?"; } else if (length != null && prop instanceof LengthToString lengthProp) { @@ -735,36 +744,21 @@ private String createName(NodeClass nodeClass, List edges, String temp case "m": result = lengthProp.toString(Length.M); break; - default: case "l": + default: result = lengthProp.toString(Length.L); break; } } else { result = prop.toString(); } + sb.append(result); break; default: - result = "#?#"; + sb.append("#?#"); break; } - - // Escape '\' and '$' to not interfere with the regular expression. - StringBuilder newResult = new StringBuilder(); - for (int i = 0; i < result.length(); ++i) { - char c = result.charAt(i); - if (c == '\\') { - newResult.append("\\\\"); - } else if (c == '$') { - newResult.append("\\$"); - } else { - newResult.append(c); - } - } - result = newResult.toString(); - m.appendReplacement(sb, result); } - m.appendTail(sb); return sb.toString(); } @@ -775,7 +769,7 @@ public void setNodeProperty(String key, Object value) { assert currentNode != null; String k = key; if (!(value instanceof InputGraph)) { - if (SYSTEM_PROPERTIES.contains(key)) { + if (isSystemProperty(key)) { k = NOT_DATA + k; } setProperty(k, value); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/TemplateParser.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/TemplateParser.java new file mode 100644 index 000000000000..91757ac91cb4 --- /dev/null +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/TemplateParser.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2025, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.graal.compiler.graphio.parsing; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TemplateParser { + private static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\{([pi])#([a-zA-Z0-9$_]+)(/([lms]))?}"); + + public static List parseTemplate(String template) { + List parts = new ArrayList<>(); + Matcher m = TEMPLATE_PATTERN.matcher(template); + int lastEnd = 0; + while (m.find()) { + if (m.start() > lastEnd) { + parts.add(new TemplatePart(template.substring(lastEnd, m.start()))); + } + String name = m.group(2); + String type = m.group(1); + switch (type) { + case "i": + parts.add(new TemplatePart(name, type, null)); + break; + case "p": + String length = m.group(4); + parts.add(new TemplatePart(name, type, length)); + break; + default: + parts.add(new TemplatePart("#?#")); + break; + } + lastEnd = m.end(); + } + if (lastEnd < template.length()) { + parts.add(new TemplatePart(template.substring(lastEnd))); + } + return parts; + } + + public static class TemplatePart { + public final String value; + public final boolean isReplacement; + public final String name; + public final String type; + public final String length; + + public TemplatePart(String name, String type, String length) { + this.name = name; + this.type = type; + this.length = length; + this.value = null; + this.isReplacement = true; + } + + public TemplatePart(String value) { + this.value = value; + this.isReplacement = false; + name = null; + type = null; + length = null; + } + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java new file mode 100644 index 000000000000..fa99503c576e --- /dev/null +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/GraphDocumentVisitor.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013, 2024, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.graal.compiler.graphio.parsing.model; + +import java.util.function.Consumer; + +/** + * Visitor interface to traverse the various elements of the {@link GraphDocument} tree. Traversal + * can be stopped early by returning {@code false} from any of the {@code visit} methods. + */ +public interface GraphDocumentVisitor { + + static void visitAll(GraphDocument doc, Consumer visit) { + GraphDocumentVisitor visitor = inputGraph -> { + visit.accept(inputGraph); + return true; + }; + visitor.visit(doc); + } + + /** + * Visits a {@link Folder} in the graph document, which could be the top-level + * {@link GraphDocument} or a nested {@link Group}. + *

+ * The default implementation visits all elements in order, stopping if + * {@link #visit(FolderElement)} returns false for any of them. + */ + default boolean visit(Folder folder) { + for (FolderElement elem : folder.getElements()) { + if (!visit(elem)) { + return false; + } + } + return true; + } + + /** + * Visits an {@link InputGraph}. Implementors can choose whether to stop at the outermost level + * or also consider nested subgraphs. + */ + boolean visit(InputGraph inputGraph); + + /** + * Visits a {@link Group}. The default implementation delegates to {@link #visit(Folder)}. + */ + default boolean visit(Group g) { + return visit((Folder) g); + } + + /** + * Visits a {@link GraphDocument}. The default implementation delegates to + * {@link #visit(Folder)}. + */ + default boolean visit(GraphDocument document) { + return visit((Folder) document); + } + + /** + * Visits a {@link FolderElement}. The default implementation delegates to the {@code visit} + * version corresponding to the concrete type of {@code element}. + */ + default boolean visit(FolderElement element) { + if (element instanceof Group group) { + return visit(group); + } + if (element instanceof InputGraph inputGraph) { + return visit(inputGraph); + } + if (element instanceof Folder folder) { + return visit(folder); + } + return true; + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java index 71b78465613c..61ad2ab8fcd7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/parsing/model/Properties.java @@ -288,9 +288,13 @@ public LinkedHashMapProperties() { } public LinkedHashMapProperties(Properties p) { - this(p.size()); - for (Property prop : p) { - map.put(prop.getName(), prop.getValue()); + if (p instanceof LinkedHashMapProperties hash) { + map = new LinkedHashMap<>(hash.map); + } else { + map = new LinkedHashMap<>(p.size()); + for (Property prop : p) { + map.put(prop.getName(), prop.getValue()); + } } } @@ -339,6 +343,7 @@ public boolean equals(Object o) { return false; } } + return true; } return true; } @@ -511,10 +516,10 @@ protected final int makeHash() { int hash = 5; for (Property prop : this) { hash = hash ^ (Property.makeHash(prop.getName(), prop.getValue())); // position affected - // hash would - // violate - // equal/hash - // contract + // hash would + // violate + // equal/hash + // contract } return hash; } diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java index 9af593eb0ebd..accdfb8370c8 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/BinaryReader.java @@ -24,31 +24,6 @@ */ package jdk.graal.compiler.graphio.parsing; -import jdk.graal.compiler.graphio.parsing.Builder.Length; -import jdk.graal.compiler.graphio.parsing.Builder.LengthToString; -import jdk.graal.compiler.graphio.parsing.Builder.ModelControl; -import jdk.graal.compiler.graphio.parsing.Builder.Node; -import jdk.graal.compiler.graphio.parsing.Builder.NodeClass; -import jdk.graal.compiler.graphio.parsing.Builder.Port; -import jdk.graal.compiler.graphio.parsing.Builder.TypedPort; -import jdk.graal.compiler.graphio.parsing.model.GraphDocument; -import jdk.graal.compiler.graphio.parsing.model.Group; -import jdk.graal.compiler.graphio.parsing.model.InputGraph; - -import java.io.EOFException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.BEGIN_GRAPH; import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.BEGIN_GROUP; import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.CLOSE_GROUP; @@ -76,6 +51,31 @@ import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.PROPERTY_TRUE; import static jdk.graal.compiler.graphio.parsing.BinaryStreamDefs.STREAM_PROPERTIES; +import java.io.EOFException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; + +import jdk.graal.compiler.graphio.parsing.Builder.Length; +import jdk.graal.compiler.graphio.parsing.Builder.LengthToString; +import jdk.graal.compiler.graphio.parsing.Builder.ModelControl; +import jdk.graal.compiler.graphio.parsing.Builder.Node; +import jdk.graal.compiler.graphio.parsing.Builder.NodeClass; +import jdk.graal.compiler.graphio.parsing.Builder.Port; +import jdk.graal.compiler.graphio.parsing.Builder.TypedPort; +import jdk.graal.compiler.graphio.parsing.model.GraphDocument; +import jdk.graal.compiler.graphio.parsing.model.Group; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; + /** * The class reads the Graal binary dump format. All model object creation or property value * computation / logic is delegated to the {@link ModelBuilder} class. While the BinaryReader should @@ -852,9 +852,9 @@ public GraphDocument parse() throws IOException { } finally { // also terminates the builder closeDanglingGroups(); - long end = System.nanoTime(); if (TRACE_PARSE_TIME) { - System.err.println((System.currentTimeMillis() - timeStart) + " Parsed file in " + ((end - start) / 1000000) + " ms"); + long end = System.nanoTime(); + System.err.println(((System.nanoTime() - timeStart) / 1_000_000) + " Parsed file in " + ((end - start) / 1_000_000) + " ms"); } } @@ -1016,7 +1016,7 @@ private InputGraph parseGraph(String title, boolean toplevel) throws IOException } } - private static final long timeStart = System.currentTimeMillis(); + private static final long timeStart = System.nanoTime(); private InputGraph parseGraph(int dumpId, String format, Object[] args, boolean toplevel) throws IOException { long start = System.nanoTime(); @@ -1043,9 +1043,9 @@ private InputGraph parseGraph(int dumpId, String format, Object[] args, boolean // we have to finish the graph. reporter.popContext(); g = builder.endGraph(); - long end = System.nanoTime(); if (TRACE_PARSE_TIME) { - System.err.println((System.currentTimeMillis() - timeStart) + " Parsed " + dumpId + " " + String.format(format, args) + " in " + ((end - start) / 1000000) + " ms"); + long end = System.nanoTime(); + System.err.println(((System.nanoTime() - timeStart) / 1_000_000) + " Parsed " + dumpId + " " + String.format(format, args) + " in " + ((end - start) / 1000000) + " ms"); } } return g; diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java index e329b370c176..ef760bf76c0f 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/Builder.java @@ -25,6 +25,12 @@ package jdk.graal.compiler.graphio.parsing; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; import jdk.graal.compiler.graphio.parsing.TemplateParser.TemplatePart; @@ -34,12 +40,6 @@ import jdk.graal.compiler.graphio.parsing.model.InputGraph; import jdk.graal.compiler.graphio.parsing.model.Properties; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; - /** * Interface for building IGV data from the stream. */ diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java index 704fe64572d2..1b590b2b5b72 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/ModelBuilder.java @@ -25,19 +25,15 @@ package jdk.graal.compiler.graphio.parsing; -import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; -import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; -import jdk.graal.compiler.graphio.parsing.model.Folder; -import jdk.graal.compiler.graphio.parsing.model.FolderElement; -import jdk.graal.compiler.graphio.parsing.model.GraphClassifier; -import jdk.graal.compiler.graphio.parsing.model.GraphDocument; -import jdk.graal.compiler.graphio.parsing.model.Group; -import jdk.graal.compiler.graphio.parsing.model.InputBlock; -import jdk.graal.compiler.graphio.parsing.model.InputEdge; -import jdk.graal.compiler.graphio.parsing.model.InputGraph; -import jdk.graal.compiler.graphio.parsing.model.InputMethod; -import jdk.graal.compiler.graphio.parsing.model.InputNode; -import jdk.graal.compiler.graphio.parsing.model.Properties; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_BLOCK; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_CLASS; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_DUPLICATE; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_HAS_PREDECESSOR; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_ID; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_IDX; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_SHORT_NAME; +import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; import java.util.ArrayDeque; import java.util.ArrayList; @@ -52,15 +48,19 @@ import java.util.Set; import java.util.logging.Logger; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_BLOCK; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_CLASS; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_DUPLICATE; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_HAS_PREDECESSOR; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_ID; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_IDX; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_NAME; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyNames.PROPNAME_SHORT_NAME; -import static jdk.graal.compiler.graphio.parsing.model.KnownPropertyValues.CLASS_ENDNODE; +import jdk.graal.compiler.graphio.parsing.BinaryReader.EnumValue; +import jdk.graal.compiler.graphio.parsing.BinaryReader.Method; +import jdk.graal.compiler.graphio.parsing.model.Folder; +import jdk.graal.compiler.graphio.parsing.model.FolderElement; +import jdk.graal.compiler.graphio.parsing.model.GraphClassifier; +import jdk.graal.compiler.graphio.parsing.model.GraphDocument; +import jdk.graal.compiler.graphio.parsing.model.Group; +import jdk.graal.compiler.graphio.parsing.model.InputBlock; +import jdk.graal.compiler.graphio.parsing.model.InputEdge; +import jdk.graal.compiler.graphio.parsing.model.InputGraph; +import jdk.graal.compiler.graphio.parsing.model.InputMethod; +import jdk.graal.compiler.graphio.parsing.model.InputNode; +import jdk.graal.compiler.graphio.parsing.model.Properties; /** * Builds a model based on SAX-like events. The expected sequence of events is: @@ -663,7 +663,7 @@ public void endNode(int nodeId) { private static boolean isSystemProperty(String key) { return switch (key) { case PROPNAME_HAS_PREDECESSOR, PROPNAME_NAME, PROPNAME_CLASS, PROPNAME_ID, PROPNAME_IDX, PROPNAME_BLOCK -> - true; + true; default -> false; }; } diff --git a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java index b26c9c8ceb89..61ad2ab8fcd7 100644 --- a/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java +++ b/visualizer/IdealGraphVisualizer/Data/src/main/java/jdk/graal/compiler/graphio/parsing/model/Properties.java @@ -114,8 +114,7 @@ public Map toMap(Map props, Set excludeN props.put(names[i], values[i]); } } else { - P: - for (int i = 0; i < size; ++i) { + P: for (int i = 0; i < size; ++i) { String n = names[i]; if (!excludes.contains(n)) { for (String p : excludePrefixes) { @@ -314,9 +313,11 @@ public boolean equals(Object o) { if (size() != hash.size()) { return false; } - // Most Properties comparisons are for cases where they are the same or very similar - // so efficiency is fairly important to loading speed. They are commonly ordered in the - // same fashion so take advantage of that in the comparison + /* + * Most Properties comparisons are for cases where they are the same or very similar + * so efficiency is fairly important to loading speed. They are commonly ordered in + * the same fashion so take advantage of that in the comparison + */ Set> set1 = map.entrySet(); Iterator> iter1 = set1.iterator(); @@ -378,8 +379,7 @@ public Map toMap(Map props, Set excludeN if (excludes.isEmpty() && excludePrefixes.length == 0) { props.putAll(map); } else { - P: - for (Map.Entry entry : map.entrySet()) { + P: for (Map.Entry entry : map.entrySet()) { String n = entry.getKey(); if (!excludes.contains(n)) { for (String p : excludePrefixes) { @@ -769,10 +769,10 @@ public RegexpPropertyMatcher(String name, String value) { /** * Constructs a regular expression based matcher. * - * @param name name of the property to search - * @param value pattern + * @param name name of the property to search + * @param value pattern * @param entireMatch whether the matcher should only accept full matches - * @param flags flags to use to compile the pattern defined by {@code value} + * @param flags flags to use to compile the pattern defined by {@code value} */ public RegexpPropertyMatcher(String name, String value, boolean entireMatch, int flags) { if (name == null) { @@ -889,7 +889,7 @@ public T get(String key, Class clazz) { * {@link #get(java.lang.String, java.lang.Class)} will throw an exception/assertion on * non-String values. * - * @param key property key + * @param key property key * @param defValue value to be returned if the property is not defined or is {@code null} * @return String representation */ From 7019373ccc316b493f88d5c68854f1bf60c3bad0 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 5 Nov 2025 12:58:22 -0800 Subject: [PATCH 27/29] [maven-release-plugin] prepare release idealgraphvisualizer-1.23 --- visualizer/IdealGraphVisualizer/Bytecodes/pom.xml | 2 +- visualizer/IdealGraphVisualizer/ControlFlow/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Coordinator/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Data/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Difference/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Filter/pom.xml | 2 +- visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml | 2 +- visualizer/IdealGraphVisualizer/FilterWindow/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Graal/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Graph/pom.xml | 2 +- visualizer/IdealGraphVisualizer/GraphSearch/pom.xml | 2 +- visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml | 2 +- visualizer/IdealGraphVisualizer/JSONExporter/pom.xml | 2 +- visualizer/IdealGraphVisualizer/JavaSources/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Layout/pom.xml | 2 +- visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml | 2 +- visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml | 2 +- visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Settings/pom.xml | 2 +- visualizer/IdealGraphVisualizer/SettingsUI/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Shell/pom.xml | 2 +- visualizer/IdealGraphVisualizer/SourceRepository/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Upgrade/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Util/pom.xml | 2 +- visualizer/IdealGraphVisualizer/View/pom.xml | 2 +- visualizer/IdealGraphVisualizer/ViewerApi/pom.xml | 2 +- visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml | 2 +- visualizer/IdealGraphVisualizer/application/pom.xml | 2 +- visualizer/IdealGraphVisualizer/branding/pom.xml | 2 +- visualizer/IdealGraphVisualizer/pom.xml | 4 ++-- 30 files changed, 31 insertions(+), 31 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml b/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml index 332dcf666dae..535bc154af55 100644 --- a/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml +++ b/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Bytecodes nbm diff --git a/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml b/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml index 5e332656f34b..6945c1cebccb 100644 --- a/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml +++ b/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 ControlFlow nbm diff --git a/visualizer/IdealGraphVisualizer/Coordinator/pom.xml b/visualizer/IdealGraphVisualizer/Coordinator/pom.xml index e14e119a607c..f3eb8074ccb2 100644 --- a/visualizer/IdealGraphVisualizer/Coordinator/pom.xml +++ b/visualizer/IdealGraphVisualizer/Coordinator/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Coordinator nbm diff --git a/visualizer/IdealGraphVisualizer/Data/pom.xml b/visualizer/IdealGraphVisualizer/Data/pom.xml index 615bc2db1273..d2f046fdb395 100644 --- a/visualizer/IdealGraphVisualizer/Data/pom.xml +++ b/visualizer/IdealGraphVisualizer/Data/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Data nbm diff --git a/visualizer/IdealGraphVisualizer/Difference/pom.xml b/visualizer/IdealGraphVisualizer/Difference/pom.xml index 4f1a24ebf11f..af5cf594a300 100644 --- a/visualizer/IdealGraphVisualizer/Difference/pom.xml +++ b/visualizer/IdealGraphVisualizer/Difference/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Difference nbm diff --git a/visualizer/IdealGraphVisualizer/Filter/pom.xml b/visualizer/IdealGraphVisualizer/Filter/pom.xml index c73b69511f59..65b26d7d0ab1 100644 --- a/visualizer/IdealGraphVisualizer/Filter/pom.xml +++ b/visualizer/IdealGraphVisualizer/Filter/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Filter nbm diff --git a/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml b/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml index f9793833da5e..9cbc149db3e2 100644 --- a/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml +++ b/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 FilterProfiles nbm diff --git a/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml b/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml index ba9fd2815d0c..9e95958674ff 100644 --- a/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml +++ b/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 FilterWindow nbm diff --git a/visualizer/IdealGraphVisualizer/Graal/pom.xml b/visualizer/IdealGraphVisualizer/Graal/pom.xml index 73a7c121f089..e8ac7f99b696 100644 --- a/visualizer/IdealGraphVisualizer/Graal/pom.xml +++ b/visualizer/IdealGraphVisualizer/Graal/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Graal nbm diff --git a/visualizer/IdealGraphVisualizer/Graph/pom.xml b/visualizer/IdealGraphVisualizer/Graph/pom.xml index 01b7e1365220..57788c3b6b72 100644 --- a/visualizer/IdealGraphVisualizer/Graph/pom.xml +++ b/visualizer/IdealGraphVisualizer/Graph/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Graph nbm diff --git a/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml b/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml index 73e3a995eeb3..49e08e7f1c76 100644 --- a/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml +++ b/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 GraphSearch nbm diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml b/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml index 7a55ac4f27dc..e0f3f439dcc6 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 HierarchicalLayout nbm diff --git a/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml b/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml index 5835f2f0f75c..a18fb56c688a 100644 --- a/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml +++ b/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 JSONExporter nbm diff --git a/visualizer/IdealGraphVisualizer/JavaSources/pom.xml b/visualizer/IdealGraphVisualizer/JavaSources/pom.xml index 06618751af2b..fdb93bf9f56b 100644 --- a/visualizer/IdealGraphVisualizer/JavaSources/pom.xml +++ b/visualizer/IdealGraphVisualizer/JavaSources/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 JavaSources nbm diff --git a/visualizer/IdealGraphVisualizer/Layout/pom.xml b/visualizer/IdealGraphVisualizer/Layout/pom.xml index 3db273db8aea..ffc55ecbcf94 100644 --- a/visualizer/IdealGraphVisualizer/Layout/pom.xml +++ b/visualizer/IdealGraphVisualizer/Layout/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Layout nbm diff --git a/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml b/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml index 1e6a06a5c2a1..e652b5d6a084 100644 --- a/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml +++ b/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 NetworkConnection nbm diff --git a/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml b/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml index 6bb4fe5555de..a3bf41975f0d 100644 --- a/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml +++ b/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 PolyglotRunner nbm diff --git a/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml b/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml index d962429d0e8a..ac78b4c034bd 100644 --- a/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml +++ b/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 SelectionCoordinator nbm diff --git a/visualizer/IdealGraphVisualizer/Settings/pom.xml b/visualizer/IdealGraphVisualizer/Settings/pom.xml index 1d1409d129b9..77eecd98a149 100644 --- a/visualizer/IdealGraphVisualizer/Settings/pom.xml +++ b/visualizer/IdealGraphVisualizer/Settings/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Settings nbm diff --git a/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml b/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml index 6fd402b57869..0fac34b4b140 100644 --- a/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml +++ b/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 SettingsUI nbm diff --git a/visualizer/IdealGraphVisualizer/Shell/pom.xml b/visualizer/IdealGraphVisualizer/Shell/pom.xml index 93610b76f742..283e98d352cd 100644 --- a/visualizer/IdealGraphVisualizer/Shell/pom.xml +++ b/visualizer/IdealGraphVisualizer/Shell/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Shell nbm diff --git a/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml b/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml index 4f2e2f616441..5770ee42bb36 100644 --- a/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml +++ b/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 SourceRepository nbm diff --git a/visualizer/IdealGraphVisualizer/Upgrade/pom.xml b/visualizer/IdealGraphVisualizer/Upgrade/pom.xml index 433fc9ac11b3..724d07ee973f 100644 --- a/visualizer/IdealGraphVisualizer/Upgrade/pom.xml +++ b/visualizer/IdealGraphVisualizer/Upgrade/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Upgrade nbm diff --git a/visualizer/IdealGraphVisualizer/Util/pom.xml b/visualizer/IdealGraphVisualizer/Util/pom.xml index 549e982c457a..a72fd3bb1c77 100644 --- a/visualizer/IdealGraphVisualizer/Util/pom.xml +++ b/visualizer/IdealGraphVisualizer/Util/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 Util nbm diff --git a/visualizer/IdealGraphVisualizer/View/pom.xml b/visualizer/IdealGraphVisualizer/View/pom.xml index f750d0bd604f..3913b730c282 100644 --- a/visualizer/IdealGraphVisualizer/View/pom.xml +++ b/visualizer/IdealGraphVisualizer/View/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 View nbm diff --git a/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml b/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml index 984688f658b1..10f6115050ef 100644 --- a/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml +++ b/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 ViewerApi nbm diff --git a/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml b/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml index 851123bf2e9f..f740b946d888 100644 --- a/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml +++ b/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 VisualizerUI nbm diff --git a/visualizer/IdealGraphVisualizer/application/pom.xml b/visualizer/IdealGraphVisualizer/application/pom.xml index 73daec8af81d..03fee47f1500 100644 --- a/visualizer/IdealGraphVisualizer/application/pom.xml +++ b/visualizer/IdealGraphVisualizer/application/pom.xml @@ -4,7 +4,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 IdealGraphVisualizer-app nbm-application diff --git a/visualizer/IdealGraphVisualizer/branding/pom.xml b/visualizer/IdealGraphVisualizer/branding/pom.xml index 4467beaa0292..7be92aff8f84 100644 --- a/visualizer/IdealGraphVisualizer/branding/pom.xml +++ b/visualizer/IdealGraphVisualizer/branding/pom.xml @@ -4,7 +4,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 IdealGraphVisualizer-branding nbm diff --git a/visualizer/IdealGraphVisualizer/pom.xml b/visualizer/IdealGraphVisualizer/pom.xml index e93d3352439d..353ebcd3ab38 100644 --- a/visualizer/IdealGraphVisualizer/pom.xml +++ b/visualizer/IdealGraphVisualizer/pom.xml @@ -3,13 +3,13 @@ IdealGraphVisualizer-parent org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23-SNAPSHOT + 1.23 pom scm:git:git@github.com:oracle/graal.git - HEAD + idealgraphvisualizer-1.23 From 4543ff4a3e5b2674cca41b0879deeba82ec71a8d Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 5 Nov 2025 12:58:23 -0800 Subject: [PATCH 28/29] [maven-release-plugin] prepare for next development iteration --- visualizer/IdealGraphVisualizer/Bytecodes/pom.xml | 2 +- visualizer/IdealGraphVisualizer/ControlFlow/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Coordinator/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Data/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Difference/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Filter/pom.xml | 2 +- visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml | 2 +- visualizer/IdealGraphVisualizer/FilterWindow/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Graal/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Graph/pom.xml | 2 +- visualizer/IdealGraphVisualizer/GraphSearch/pom.xml | 2 +- visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml | 2 +- visualizer/IdealGraphVisualizer/JSONExporter/pom.xml | 2 +- visualizer/IdealGraphVisualizer/JavaSources/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Layout/pom.xml | 2 +- visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml | 2 +- visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml | 2 +- visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Settings/pom.xml | 2 +- visualizer/IdealGraphVisualizer/SettingsUI/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Shell/pom.xml | 2 +- visualizer/IdealGraphVisualizer/SourceRepository/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Upgrade/pom.xml | 2 +- visualizer/IdealGraphVisualizer/Util/pom.xml | 2 +- visualizer/IdealGraphVisualizer/View/pom.xml | 2 +- visualizer/IdealGraphVisualizer/ViewerApi/pom.xml | 2 +- visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml | 2 +- visualizer/IdealGraphVisualizer/application/pom.xml | 2 +- visualizer/IdealGraphVisualizer/branding/pom.xml | 2 +- visualizer/IdealGraphVisualizer/pom.xml | 4 ++-- 30 files changed, 31 insertions(+), 31 deletions(-) diff --git a/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml b/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml index 535bc154af55..be15f16956fe 100644 --- a/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml +++ b/visualizer/IdealGraphVisualizer/Bytecodes/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Bytecodes nbm diff --git a/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml b/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml index 6945c1cebccb..0712076399bd 100644 --- a/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml +++ b/visualizer/IdealGraphVisualizer/ControlFlow/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT ControlFlow nbm diff --git a/visualizer/IdealGraphVisualizer/Coordinator/pom.xml b/visualizer/IdealGraphVisualizer/Coordinator/pom.xml index f3eb8074ccb2..f65dab9cacf7 100644 --- a/visualizer/IdealGraphVisualizer/Coordinator/pom.xml +++ b/visualizer/IdealGraphVisualizer/Coordinator/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Coordinator nbm diff --git a/visualizer/IdealGraphVisualizer/Data/pom.xml b/visualizer/IdealGraphVisualizer/Data/pom.xml index d2f046fdb395..acee3955ce2f 100644 --- a/visualizer/IdealGraphVisualizer/Data/pom.xml +++ b/visualizer/IdealGraphVisualizer/Data/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Data nbm diff --git a/visualizer/IdealGraphVisualizer/Difference/pom.xml b/visualizer/IdealGraphVisualizer/Difference/pom.xml index af5cf594a300..ba8218b76655 100644 --- a/visualizer/IdealGraphVisualizer/Difference/pom.xml +++ b/visualizer/IdealGraphVisualizer/Difference/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Difference nbm diff --git a/visualizer/IdealGraphVisualizer/Filter/pom.xml b/visualizer/IdealGraphVisualizer/Filter/pom.xml index 65b26d7d0ab1..687291827aab 100644 --- a/visualizer/IdealGraphVisualizer/Filter/pom.xml +++ b/visualizer/IdealGraphVisualizer/Filter/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Filter nbm diff --git a/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml b/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml index 9cbc149db3e2..e8befa99cc39 100644 --- a/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml +++ b/visualizer/IdealGraphVisualizer/FilterProfiles/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT FilterProfiles nbm diff --git a/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml b/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml index 9e95958674ff..d7711ab9911f 100644 --- a/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml +++ b/visualizer/IdealGraphVisualizer/FilterWindow/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT FilterWindow nbm diff --git a/visualizer/IdealGraphVisualizer/Graal/pom.xml b/visualizer/IdealGraphVisualizer/Graal/pom.xml index e8ac7f99b696..8a22a9ee9cd3 100644 --- a/visualizer/IdealGraphVisualizer/Graal/pom.xml +++ b/visualizer/IdealGraphVisualizer/Graal/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Graal nbm diff --git a/visualizer/IdealGraphVisualizer/Graph/pom.xml b/visualizer/IdealGraphVisualizer/Graph/pom.xml index 57788c3b6b72..22f44dfadfd2 100644 --- a/visualizer/IdealGraphVisualizer/Graph/pom.xml +++ b/visualizer/IdealGraphVisualizer/Graph/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Graph nbm diff --git a/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml b/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml index 49e08e7f1c76..758e661390ae 100644 --- a/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml +++ b/visualizer/IdealGraphVisualizer/GraphSearch/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT GraphSearch nbm diff --git a/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml b/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml index e0f3f439dcc6..69e2910c7722 100644 --- a/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml +++ b/visualizer/IdealGraphVisualizer/HierarchicalLayout/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT HierarchicalLayout nbm diff --git a/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml b/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml index a18fb56c688a..49e3e2777bdc 100644 --- a/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml +++ b/visualizer/IdealGraphVisualizer/JSONExporter/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT JSONExporter nbm diff --git a/visualizer/IdealGraphVisualizer/JavaSources/pom.xml b/visualizer/IdealGraphVisualizer/JavaSources/pom.xml index fdb93bf9f56b..d7be69a43093 100644 --- a/visualizer/IdealGraphVisualizer/JavaSources/pom.xml +++ b/visualizer/IdealGraphVisualizer/JavaSources/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT JavaSources nbm diff --git a/visualizer/IdealGraphVisualizer/Layout/pom.xml b/visualizer/IdealGraphVisualizer/Layout/pom.xml index ffc55ecbcf94..3b07685cdde5 100644 --- a/visualizer/IdealGraphVisualizer/Layout/pom.xml +++ b/visualizer/IdealGraphVisualizer/Layout/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Layout nbm diff --git a/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml b/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml index e652b5d6a084..afc8733ae5c1 100644 --- a/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml +++ b/visualizer/IdealGraphVisualizer/NetworkConnection/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT NetworkConnection nbm diff --git a/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml b/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml index a3bf41975f0d..974e83d4b803 100644 --- a/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml +++ b/visualizer/IdealGraphVisualizer/PolyglotRunner/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT PolyglotRunner nbm diff --git a/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml b/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml index ac78b4c034bd..7f6bb161e9d7 100644 --- a/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml +++ b/visualizer/IdealGraphVisualizer/SelectionCoordinator/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT SelectionCoordinator nbm diff --git a/visualizer/IdealGraphVisualizer/Settings/pom.xml b/visualizer/IdealGraphVisualizer/Settings/pom.xml index 77eecd98a149..13403a5f037c 100644 --- a/visualizer/IdealGraphVisualizer/Settings/pom.xml +++ b/visualizer/IdealGraphVisualizer/Settings/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Settings nbm diff --git a/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml b/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml index 0fac34b4b140..af646801e461 100644 --- a/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml +++ b/visualizer/IdealGraphVisualizer/SettingsUI/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT SettingsUI nbm diff --git a/visualizer/IdealGraphVisualizer/Shell/pom.xml b/visualizer/IdealGraphVisualizer/Shell/pom.xml index 283e98d352cd..c2f9b22ddefc 100644 --- a/visualizer/IdealGraphVisualizer/Shell/pom.xml +++ b/visualizer/IdealGraphVisualizer/Shell/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Shell nbm diff --git a/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml b/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml index 5770ee42bb36..216db14f3a9e 100644 --- a/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml +++ b/visualizer/IdealGraphVisualizer/SourceRepository/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT SourceRepository nbm diff --git a/visualizer/IdealGraphVisualizer/Upgrade/pom.xml b/visualizer/IdealGraphVisualizer/Upgrade/pom.xml index 724d07ee973f..8de9d8e0cbdb 100644 --- a/visualizer/IdealGraphVisualizer/Upgrade/pom.xml +++ b/visualizer/IdealGraphVisualizer/Upgrade/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Upgrade nbm diff --git a/visualizer/IdealGraphVisualizer/Util/pom.xml b/visualizer/IdealGraphVisualizer/Util/pom.xml index a72fd3bb1c77..ec6ea755bdbd 100644 --- a/visualizer/IdealGraphVisualizer/Util/pom.xml +++ b/visualizer/IdealGraphVisualizer/Util/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT Util nbm diff --git a/visualizer/IdealGraphVisualizer/View/pom.xml b/visualizer/IdealGraphVisualizer/View/pom.xml index 3913b730c282..b92597db7c6b 100644 --- a/visualizer/IdealGraphVisualizer/View/pom.xml +++ b/visualizer/IdealGraphVisualizer/View/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT View nbm diff --git a/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml b/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml index 10f6115050ef..2af548f08787 100644 --- a/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml +++ b/visualizer/IdealGraphVisualizer/ViewerApi/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT ViewerApi nbm diff --git a/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml b/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml index f740b946d888..c58da33995ba 100644 --- a/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml +++ b/visualizer/IdealGraphVisualizer/VisualizerUI/pom.xml @@ -3,7 +3,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT VisualizerUI nbm diff --git a/visualizer/IdealGraphVisualizer/application/pom.xml b/visualizer/IdealGraphVisualizer/application/pom.xml index 03fee47f1500..054b3e57524f 100644 --- a/visualizer/IdealGraphVisualizer/application/pom.xml +++ b/visualizer/IdealGraphVisualizer/application/pom.xml @@ -4,7 +4,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT IdealGraphVisualizer-app nbm-application diff --git a/visualizer/IdealGraphVisualizer/branding/pom.xml b/visualizer/IdealGraphVisualizer/branding/pom.xml index 7be92aff8f84..ca8e24e7e885 100644 --- a/visualizer/IdealGraphVisualizer/branding/pom.xml +++ b/visualizer/IdealGraphVisualizer/branding/pom.xml @@ -4,7 +4,7 @@ org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT IdealGraphVisualizer-branding nbm diff --git a/visualizer/IdealGraphVisualizer/pom.xml b/visualizer/IdealGraphVisualizer/pom.xml index 353ebcd3ab38..ad7ced889976 100644 --- a/visualizer/IdealGraphVisualizer/pom.xml +++ b/visualizer/IdealGraphVisualizer/pom.xml @@ -3,13 +3,13 @@ IdealGraphVisualizer-parent org.graalvm.visualizer IdealGraphVisualizer-parent - 1.23 + 1.24-SNAPSHOT pom scm:git:git@github.com:oracle/graal.git - idealgraphvisualizer-1.23 + HEAD From 8039392f228ecc24244fbe99f2901cbee50c0690 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 5 Nov 2025 13:00:14 -0800 Subject: [PATCH 29/29] Update IDEALGRAPHVISUALIZER_DIST --- compiler/mx.compiler/suite.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 9b661cf9f99a..86c0b21d60cb 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -60,9 +60,10 @@ "digest" : "sha512:40c505dd03ca0bb102f1091b89b90672126922f290bd8370eef9a7afc5d9c1e7b5db08c448a0948ef46bf57d850e166813e2d68bf7b1c88a46256d839b6b0201", "packedResource": True, }, + "IDEALGRAPHVISUALIZER_DIST" : { - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/idealgraphvisualizer/idealgraphvisualizer-1.22-6cb0d3acbb1.zip"], - "digest" : "sha512:8c4795fae203bfa84c40b041fe6d0f46a89bd8b975120d28aea9483eef1c1b63ab685716c1258387c12a255560904284fd0bf9aa947f2efabc4a629148000b5d", + "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/idealgraphvisualizer/idealgraphvisualizer-1.23-4543ff4a3e5.zip"], + "digest" : "sha512:2c779c8a01ab4cc7b77e1497ca97641799bb934309ac1306ae8383ab4efdd7af50bbd1bf55438c742e4159b581e69476a2dd8023af0f105433992a35454bdbf0", "packedResource": True, },