diff --git a/.gitignore b/.gitignore
index 28321b0496eb..1433d695556d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@ bench-results.json
jmh_result.json
/vm/src/installer/dist/
visualizer/IdealGraphVisualizer/*/target/
+visualizer/C1Visualizer/*/target/
/.src-rev
*.interp
*.tokens
diff --git a/compiler/mx.compiler/mx_graal_tools.py b/compiler/mx.compiler/mx_graal_tools.py
index e1c1d355100c..5c6da176f592 100644
--- a/compiler/mx.compiler/mx_graal_tools.py
+++ b/compiler/mx.compiler/mx_graal_tools.py
@@ -26,11 +26,11 @@
from __future__ import print_function
import os
-import shutil
import re
+import shutil
import sys
-from os.path import join, exists
from argparse import ArgumentParser, REMAINDER
+from os.path import join, exists
import mx
@@ -41,7 +41,7 @@
_suite = mx.suite('compiler')
-def run_netbeans_app(app_name, jdkhome, args=None, dist=None):
+def run_netbeans_app(app_name, jdkhome, args=None, dist=None, launch_message=None):
args = [] if args is None else args
if dist is None:
dist = app_name.upper() + '_DIST'
@@ -75,12 +75,13 @@ def run_netbeans_app(app_name, jdkhome, args=None, dist=None):
if mx.get_os() == 'linux':
# Mitigates X server crashes on Linux
launch.append('-J-Dsun.java2d.xrender=false')
- print('Consider flag -J-Dsun.java2d.uiScale=2 if on a high resolution display')
- print('Consider flag -J-Xms4g -J-Xmx8g if dealing with large graphs')
+ if launch_message:
+ launch_message()
mx.run(launch+args)
-def igv(args):
- """run the Ideal Graph Visualizer
+
+def netbeans_docstring(fullname, mxname):
+ return f"""run the {fullname}
The current version is based on NetBeans 26 which officially supports JDK 17 through JDK 24. A
supported JDK will be chosen from the JDKs known to mx but it will fall back to whatever is
@@ -90,19 +91,21 @@ def igv(args):
You can directly control which JDK is used to launch IGV using
- mx igv --jdkhome /path/to/java/home
+ mx {mxname} --jdkhome /path/to/java/home
This will completely ignore any JAVA_HOME settings in mx.
- Extra NetBeans specific options can be passed as well. mx igv --help will show the
+ Extra NetBeans specific options can be passed as well. mx {mxname} --help will show the
help for the NetBeans launcher.
"""
+
+def launch_netbeans_app(fullname, distname, mxname, args, launch_message=None):
min_version = 17
max_version = 24
min_version_spec = mx.VersionSpec(str(min_version))
next_version_spec = mx.VersionSpec(str(max_version + 1))
- def _igvJdkVersionCheck(version):
+ def _netbeansJdkVersionCheck(version):
return min_version_spec <= version < next_version_spec
jdkhome = None
@@ -111,29 +114,35 @@ def _do_not_abort(msg):
pass
# try to find a fully supported version first
- jdk = mx.get_tools_jdk(versionCheck=_igvJdkVersionCheck, versionDescription=f'IGV prefers JDK {min_version} through JDK {max_version}', abortCallback=_do_not_abort)
+ jdk = mx.get_tools_jdk(versionCheck=_netbeansJdkVersionCheck, versionDescription=f'{fullname} prefers JDK {min_version} through JDK {max_version}', abortCallback=_do_not_abort)
if jdk is None:
# try any JDK
jdk = mx.get_jdk()
if jdk:
jdkhome = jdk.home
- mx.log(f'Launching IGV with {jdkhome}')
- if not _igvJdkVersionCheck(jdk.version):
- mx.warn(f'{jdk.home} is not an officially supported JDK for IGV.')
+ mx.log(f'Launching {fullname} with {jdkhome}')
+ if not _netbeansJdkVersionCheck(jdk.version):
+ mx.warn(f'{jdk.home} is not an officially supported JDK.')
mx.warn(f'If you experience any problems try to use an LTS release between JDK {min_version} and JDK {max_version} instead.')
- mx.warn(f'mx help igv provides more details.')
+ mx.warn(f'mx help {mxname} provides more details.')
- run_netbeans_app('IdealGraphVisualizer', jdkhome, args=args, dist='IDEALGRAPHVISUALIZER_DIST')
+ run_netbeans_app(distname, jdkhome, args=args, dist=f'{distname.upper()}_DIST', launch_message=launch_message)
+
+def igv(args):
+ def help_message():
+ print('Consider flag -J-Dsun.java2d.uiScale=2 if on a high resolution display')
+ print('Consider flag -J-Xms4g -J-Xmx8g if dealing with large graphs')
+
+ launch_netbeans_app('Ideal Graph Visualizer', 'IdealGraphVisualizer', 'igv', args, launch_message=help_message)
+
+igv.__doc__ = netbeans_docstring('Ideal Graph Visualizer', 'igv')
def c1visualizer(args):
- """run the C1 Compiler Visualizer"""
- v8u40 = mx.VersionSpec("1.8.0_40")
- v12 = mx.VersionSpec("12")
- def _c1vJdkVersionCheck(version):
- return v8u40 <= version < v12
- jdkhome = mx.get_jdk(_c1vJdkVersionCheck, versionDescription='(JDK that is >= 1.8.0u40 and <= 11 which can be specified via EXTRA_JAVA_HOMES or --extra-java-homes)', purpose="running C1 Visualizer").home
- run_netbeans_app('C1Visualizer', jdkhome, args() if callable(args) else args)
+ launch_netbeans_app('C1 Visualizer', 'C1Visualizer', 'c1visualizer', args)
+
+c1visualizer.__doc__ = netbeans_docstring('C1 Visualizer', 'c1visualizer')
+
def hsdis(args, copyToDir=None):
"""download the hsdis library and copy it to a specific dir or to the current JDK
diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py
index 8a2fd4b32570..d7107c1f6d44 100644
--- a/compiler/mx.compiler/suite.py
+++ b/compiler/mx.compiler/suite.py
@@ -58,8 +58,8 @@
},
"C1VISUALIZER_DIST" : {
- "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/c1visualizer/c1visualizer-1.10.zip"],
- "digest" : "sha512:40c505dd03ca0bb102f1091b89b90672126922f290bd8370eef9a7afc5d9c1e7b5db08c448a0948ef46bf57d850e166813e2d68bf7b1c88a46256d839b6b0201",
+ "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/c1visualizer/c1visualizer-1.13-3413409cce0.zip"],
+ "digest" : "sha512:176dcef9447f1760f70ec4da50b2f742e786fc3db6af9db9d699c303ecfe0e470deb3bb32120123cb93a0073f4f31cecffde2a7860edcf514dce9894d6df25c4",
"packedResource": True,
},
diff --git a/visualizer/C1Visualizer.md b/visualizer/C1Visualizer.md
new file mode 100644
index 000000000000..79b4d22aaa08
--- /dev/null
+++ b/visualizer/C1Visualizer.md
@@ -0,0 +1,32 @@
+# Readme for C1Visualizer
+
+
+# Developing the C1Visualizer
+
+C1Visualizer is based on Netbeans 26 but can be often be worked on with later releases or with any
+IDE that supports Maven. Care must be taken not to commmit anything that would keep it from working
+with 26 so any automatic changes to property file updates by later NetBeans versions shouldn't be
+pushed. The packaged product is built by:
+```
+cd C1Visualizer
+mvn package
+```
+
+# Regenerating the cfg file parser
+
+The cfg file parser is based on CoCo/R which hasn't been updated since 2018 and doesn't support
+large files. For simplicity, it has been checked in and some bugs with handling of large files were
+fixed. It can be regenerated by getting Coco.jar from https://ssw.jku.at/Research/Projects/Coco and
+running the following command line. Note that still will overwrite any locals fixes but this should
+never be necessary.
+
+```
+java -jar Coco.jar -o CompilationModel/src/main/java/at/ssw/visualizer/parser \
+ -package at.ssw.visualizer.parser CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilerOutput.atg
+```
+
+# Releasing a new version
+
+As this is now maven based, `mvn -B release:prepare` is used to update to new versions which will automatically bump the module versions.
+
+The resulting zip file will be in `C1Visualizer/application/target`.
diff --git a/visualizer/C1Visualizer/BlockView/pom.xml b/visualizer/C1Visualizer/BlockView/pom.xml
new file mode 100644
index 000000000000..1649a167cbdf
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/pom.xml
@@ -0,0 +1,97 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ BlockView
+ 1.14-SNAPSHOT
+ nbm
+ BlockView
+
+ UTF-8
+
+
+
+ at.ssw.visualizer
+ VisualizerUI
+ ${project.version}
+
+
+ at.ssw.visualizer
+ CompilationModel
+ ${project.version}
+
+
+ org.netbeans.api
+ org-openide-explorer
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-loaders
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-nodes
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-windows
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.BlockView
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/BlockTableModel.java b/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/BlockTableModel.java
new file mode 100644
index 000000000000..8dab66ee7a06
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/BlockTableModel.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.block.view;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.table.AbstractTableModel;
+
+/**
+ * TableModel containing the blocks of the currently selected view
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+public class BlockTableModel extends AbstractTableModel {
+
+ public static final int BLOCK_TABLE_NAME_COL_IDX = 0;
+ public static final int BLOCK_TABLE_BCI_COL_IDX = 1;
+ public static final int BLOCK_TABLE_FLAGS_COL_IDX = 2;
+ public static final int BLOCK_TABLE_LOOP_DEPTH_COL_IDX = 3;
+ public static final int BLOCK_TABLE_LOOP_INDEX_COL_IDX = 4;
+ public static final int BLOCK_TABLE_DOMINATOR_COL_IDX = 5;
+ public static final int BLOCK_TABLE_PREDECESSORS_COL_IDX = 6;
+ public static final int BLOCK_TABLE_SUCCESSORS_COL_IDX = 7;
+ public static final int BLOCK_TABLE_XHANDLERS_COL_IDX = 8;
+ public static final int BLOCK_TABLE_PROBABILITY_COL_IDX = 9;
+
+ public static final String[] COLUMN_NAMES = new String[]{"Name", "BCI", "Flags", "Loop Depth", "Loop Index", "Dominator", "Predecessors", "Successors", "XHandlers", "Probability"};
+ public static final int[] COLUMN_WIDTHS = new int[]{60, 60, 60, 80, 80, 60, 120, 120, 120};
+
+ private List blocks = Collections.emptyList();
+
+ public void setControlFlowGraph(ControlFlowGraph cfg) {
+ if (cfg == null) {
+ blocks = Collections.emptyList();
+ } else {
+ blocks = cfg.getBasicBlocks();
+ }
+ fireTableDataChanged();
+ }
+
+ public int getRowCount() {
+ return blocks.size();
+ }
+
+ public int getColumnCount() {
+ return COLUMN_NAMES.length;
+ }
+
+ @Override
+ public String getColumnName(int column) {
+ return COLUMN_NAMES[column];
+ }
+
+ public Object getValueAt(int row, int column) {
+ BasicBlock block = blocks.get(row);
+ switch (column) {
+ case BLOCK_TABLE_NAME_COL_IDX:
+ return block.getName();
+ case BLOCK_TABLE_BCI_COL_IDX:
+ return "[" + block.getFromBci() + ", " + block.getToBci() + "]";
+ case BLOCK_TABLE_FLAGS_COL_IDX:
+ return formatFlags(block.getFlags());
+ case BLOCK_TABLE_LOOP_DEPTH_COL_IDX:
+ return Integer.toString(block.getLoopDepth());
+ case BLOCK_TABLE_LOOP_INDEX_COL_IDX:
+ return block.getLoopDepth() > 0 ? Integer.toString(block.getLoopIndex()) : "";
+ case BLOCK_TABLE_DOMINATOR_COL_IDX:
+ return block.getDominator() != null ? block.getDominator().getName() : "";
+ case BLOCK_TABLE_PREDECESSORS_COL_IDX:
+ return formatBlocks(block.getPredecessors());
+ case BLOCK_TABLE_SUCCESSORS_COL_IDX:
+ return formatBlocks(block.getSuccessors());
+ case BLOCK_TABLE_XHANDLERS_COL_IDX:
+ return formatBlocks(block.getXhandlers());
+ case BLOCK_TABLE_PROBABILITY_COL_IDX:
+ return Double.isNaN(block.getProbability()) ? "" : (Double)block.getProbability();
+ default:
+ throw new Error("invalid column");
+ }
+ }
+
+ @Override
+ public Class> getColumnClass(int columnIndex) {
+ if (blocks.isEmpty()) {
+ return Object.class;
+ }
+ return getValueAt(0, columnIndex).getClass();
+ }
+
+ private String formatFlags(List flags) {
+ StringBuilder sb = new StringBuilder();
+ String prefix = "";
+ for (String flag : flags) {
+ sb.append(prefix).append(flag);
+ prefix = ", ";
+ }
+ return sb.toString();
+ }
+
+ private String formatBlocks(List blocks) {
+ StringBuilder sb = new StringBuilder();
+ String prefix = "";
+ for (BasicBlock block : blocks) {
+ sb.append(prefix).append(block.getName());
+ prefix = ", ";
+ }
+ return sb.toString();
+ }
+}
diff --git a/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/BlockViewTopComponent.java b/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/BlockViewTopComponent.java
new file mode 100644
index 000000000000..8e0109534fda
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/BlockViewTopComponent.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.block.view;
+
+import at.ssw.visualizer.core.selection.Selection;
+import at.ssw.visualizer.core.selection.SelectionManager;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.awt.BorderLayout;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.swing.BorderFactory;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * TopComponent which displays the BlockView.
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+final class BlockViewTopComponent extends TopComponent {
+ private ControlFlowGraph curCFG;
+ private BasicBlock[] curBlocks;
+
+ private JTable blockTable;
+ private BlockTableModel tableModel;
+ private boolean selectionUpdating;
+
+ private BlockViewTopComponent() {
+ setName("Blocks");
+ setToolTipText("List of Blocks");
+
+ tableModel = new BlockTableModel();
+ blockTable = new JTable(tableModel);
+ blockTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ blockTable.setRowMargin(0);
+ blockTable.getColumnModel().setColumnMargin(0);
+ blockTable.setShowGrid(false);
+ blockTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+ for (int i = 0; i < BlockTableModel.COLUMN_WIDTHS.length; i++) {
+ blockTable.getColumnModel().getColumn(i).setPreferredWidth(BlockTableModel.COLUMN_WIDTHS[i]);
+ }
+ blockTable.getSelectionModel().addListSelectionListener(listSelectionListener);
+
+ // sorting
+ TableRowSorter sorter = new TableRowSorter(blockTable.getModel());
+ sorter.setComparator(BlockTableModel.BLOCK_TABLE_NAME_COL_IDX, new Comparator() {
+
+ @Override
+ public int compare(String block1, String block2) {
+ if (block1.charAt(0) == 'B' && block2.charAt(0)=='B') {
+ try {
+ return Integer.parseUnsignedInt(block1.substring(1)) - Integer.parseUnsignedInt(block2.substring(1));
+ } catch(NumberFormatException e) {
+ // fall-back to string
+ }
+ }
+ return block1.compareTo(block2);
+ }
+ });
+ blockTable.setRowSorter(sorter);
+
+ JScrollPane scrollPane = new JScrollPane(blockTable);
+ scrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
+ scrollPane.setBorder(BorderFactory.createEmptyBorder());
+ setLayout(new BorderLayout());
+ add(scrollPane);
+ }
+
+ @Override
+ protected void componentShowing() {
+ super.componentShowing();
+ SelectionManager.getDefault().addChangeListener(selectionChangeListener);
+ updateContent();
+ }
+
+ @Override
+ protected void componentHidden() {
+ super.componentHidden();
+ SelectionManager.getDefault().removeChangeListener(selectionChangeListener);
+ selectionUpdating = true;
+ curCFG = null;
+ curBlocks = null;
+ tableModel.setControlFlowGraph(null);
+ selectionUpdating = false;
+ }
+
+
+ private ChangeListener selectionChangeListener = new ChangeListener() {
+ public void stateChanged(ChangeEvent event) {
+ updateContent();
+ }
+ };
+
+ protected void updateContent() {
+ if (selectionUpdating) {
+ return;
+ }
+ selectionUpdating = true;
+ Selection selection = SelectionManager.getDefault().getCurSelection();
+ ControlFlowGraph newCFG = selection.get(ControlFlowGraph.class);
+ BasicBlock[] newBlocks = selection.get(BasicBlock[].class);
+
+ if (curCFG != newCFG) {
+ // This resets a user-defined sorting.
+ tableModel.setControlFlowGraph(newCFG);
+ curBlocks = null;
+ }
+
+ if (newBlocks != null) {
+ if(newBlocks.length == 0) {
+ blockTable.clearSelection();
+ } else if (!Arrays.equals(curBlocks, newBlocks)) {
+ Map blockNames = new HashMap();
+ for (BasicBlock block : newBlocks) {
+ blockNames.put(block.getName(), block);
+ }
+
+ blockTable.clearSelection();
+ for (int i = blockTable.getModel().getRowCount() - 1; i >= 0; i--) {
+ BasicBlock block = blockNames.get(blockTable.getValueAt(i, 0));
+ if (block != null) {
+ blockTable.addRowSelectionInterval(i, i);
+ blockTable.scrollRectToVisible(blockTable.getCellRect(i, 0, true));
+ }
+ }
+ }
+ }
+ curCFG = newCFG;
+ curBlocks = newBlocks;
+ selectionUpdating = false;
+ }
+
+
+ private ListSelectionListener listSelectionListener = new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent event) {
+ updateSelection();
+ }
+ };
+
+ private void updateSelection() {
+ if (selectionUpdating) {
+ return;
+ }
+ selectionUpdating = true;
+
+ List blocks = new ArrayList();
+ for (int i = 0; i < blockTable.getModel().getRowCount(); i++) {
+ if (blockTable.getSelectionModel().isSelectedIndex(i)) {
+ blocks.add(curCFG.getBasicBlockByName((String) blockTable.getValueAt(i, 0)));
+ }
+ }
+
+ curBlocks = blocks.toArray(new BasicBlock[blocks.size()]);
+ Selection selection = SelectionManager.getDefault().getCurSelection();
+ selection.put(curBlocks);
+
+ selectionUpdating = false;
+ }
+
+ //
+ private static final String PREFERRED_ID = "BlockViewTopComponent";
+ private static BlockViewTopComponent instance;
+
+ public static synchronized BlockViewTopComponent getDefault() {
+ if (instance == null) {
+ instance = new BlockViewTopComponent();
+ }
+ return instance;
+ }
+
+ public static synchronized BlockViewTopComponent findInstance() {
+ return (BlockViewTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+ }
+
+ @Override
+ public int getPersistenceType() {
+ return TopComponent.PERSISTENCE_ALWAYS;
+ }
+
+ @Override
+ protected String preferredID() {
+ return PREFERRED_ID;
+ }
+
+ @Override
+ public Object writeReplace() {
+ return new ResolvableHelper();
+ }
+
+ static final class ResolvableHelper implements Serializable {
+ private static final long serialVersionUID = 1L;
+ public Object readResolve() {
+ return BlockViewTopComponent.getDefault();
+ }
+ }
+ //
+}
diff --git a/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/ShowBlockViewAction.java b/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/ShowBlockViewAction.java
new file mode 100644
index 000000000000..053509a9a84a
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/java/at/ssw/visualizer/block/view/ShowBlockViewAction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.block.view;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.windows.TopComponent;
+
+/**
+ * Action which shows BlockView component.
+ *
+ * @author Bernhard Stiftner
+ */
+public class ShowBlockViewAction extends AbstractAction {
+ public ShowBlockViewAction() {
+ super("Blocks View");
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ TopComponent win = BlockViewTopComponent.findInstance();
+ win.open();
+ win.requestActive();
+ }
+}
diff --git a/visualizer/C1Visualizer/BlockView/src/main/nbm/manifest.mf b/visualizer/C1Visualizer/BlockView/src/main/nbm/manifest.mf
new file mode 100644
index 000000000000..e57c53fa1021
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/nbm/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.block.view
+OpenIDE-Module-Layer: at/ssw/visualizer/block/view/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/block/view/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
diff --git a/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/BlockViewTopComponentSettings.xml b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/BlockViewTopComponentSettings.xml
new file mode 100644
index 000000000000..e9cb6e95d844
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/BlockViewTopComponentSettings.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/BlockViewTopComponentWstcref.xml b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/BlockViewTopComponentWstcref.xml
new file mode 100644
index 000000000000..66cb2b958926
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/BlockViewTopComponentWstcref.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/Bundle.properties b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/Bundle.properties
new file mode 100644
index 000000000000..01077adde15c
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=Block View
diff --git a/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/layer.xml b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/layer.xml
new file mode 100644
index 000000000000..e0243e78c1f7
--- /dev/null
+++ b/visualizer/C1Visualizer/BlockView/src/main/resources/at/ssw/visualizer/block/view/layer.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeEditor/pom.xml b/visualizer/C1Visualizer/BytecodeEditor/pom.xml
new file mode 100644
index 000000000000..dcb904953196
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/pom.xml
@@ -0,0 +1,128 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ BytecodeEditor
+ 1.14-SNAPSHOT
+ nbm
+ BytecodeEditor
+
+ UTF-8
+
+
+
+ at.ssw.visualizer
+ VisualizerUI
+ ${project.version}
+
+
+ at.ssw.visualizer
+ BytecodeModel
+ ${project.version}
+
+
+ at.ssw.visualizer
+ CompilationModel
+ ${project.version}
+
+
+ at.ssw.visualizer
+ TextEditor
+ ${project.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-editor
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-editor-fold
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-editor-lib
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-awt
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-nodes
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-text
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-ui
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-windows
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.bc
+ at.ssw.visualizer.bc.model
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditor.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditor.java
new file mode 100644
index 000000000000..b68c04331d0f
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc;
+
+import at.ssw.visualizer.texteditor.Editor;
+import org.openide.windows.CloneableTopComponent;
+
+/**
+ * Editor associated to the BCEditorSupport.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class BCEditor extends Editor {
+
+ /**
+ * Creates a new CloneableEditor for the ClonableEditorSupport.
+ *
+ * @param support ClonableEditor to attach
+ */
+ public BCEditor(BCEditorSupport support) {
+ super(support);
+ }
+
+ @Override
+ protected CloneableTopComponent createClonedObject() {
+ BCEditor editor = new BCEditor((BCEditorSupport) cloneableEditorSupport());
+ editor.setActivatedNodes(getActivatedNodes());
+ return editor;
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditorKit.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditorKit.java
new file mode 100644
index 000000000000..fd6fc653b1f1
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditorKit.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc;
+
+import at.ssw.visualizer.bc.model.BCScanner;
+import at.ssw.visualizer.texteditor.EditorKit;
+import javax.swing.text.Document;
+import org.netbeans.editor.Syntax;
+
+/**
+ * A EditorKit for the bytecode, mime type text/x-compilation-bc, providing
+ * the syntax for the bytecode.
+ *
+ * @author Alexander Reder
+ */
+public class BCEditorKit extends EditorKit {
+
+ @Override
+ public Syntax createSyntax(Document document) {
+ return new BCScanner();
+ }
+
+ /**
+ * Returns the mime type which identifies the bytecode for this EditorKit.
+ *
+ * @return the mime type from the EditorSupport (text/x-compilation-bc)
+ */
+ @Override
+ public String getContentType() {
+ return BCEditorSupport.MIME_TYPE;
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditorSupport.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditorSupport.java
new file mode 100644
index 000000000000..2f174f3f42b8
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/BCEditorSupport.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc;
+
+import at.ssw.visualizer.bc.icons.Icons;
+import at.ssw.visualizer.bc.model.BCTextBuilder;
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.texteditor.EditorSupport;
+import javax.swing.text.EditorKit;
+import javax.swing.text.StyledDocument;
+import org.openide.text.CloneableEditor;
+import org.openide.util.ImageUtilities;
+
+/**
+ * Associates an Editor to a StyledDocument.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class BCEditorSupport extends EditorSupport {
+
+ public static final String MIME_TYPE = "text/x-compilation-bc";
+
+ private Bytecodes bytecodes;
+
+ public BCEditorSupport(Bytecodes bytecodes) {
+ super(bytecodes.getControlFlowGraph());
+ this.bytecodes = bytecodes;
+ this.text = new BCTextBuilder().buildDocument(cfg);
+ }
+
+ public String getMimeType() {
+ return MIME_TYPE;
+ }
+
+ public Bytecodes getBytecodes() {
+ return bytecodes;
+ }
+
+ /**
+ * Returns the Editor associated to the EditorSupport.
+ *
+ * @return a new BCEditor
+ */
+ @Override
+ protected CloneableEditor createCloneableEditor() {
+ return new BCEditor(this);
+ }
+
+ /**
+ * Returns the document associated to the EditorSupport and the EditorKit.
+ *
+ * @param kit the EditorKit
+ * @return the new created styled document
+ */
+ @Override
+ protected StyledDocument createStyledDocument(EditorKit kit) {
+ StyledDocument doc = super.createStyledDocument(kit);
+ doc.putProperty(Bytecodes.class, bytecodes);
+ doc.putProperty(ControlFlowGraph.class, bytecodes.getControlFlowGraph());
+ return doc;
+ }
+
+ /**
+ * Returns the name of the method which will be displayed on top of the
+ * editor window.
+ *
+ * @return the method name
+ */
+ @Override
+ public String messageName() {
+ return bytecodes.getControlFlowGraph().getShortName();
+ }
+
+ @Override
+ protected String messageToolTip() {
+ return bytecodes.getControlFlowGraph().getName();
+ }
+
+ @Override
+ protected void initializeCloneableEditor(CloneableEditor editor) {
+ super.initializeCloneableEditor(editor);
+ editor.setIcon(ImageUtilities.loadImage(Icons.BYTECODE));
+ }
+
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/action/ShowBCEditorAction.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/action/ShowBCEditorAction.java
new file mode 100644
index 000000000000..633f12424599
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/action/ShowBCEditorAction.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.action;
+
+import at.ssw.visualizer.bc.BCEditor;
+import at.ssw.visualizer.bc.BCEditorSupport;
+import at.ssw.visualizer.bc.icons.Icons;
+import at.ssw.visualizer.bc.model.BytecodeModel;
+import at.ssw.visualizer.core.focus.Focus;
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import javax.swing.JOptionPane;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+import org.openide.util.actions.CookieAction;
+
+/**
+ * This class provides methods for the action to open the BytecodeEditor
+ * for an entry of the compilation menu.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public final class ShowBCEditorAction extends CookieAction {
+ /**
+ * Opens the BCEditor for the control flow graph of the active node.
+ *
+ * @param activatedNodes Nodes that are selected
+ */
+ protected void performAction(Node[] activatedNodes) {
+ BytecodeModel bcModel = Lookup.getDefault().lookup(BytecodeModel.class);
+ ControlFlowGraph cfg = activatedNodes[0].getLookup().lookup(ControlFlowGraph.class);
+ Bytecodes bytecodes = bcModel.getBytecodes(cfg);
+ if (bytecodes == null) {
+ JOptionPane.showMessageDialog(null, bcModel.noBytecodesMsg(cfg), "No bytecodes available", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+
+ if (!Focus.findEditor(BCEditor.class, bytecodes.getControlFlowGraph())) {
+ BCEditorSupport editor = new BCEditorSupport(bytecodes);
+ editor.open();
+ }
+ }
+
+ /**
+ * Returns how often an action can be performed on a selected node.
+ *
+ * @return it can be performed only one time.
+ */
+ protected int mode() {
+ return CookieAction.MODE_EXACTLY_ONE;
+ }
+
+ /**
+ * When should the BCEditor be available.
+ *
+ * @return returns true if exactely one BlockListBuilder node is selected
+ * or exactly one After Generation of HIR node is selected and there is
+ * only one BlockListerBuilder node, false otherwise.
+ */
+ @Override
+ protected boolean enable(Node[] activatedNodes) {
+ if (!super.enable(activatedNodes)) {
+ return false;
+ }
+ BytecodeModel bcModel = Lookup.getDefault().lookup(BytecodeModel.class);
+ ControlFlowGraph cfg = activatedNodes[0].getLookup().lookup(ControlFlowGraph.class);
+ return bcModel.hasBytecodes(cfg);
+ }
+
+ /**
+ * Returns the name of the action.
+ *
+ * @return name of the action
+ */
+ public String getName() {
+ return "Open Bytecodes";
+ }
+
+ /**
+ * Returns the icon of the action.
+ *
+ * @return icon of the action
+ */
+ @Override
+ protected String iconResource() {
+ return Icons.BYTECODE;
+ }
+
+ /**
+ * Specfies the cookie classes where this action should be available.
+ *
+ * @return ControlFlowGraph.class
+ */
+ protected Class[] cookieClasses() {
+ return new Class[]{ControlFlowGraph.class};
+ }
+
+ /**
+ * Returns the help context for this action.
+ *
+ * @return null, no help context available
+ */
+ public HelpCtx getHelpCtx() {
+ return null;
+ }
+
+ /**
+ * How this action should be performed.
+ *
+ * @return false, this action will be performed immediatly
+ */
+ @Override
+ protected boolean asynchronous() {
+ return false;
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/icons/Icons.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/icons/Icons.java
new file mode 100644
index 000000000000..99e696668ac0
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/icons/Icons.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.icons;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class Icons {
+ private static final String PATH = "at/ssw/visualizer/bc/icons/";
+
+ public static final String BYTECODE = PATH + "bytecode.gif";
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCScanner.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCScanner.java
new file mode 100644
index 000000000000..0adfc419777a
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCScanner.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.model;
+
+import at.ssw.visualizer.texteditor.model.Scanner;
+import org.netbeans.editor.TokenID;
+
+/**
+ * This class is used for parsing the bytecode text.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class BCScanner extends Scanner {
+ public BCScanner() {
+ super("\n\r\t ,:", BCTokenContext.contextPath);
+ }
+
+ private boolean isBlock() {
+ return expectChar('B') && expectChar(DIGIT) && expectChars(DIGIT) && expectEnd();
+ }
+
+ private boolean isBciDef() {
+ return expectChar(DIGIT) && expectChars(DIGIT) && expectEnd(':');
+ }
+
+ private boolean isBciRef() {
+ return expectChar('#') && expectChar(DIGIT) && expectChars(DIGIT) && expectEnd();
+ }
+
+ private boolean isVarRef() {
+ return expectChar('%') && expectChar(DIGIT) && expectChars(DIGIT) && expectEnd();
+ }
+
+ private boolean isBcDescription() {
+ return beforeChar(':') && expectChar(LETTER) && expectChars(LETTER_DIGIT) && expectEnd();
+ }
+
+ @Override
+ protected TokenID parseToken() {
+ findTokenBegin();
+ if (ch == EOF) {
+ return BCTokenContext.EOF_TOKEN;
+ } else if (isWhitespace()) {
+ return BCTokenContext.WHITESPACE_TOKEN;
+ } else if (isBlock()) {
+ return BCTokenContext.BLOCK_TOKEN;
+ } else if (isBciDef() || isBciRef()) {
+ return BCTokenContext.BCI_TOKEN;
+ } else if (isVarRef()) {
+ return BCTokenContext.VAR_REFERENCE_TOKEN;
+ } else if (isBcDescription()) {
+ return BCTokenContext.BC_DESCRIPTION_TOKEN;
+ } else {
+ readToWhitespace();
+ return BCTokenContext.OTHER_TOKEN;
+ }
+ }
+
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCTextBuilder.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCTextBuilder.java
new file mode 100644
index 000000000000..d3787a02f818
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCTextBuilder.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.model;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.bc.BCEditorSupport;
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.texteditor.model.BlockRegion;
+import at.ssw.visualizer.texteditor.model.FoldingRegion;
+import at.ssw.visualizer.texteditor.model.HoverParser;
+import at.ssw.visualizer.texteditor.model.Text;
+import at.ssw.visualizer.texteditor.model.TextBuilder;
+import at.ssw.visualizer.texteditor.model.TextRegion;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.netbeans.api.editor.fold.FoldType;
+import org.netbeans.editor.TokenID;
+import org.openide.util.Lookup;
+
+/**
+ * Builds the text containing the bytecode.
+ *
+ * @author Alexander Reder
+ */
+public class BCTextBuilder extends TextBuilder {
+
+ private static final FoldType KIND_BLOCK = new FoldType("...");
+
+ private static final String BLOCK_LIST_PREFIX = "BlockListBuilder ";
+
+ public BCTextBuilder() {
+ super();
+ scanner = new BCScanner();
+ }
+
+ @Override
+ public Text buildDocument(ControlFlowGraph cfg) {
+ BytecodeModel bcModel = Lookup.getDefault().lookup(BytecodeModel.class);
+ Bytecodes bytecodes = bcModel.getBytecodes(cfg);
+ bytecodes.parseBytecodes();
+
+ Compilation compilation = cfg.getCompilation();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
+
+ String name = cfg.getName();
+ if (name.startsWith(BLOCK_LIST_PREFIX)) {
+ name = name.substring(BLOCK_LIST_PREFIX.length());
+ }
+ text.append(name).append("\n");
+ text.append(dateFormat.format(compilation.getDate())).append("\n\n");
+
+ BasicBlock[] sortedBlocks = sortBlocks(cfg.getBasicBlocks());
+ if (sortedBlocks.length == 0) {
+ appendAll(bytecodes);
+ } else {
+ for(int i = 0; i < sortedBlocks.length; i++) {
+ appendBlock(sortedBlocks, bytecodes, i);
+ }
+ }
+ text.append("\n\n").append(bytecodes.getEpilogue());
+ return buildText(cfg, BCEditorSupport.MIME_TYPE);
+ }
+
+ public String buildView(ControlFlowGraph cfg, BasicBlock[] basicBlocks) {
+ BytecodeModel bcModel = Lookup.getDefault().lookup(BytecodeModel.class);
+ Bytecodes bytecodes = bcModel.getBytecodes(cfg);
+ if(bytecodes == null) {
+ return "No bytecodes available\n";
+ }
+ StringBuilder view = new StringBuilder(1024);
+ buildDocument(cfg);
+ for(BasicBlock b : basicBlocks) {
+ BlockRegion br = blocks.get(b);
+ view.append(text.substring(br.getStart(), br.getEnd()));
+ }
+ return view.toString();
+ }
+
+ private void appendAll(Bytecodes bytecodes) {
+ int fromBCI = 0;
+ int toBCI = Integer.MAX_VALUE;
+ String[] bcs = bytecodes.getBytecodes(fromBCI, toBCI).split("\n");
+ for(String s : bcs) {
+ appendBytecode(null, s);
+ }
+ }
+
+ private void appendBlock(BasicBlock[] basicBlocks, Bytecodes bytecodes, int index) {
+ int start = text.length();
+ int fromBCI = basicBlocks[index].getFromBci();
+ int toBCI = Integer.MAX_VALUE;
+ if(basicBlocks.length > (index + 1) && basicBlocks[index + 1].getFromBci() >= 0) {
+ toBCI = basicBlocks[index + 1].getFromBci();
+ }
+ appendBlockDetails(basicBlocks[index]);
+ text.append("\n");
+ int bytecodesStart = text.length();
+ String[] bcs = bytecodes.getBytecodes(fromBCI, toBCI).split("\n");
+ for(String s : bcs) {
+ appendBytecode(basicBlocks[index], s);
+ }
+ blocks.put(basicBlocks[index],
+ new BlockRegion(basicBlocks[index], start, text.length(), start, start + basicBlocks[index].getName().length()));
+ foldingRegions.add(new FoldingRegion(KIND_BLOCK, bytecodesStart - 1, text.length() - 1, false));
+ hyperlinks.put(basicBlocks[index].getName(), new TextRegion(start, start + basicBlocks[index].getName().length()));
+ }
+
+ private void appendBytecode(BasicBlock block, String bytecode) {
+ int start = text.length();
+ HoverParser p = new HoverParser(bytecode);
+ while (p.hasNext()) {
+ int pstart = text.length();
+ text.append(p.next());
+ if (p.getHover() != null) {
+ regionHovers.put(new TextRegion(pstart, text.length()), p.getHover());
+ }
+ }
+ text.append("\n");
+ scanner.setText(bytecode, 0, bytecode.length());
+ TokenID token = scanner.nextToken();
+ String tokenString;
+ while(token != null && token.getNumericID() != BCTokenContext.EOF_TOKEN_ID) {
+ tokenString = scanner.getTokenString();
+ if(token.getNumericID() == BCTokenContext.BCI_TOKEN_ID) {
+ if(scanner.getTokenString().startsWith("#")) {
+ addReference(block, tokenString, bytecode);
+ addReference(block, tokenString.substring(1, tokenString.length()), bytecode);
+ } else {
+ hoverKeys.add(tokenString);
+ hoverKeys.add('#' + tokenString);
+ addDefinition(block, tokenString, bytecode);
+ addDefinition(block, '#' + tokenString, bytecode);
+ hyperlinks.put('#' + tokenString, new TextRegion(start + scanner.getTokenOffset(), start + scanner.getOffset()));
+ }
+ } else if(token.getNumericID() == BCTokenContext.VAR_REFERENCE_TOKEN_ID) {
+ hoverKeys.add(tokenString);
+ addReference(block, tokenString, bytecode);
+ }
+ token = scanner.nextToken();
+ }
+ }
+
+ private void addReference(BasicBlock block, String key, String s) {
+ if (block == null) {
+ return;
+ }
+ if(!hoverReferences.containsKey(key)) {
+ hoverReferences.put(key, new ArrayList());
+ }
+ hoverReferences.get(key).add(block.getName() + ":\t" + s);
+ }
+
+ private void addDefinition(BasicBlock block, String key, String s) {
+ if (block == null) {
+ return;
+ }
+ hoverDefinitions.put(key, block.getName() + ":\t" + s);
+ }
+
+ @Override
+ protected void buildHighlighting() {
+ scanner.setText(text.toString(), 0, text.length());
+ TokenID token = scanner.nextToken();
+ Map> highlightings = new HashMap>();
+ while(token != null && token.getNumericID() != BCTokenContext.EOF_TOKEN_ID) {
+ String key = scanner.getTokenString();
+ switch(token.getNumericID()) {
+ case BCTokenContext.BCI_TOKEN_ID:
+ if(key.startsWith("#")) {
+ key = key.substring(1, key.length());
+ }
+ List tr = new ArrayList();
+ if(!highlightings.containsKey(key)) {
+ highlightings.put(key, tr);
+ highlightings.put('#' + key, tr);
+ }
+ highlightings.get(key).add(new TextRegion(scanner.getTokenOffset(), scanner.getOffset()));
+ break;
+ case BCTokenContext.BLOCK_TOKEN_ID:
+ case BCTokenContext.VAR_REFERENCE_TOKEN_ID:
+ if(!highlightings.containsKey(key)) {
+ highlightings.put(key, new ArrayList());
+ }
+ highlightings.get(key).add(new TextRegion(scanner.getTokenOffset(), scanner.getOffset()));
+ break;
+ }
+ token = scanner.nextToken();
+ }
+ for(String key : highlightings.keySet()) {
+ List regions = highlightings.get(key);
+ highlighting.put(key, regions.toArray(new TextRegion[regions.size()]));
+ }
+ }
+
+ /**
+ * Sorts the blocks on the basis of the starting BCI. BCIs < 0 will be
+ * placed at the end of the array.
+ *
+ * @param blocks array containing the unsorted blocks
+ * @return sorted array of blocks
+ */
+ protected BasicBlock[] sortBlocks(List blocks) {
+ List blockList = new ArrayList(blocks);
+ Collections.sort(blockList, new Comparator() {
+
+ public int compare(BasicBlock b1, BasicBlock b2) {
+ if (b1.getFromBci() >= 0 && b2.getFromBci() < 0) {
+ return -1;
+ }
+ if (b1.getFromBci() < 0 && b2.getFromBci() >= 0) {
+ return 1;
+ }
+ if(b1 != b2 && b1.getFromBci() == b2.getFromBci()) {
+ return -1;
+ }
+ return b1.getFromBci() - b2.getFromBci();
+ }
+ });
+ return blockList.toArray(new BasicBlock[blocks.size()]);
+ }
+
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCTokenContext.java b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCTokenContext.java
new file mode 100644
index 000000000000..718051890be9
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/java/at/ssw/visualizer/bc/model/BCTokenContext.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.model;
+
+import org.netbeans.editor.BaseTokenID;
+import org.netbeans.editor.TokenContext;
+import org.netbeans.editor.TokenContextPath;
+import org.netbeans.editor.TokenID;
+
+/**
+ * The token context for the scanner.
+ *
+ * @author Alexander Reder
+ */
+public class BCTokenContext extends TokenContext {
+
+ public static final int EOF_TOKEN_ID = -1;
+ public static final int WHITESPACE_TOKEN_ID = -2;
+ public static final int OTHER_TOKEN_ID = -3;
+ public static final int BCI_TOKEN_ID = 4;
+ public static final int BC_DESCRIPTION_TOKEN_ID = 5;
+ public static final int VAR_REFERENCE_TOKEN_ID = 6;
+ public static final int BLOCK_TOKEN_ID = 7;
+
+ public static final TokenID EOF_TOKEN = new BaseTokenID("eof", EOF_TOKEN_ID);
+ public static final TokenID WHITESPACE_TOKEN = new BaseTokenID("whitespace", WHITESPACE_TOKEN_ID);
+ public static final TokenID OTHER_TOKEN = new BaseTokenID("other", OTHER_TOKEN_ID);
+ public static final TokenID BCI_TOKEN = new BaseTokenID("bci", BCI_TOKEN_ID);
+ public static final TokenID BC_DESCRIPTION_TOKEN = new BaseTokenID("bytecode_description", BC_DESCRIPTION_TOKEN_ID);
+ public static final TokenID VAR_REFERENCE_TOKEN = new BaseTokenID("var_reference", VAR_REFERENCE_TOKEN_ID);
+ public static final TokenID BLOCK_TOKEN = new BaseTokenID("block", BLOCK_TOKEN_ID);
+
+ public static final BCTokenContext context = new BCTokenContext();
+ public static final TokenContextPath contextPath = context.getContextPath();
+
+ /**
+ * Initializes the token context with the prefix "bc-" and all available
+ * tokens.
+ */
+ private BCTokenContext() {
+ super("bc-");
+ addTokenID(WHITESPACE_TOKEN);
+ addTokenID(OTHER_TOKEN);
+ addTokenID(BCI_TOKEN);
+ addTokenID(BC_DESCRIPTION_TOKEN);
+ addTokenID(VAR_REFERENCE_TOKEN);
+ addTokenID(BLOCK_TOKEN);
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/nbm/manifest.mf b/visualizer/C1Visualizer/BytecodeEditor/src/main/nbm/manifest.mf
new file mode 100644
index 000000000000..6dc884109add
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/nbm/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.bc
+OpenIDE-Module-Layer: at/ssw/visualizer/bc/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/bc/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/Bundle.properties b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/Bundle.properties
new file mode 100644
index 000000000000..e1b692d69fb8
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/Bundle.properties
@@ -0,0 +1,12 @@
+OpenIDE-Module-Name=Bytecode Editor
+
+text/x-compilation-bc=Bytecodes
+bc-bci=Bytecode index
+bc-bci_reference=Bytecode index reference
+bc-bytecode_description=Bytecode description
+bc-var_reference=Variable reference
+bc-block=Block
+bc-block_reference=Block reference
+bc-whitespace=Whitespace
+bc-other=Other
+bc-default=Default
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/icons/bytecode.gif b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/icons/bytecode.gif
new file mode 100644
index 000000000000..daa9302b4d10
Binary files /dev/null and b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/icons/bytecode.gif differ
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/layer.xml b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/layer.xml
new file mode 100644
index 000000000000..6ac977f8e289
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/layer.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/model/NetBeans-BC-fontsColors.xml b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/model/NetBeans-BC-fontsColors.xml
new file mode 100644
index 000000000000..9067fc09e5a7
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeEditor/src/main/resources/at/ssw/visualizer/bc/model/NetBeans-BC-fontsColors.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeModel/pom.xml b/visualizer/C1Visualizer/BytecodeModel/pom.xml
new file mode 100644
index 000000000000..22db187991f5
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/pom.xml
@@ -0,0 +1,97 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ BytecodeModel
+ 1.14-SNAPSHOT
+ nbm
+ BytecodeModel
+
+ UTF-8
+
+
+
+ at.ssw.visualizer
+ CompilationModel
+ ${project.version}
+
+
+ org.apache.bcel
+ bcel
+ 5.2
+
+
+ org.netbeans.api
+ org-netbeans-modules-options-api
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-awt
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-filesystems
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-ui
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.bc.model
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/model/BytecodeModel.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/model/BytecodeModel.java
new file mode 100644
index 000000000000..8f5c6f1285ad
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/model/BytecodeModel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.model;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+
+/**
+ * Entry point for the public bytecodes data model.
+ *
+ * @author Christian Wimmer
+ */
+public interface BytecodeModel {
+ /**
+ * Checks if bytecodes can be available for a control flow graph, i.e. if
+ * the control flow graph is either from the early bytecode parsing phase
+ * of the compiler, or no method inlining was performed.
+ *
+ * This does not imply that {link #getBytecodes()} returns true for this
+ * control flow graph. It is possible that the class is not in the
+ * classpath specified in the visualizer options.
+ *
+ * @return returns true if a BlockListBuilder node is selected
+ * or a After Generation of HIR node is selected and there is
+ * only one BlockListerBuilder node, false otherwise.
+ */
+ public boolean hasBytecodes(ControlFlowGraph cfg);
+
+ /**
+ * Gets the bytecodes for a control flow graph.
+ *
+ * @return the bytecodes, or null if not available.
+ */
+ public Bytecodes getBytecodes(ControlFlowGraph cfg);
+
+ /**
+ * Returns a human-readable message that explains why no bytecodes are
+ * available for the specified control flow graph.
+ */
+ public String noBytecodesMsg(ControlFlowGraph cfg);
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodeModelImpl.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodeModelImpl.java
new file mode 100644
index 000000000000..a36468c84826
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodeModelImpl.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.modelimpl;
+
+import at.ssw.visualizer.bc.model.BytecodeModel;
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.CompilationElement;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.Repository;
+
+/**
+ * This class holds the classpaths and the method bytecodes.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class BytecodeModelImpl implements BytecodeModel {
+
+ private String[] classPaths;
+ private Map loadedBytecodes;
+
+ /**
+ * Initializes a BytecodeModel.
+ */
+ public BytecodeModelImpl() {
+ loadClassPaths();
+
+ // Use a synchronized map to avoid all possible threading issues.
+ // Use a weak map because elements are never removed explicitly.
+ loadedBytecodes = Collections.synchronizedMap(new WeakHashMap());
+ }
+
+ /** The prefix of all control flow graphs in the early bytecode parsing phase of the compiler. */
+ private static final String BLOCK_LIST_PREFIX = "BlockListBuilder ";
+
+ private ControlFlowGraph getBlockListCFG(ControlFlowGraph cfg) {
+ if (cfg.getBytecodes() != null) {
+ return cfg;
+ }
+ if (cfg.getName().startsWith(BLOCK_LIST_PREFIX)) {
+ return cfg;
+ }
+
+ ControlFlowGraph result = null;
+ for (CompilationElement ce : cfg.getCompilation().getElements()) {
+ if (ce instanceof ControlFlowGraph && ce.getName().startsWith(BLOCK_LIST_PREFIX)) {
+ if (result == null) {
+ result = (ControlFlowGraph) ce;
+ if (result.getElements().size() > 0) {
+ // Child elements are present, so methods were inlined.
+ return null;
+ }
+ } else {
+ // More than one BlockListBuilder, so methods were inlined.
+ return null;
+ }
+ }
+ }
+ return result;
+ }
+
+ private String getMethodName(ControlFlowGraph cfg) {
+ assert cfg.getName().startsWith(BLOCK_LIST_PREFIX);
+ return cfg.getName().substring(BLOCK_LIST_PREFIX.length());
+ }
+
+
+ public boolean hasBytecodes(ControlFlowGraph cfg) {
+ return getBlockListCFG(cfg) != null;
+ }
+/*
+ public boolean bytecodesLoaded(ControlFlowGraph cfg) {
+ return getBytecodes(cfg) != null;
+ }
+*/
+ public String noBytecodesMsg(ControlFlowGraph cfg) {
+ StringBuilder result = new StringBuilder();
+ result.append("No bytecodes available for ").append(cfg.getCompilation().getName()).append(" - ").append(cfg.getName());
+ if (!hasBytecodes(cfg)) {
+ result.append("\nThe compiler inlined methods during compilation, so there is no single method to take the bytecodes from.");
+ } else {
+ result.append("\nThe method is not present in the classpath. Configure the claspath using Tools->Options.");
+ }
+ return result.toString();
+ }
+
+ public Bytecodes getBytecodes(ControlFlowGraph cfg) {
+ Bytecodes result = loadedBytecodes.get(cfg);
+ if (result != null) {
+ return result;
+ }
+
+ cfg = getBlockListCFG(cfg);
+ if (cfg == null) {
+ return null;
+ }
+
+ if (cfg.getBytecodes() != null) {
+ return cfg.getBytecodes();
+ }
+
+ String methodName = getMethodName(cfg);
+ List mbcs = BytecodesParser.readMethod(cfg, methodName, classPaths);
+ if (mbcs.size() == 0) {
+ return null;
+ } else if (mbcs.size() == 1) {
+ result = mbcs.get(0);
+ } else {
+ result = (Bytecodes) JOptionPane.showInputDialog(null, "Ambiguous methodname: \n" + methodName, "Select method", JOptionPane.QUESTION_MESSAGE, null, mbcs.toArray(), mbcs.get(0));
+ if (result == null) {
+ return null;
+ }
+ }
+
+ loadedBytecodes.put(cfg, result);
+ return result;
+ }
+
+ private FileObject getOptionLocation() {
+ return Repository.getDefault().getDefaultFileSystem().findResource("at-ssw-visualizer-bc/classpaths");
+ }
+
+ /**
+ * Loads the classpath information from the system filesystem.
+ */
+ private void loadClassPaths() {
+ List data = new ArrayList();
+ try {
+ InputStream stream = getOptionLocation().getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+
+ String cp = reader.readLine();
+ while (cp != null) {
+ data.add(cp);
+ cp = reader.readLine();
+ }
+ reader.close();
+ } catch (IOException ex) {
+ Logger log = Logger.getLogger(BytecodeModel.class.getName());
+ log.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+
+ if (data.size() > 0) {
+ classPaths = data.toArray(new String[data.size()]);
+ } else {
+ classPaths = getDefaultClassPaths();
+ }
+ }
+
+ /**
+ * Stores the classpath infotmation to the system filesystem.
+ */
+ private void saveClassPaths() {
+ try {
+ OutputStream stream = getOptionLocation().getOutputStream();
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));
+
+ for (String cp : classPaths) {
+ writer.write(cp);
+ writer.newLine();
+ }
+ writer.close();
+ } catch (IOException ex) {
+ Logger log = Logger.getLogger(BytecodeModel.class.getName());
+ log.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+
+ public String[] getDefaultClassPaths() {
+ return System.getProperty("sun.boot.class.path", "").split(System.getProperty("path.separator"));
+ }
+
+ /**
+ * Returns an array of all classpaths stored in the model.
+ *
+ * @return String array with all classpaths
+ */
+ public String[] getClassPaths() {
+ return classPaths;
+ }
+
+ public void setClassPaths(String[] classPaths) {
+ this.classPaths = classPaths;
+
+ loadedBytecodes.clear();
+ saveClassPaths();
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodesImpl.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodesImpl.java
new file mode 100644
index 000000000000..96415af3bcfa
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodesImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.modelimpl;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.util.SortedMap;
+
+/**
+ * This class holds the bytecode of a method and provides severel methods
+ * accessing the details.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class BytecodesImpl implements Bytecodes {
+
+ private ControlFlowGraph controlFlowGraph;
+ private String name;
+ private String shortName;
+
+ private String prolog;
+ private String attributes;
+ private SortedMap byteCodes;
+
+ public BytecodesImpl(ControlFlowGraph controlFlowGraph, String name, String shortName, String prolog, String attributes, SortedMap byteCodes) {
+ this.controlFlowGraph = controlFlowGraph;
+ this.name = name;
+ this.shortName = shortName;
+ this.prolog = prolog;
+ this.attributes = attributes;
+ this.byteCodes = byteCodes;
+ }
+
+ @Override
+ public ControlFlowGraph getControlFlowGraph() {
+ return controlFlowGraph;
+ }
+
+ @Override
+ public void parseBytecodes() {
+ // Nothing to parse
+ }
+
+ @Override
+ public String getBytecodes(int fromBCI, int toBCI) {
+ StringBuilder sb = new StringBuilder();
+ for (Integer key : byteCodes.subMap(fromBCI, toBCI).keySet()) {
+ String keyString = Integer.toString(key);
+ sb.append(keyString).append(":");
+ sb.append(" ".substring(Math.min(keyString.length(), 4)));
+ sb.append(byteCodes.get(key));
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String getEpilogue() {
+ return attributes;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodesParser.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodesParser.java
new file mode 100644
index 000000000000..accdc8b9d3f2
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/BytecodesParser.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.modelimpl;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.Code;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.Type;
+
+/**
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class BytecodesParser {
+
+ private BytecodesParser() {
+ }
+
+ /**
+ * Trys to read the bytecode of the given method name.
+ *
+ * @param method full name of the method
+ */
+ public static List readMethod(ControlFlowGraph cfg, String method, String[] classPaths) {
+ List result = new ArrayList();
+
+ MethodName methodName = MethodName.parse(method);
+ if (methodName == null) {
+ return result;
+ }
+
+ for (String classPath : classPaths) {
+ try {
+ ClassParser cp = locateClass(methodName, classPath);
+ if (cp != null) {
+ JavaClass c = cp.parse();
+ for (Method m : c.getMethods()) {
+ if (methodName.matches(m)) {
+ result.add(readBytecodes(cfg, methodName, m));
+ }
+ }
+ }
+ } catch (IOException ex) {
+ Logger log = Logger.getLogger(BytecodesParser.class.getName());
+ log.log(Level.INFO, ex.getMessage(), ex);
+ }
+ }
+ return result;
+ }
+
+ private static ClassParser locateClass(MethodName methodName, String classPath) throws IOException {
+ File baseFile = new File(classPath);
+ if (!baseFile.exists()) {
+ return null;
+ }
+
+ if (baseFile.isDirectory()) {
+ String className = methodName.className.replace('.', File.separatorChar) + ".class";
+ File classFile = new File(baseFile, className);
+ if (classFile.exists()) {
+ return new ClassParser(new FileInputStream(classFile), className);
+ }
+
+ } else {
+ String className = methodName.className.replace('.', '/') + ".class";
+ ZipFile zipFile = new ZipFile(baseFile);
+ ZipEntry zipEntry = zipFile.getEntry(className);
+ if (zipEntry != null) {
+ return new ClassParser(zipFile.getInputStream(zipEntry), className);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parses the code string and generates the prolog, attributeslist and the
+ * hashmap for the bytecode.
+ */
+ private static Bytecodes readBytecodes(ControlFlowGraph cfg, MethodName methodName, Method method) {
+ Code code = method.getCode();
+ Scanner bcScanner = new Scanner(code.toString());
+
+ String prolog = "";
+ String attributes = "";
+ SortedMap byteCodes = new TreeMap();
+
+ bcScanner.useDelimiter("\n");
+ while (bcScanner.hasNext()) {
+ String codeLine = bcScanner.next();
+ if (codeLine.startsWith("Code")) {
+ prolog = codeLine;
+ } else if (codeLine.length() > 0 && codeLine.charAt(0) >= '0' && codeLine.charAt(0) <= '9' && codeLine.indexOf(':') > 0) {
+ Scanner codeLineScanner = new Scanner(codeLine);
+ codeLineScanner.useDelimiter(":\\s*");
+// try {
+ int key = Integer.parseInt(codeLineScanner.next());
+ byteCodes.put(key, codeLineScanner.next());
+/* } catch (NumberFormatException ex) {
+ System.err.println(codeLine);
+ } catch (NoSuchElementException ex) {
+ System.err.println(codeLine);
+ }
+ */
+ codeLineScanner.close();
+ } else if (codeLine.length() > 0 && codeLine.charAt(0) != ' ') {
+ attributes = attributes + codeLine + "\n";
+ }
+ }
+ bcScanner.close();
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(method.getReturnType()).append(" ");
+ sb.append(methodName.className);
+ sb.append(".").append(method.getName()).append("(");
+ boolean sep = false;
+ for (Type t : method.getArgumentTypes()) {
+ if (sep) {
+ sb.append(", ");
+ }
+ sb.append(t);
+ sep = true;
+ }
+ sb.append(")");
+ String name = sb.toString();
+
+ sb = new StringBuilder();
+ int point = methodName.className.lastIndexOf('.');
+ if (point > 0) {
+ sb.append(methodName.className.substring(point + 1));
+ } else {
+ sb.append(methodName.className);
+ }
+ sb.append(".").append(method.getName());
+ String shortName = sb.toString();
+
+ return new BytecodesImpl(cfg, name, shortName, prolog, attributes, byteCodes);
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/MethodName.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/MethodName.java
new file mode 100644
index 000000000000..8d3267f29063
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/modelimpl/MethodName.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.modelimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.Type;
+
+/**
+ * This class holds informations like package, class, arguments, return values
+ * and name of a method.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public class MethodName {
+
+ public String methodModifier;
+ public Type returnValType;
+ public String className;
+ public String methodName;
+ public List arguments;
+
+ private MethodName() {
+ // Prevent creation from outside.
+ }
+
+ /**
+ * Initializes a new MethodName and parses the full name.
+ *
+ * @param name full name of the method
+ */
+ public static MethodName parse(String name) {
+ Scanner methodScanner = new Scanner(name);
+ methodScanner.useDelimiter("\\s|\\,\\s|\\(|\\)$");
+ try {
+ MethodName result = new MethodName();
+ result.methodModifier = methodScanner.next();
+ result.returnValType = getTypeOf(methodScanner.next());
+ String[] classMethodName = methodScanner.next().split("\\.");
+ StringBuilder pkgClass = new StringBuilder();
+ pkgClass.append(classMethodName[0]);
+ for(int i = 1; i < classMethodName.length - 1; i++) {
+ pkgClass.append(".");
+ pkgClass.append(classMethodName[i]);
+ }
+ result.className = pkgClass.toString();
+ result.methodName = classMethodName[classMethodName.length - 1];
+ result.arguments = new ArrayList();
+ String argument;
+ while(methodScanner.hasNext()) {
+ argument = methodScanner.next();
+ if(!argument.equals("")) {
+ result.arguments.add(getTypeOf(argument));
+ }
+ }
+ return result;
+ } catch (Exception ex) {
+ Logger log = Logger.getLogger(BytecodesParser.class.getName());
+ log.log(Level.WARNING, ex.getMessage(), ex);
+ return null;
+ } finally {
+ methodScanner.close();
+ }
+ }
+
+ /**
+ * Checks if the specified method has the same signature as defined by this
+ * parsed method name.
+ */
+ public boolean matches(Method m) {
+ if (!methodName.equals(m.getName())) {
+ return false;
+ }
+ if (returnValType != Type.UNKNOWN && returnValType != m.getReturnType()) {
+ return false;
+ }
+ if (arguments.size() != m.getArgumentTypes().length) {
+ return false;
+ }
+ for(int i = 0; i < arguments.size(); i++) {
+ if (arguments.get(i) != Type.UNKNOWN && arguments.get(i) != m.getArgumentTypes()[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Translates the String representation of a type into a Type.
+ *
+ * @param type String representation of the type
+ * @return Type of the Stringrepresentation
+ */
+ private static Type getTypeOf(String type) {
+ if(type.equals("void")) {
+ return Type.VOID;
+ } else if(type.equals("jint")) {
+ return Type.INT;
+ } else if(type.equals("jshort")) {
+ return Type.SHORT;
+ } else if(type.equals("jlong")) {
+ return Type.LONG;
+ } else if(type.equals("jchar")) {
+ return Type.CHAR;
+ } else if(type.equals("jboolean")) {
+ return Type.BOOLEAN;
+ } else if(type.equals("jdouble")) {
+ return Type.DOUBLE;
+ } else if(type.equals("jfloat")) {
+ return Type.FLOAT;
+ } else {
+ return Type.UNKNOWN;
+ }
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionPanel.form b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionPanel.form
new file mode 100644
index 000000000000..de6db176c838
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionPanel.form
@@ -0,0 +1,102 @@
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionPanel.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionPanel.java
new file mode 100644
index 000000000000..fa9e46680b59
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionPanel.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.options;
+
+import at.ssw.visualizer.bc.model.BytecodeModel;
+import at.ssw.visualizer.bc.modelimpl.BytecodeModelImpl;
+import javax.swing.DefaultListModel;
+import javax.swing.JFileChooser;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import org.openide.util.Lookup;
+
+/**
+ * The panel for setting the classpaths.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+final class BCOptionPanel extends javax.swing.JPanel {
+
+ private final BCOptionsPanelController controller;
+ private final BytecodeModelImpl bytecodeModel;
+ private final DefaultListModel listModel;
+
+ public BCOptionPanel(BCOptionsPanelController controller) {
+ this.controller = controller;
+ initComponents();
+
+ bytecodeModel = (BytecodeModelImpl) Lookup.getDefault().lookup(BytecodeModel.class);
+ listModel = new DefaultListModel();
+ classpathList.setModel(listModel);
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ classpathScrollPane = new javax.swing.JScrollPane();
+ classpathList = new javax.swing.JList();
+ addPathButton = new javax.swing.JButton();
+ removeButton = new javax.swing.JButton();
+ addJarZipButton = new javax.swing.JButton();
+ addDefaultClasspath = new javax.swing.JButton();
+
+ classpathList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
+ classpathScrollPane.setViewportView(classpathList);
+
+ org.openide.awt.Mnemonics.setLocalizedText(addPathButton, "Add folder");
+ addPathButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ addPathButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(removeButton, "Remove");
+ removeButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ removeButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(addJarZipButton, "Add Jar/Zip file");
+ addJarZipButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ addJarZipButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(addDefaultClasspath, "Add default classpath");
+ addDefaultClasspath.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ addDefaultClasspathActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(classpathScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(addJarZipButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(addDefaultClasspath, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(removeButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(addPathButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+
+ layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {addDefaultClasspath, addJarZipButton, removeButton});
+
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(addPathButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(addJarZipButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(addDefaultClasspath)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(removeButton))
+ .addComponent(classpathScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 202, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ }// //GEN-END:initComponents
+
+ private void addDefaultClasspathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addDefaultClasspathActionPerformed
+ for (String cp : bytecodeModel.getDefaultClassPaths()) {
+ listModel.addElement(cp);
+ controller.changed();
+ classpathList.setSelectedIndex(listModel.getSize() - 1);
+ }
+ }//GEN-LAST:event_addDefaultClasspathActionPerformed
+
+ private void addJarZipButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addJarZipButtonActionPerformed
+ JFileChooser chooser = new JFileChooser();
+ chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+ chooser.setFileFilter(new FileNameExtensionFilter("Bytecode archives", "jar", "zip"));
+ if (chooser.showOpenDialog(getParent()) == JFileChooser.APPROVE_OPTION) {
+ listModel.addElement(chooser.getSelectedFile().getAbsolutePath());
+ controller.changed();
+ classpathList.setSelectedIndex(listModel.getSize() - 1);
+ }
+ }//GEN-LAST:event_addJarZipButtonActionPerformed
+
+ private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
+ int idx = classpathList.getSelectedIndex();
+ if (idx >= 0 && idx < listModel.getSize()) {
+ listModel.remove(idx);
+ controller.changed();
+ if (listModel.size() > 0) {
+ classpathList.setSelectedIndex(Math.max(0, idx - 1));
+ }
+ }
+ }//GEN-LAST:event_removeButtonActionPerformed
+
+ private void addPathButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addPathButtonActionPerformed
+ JFileChooser chooser = new JFileChooser();
+ chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ if (chooser.showOpenDialog(getParent()) == JFileChooser.APPROVE_OPTION) {
+ listModel.addElement(chooser.getSelectedFile().getAbsolutePath());
+ controller.changed();
+ classpathList.setSelectedIndex(listModel.getSize() - 1);
+ }
+ }//GEN-LAST:event_addPathButtonActionPerformed
+
+ public void update() {
+ listModel.clear();
+ for (String cp : bytecodeModel.getClassPaths()) {
+ listModel.addElement(cp);
+ }
+ }
+
+ public void applyChanges() {
+ String[] data = new String[listModel.getSize()];
+ listModel.copyInto(data);
+ bytecodeModel.setClassPaths(data);
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton addDefaultClasspath;
+ private javax.swing.JButton addJarZipButton;
+ private javax.swing.JButton addPathButton;
+ private javax.swing.JList classpathList;
+ private javax.swing.JScrollPane classpathScrollPane;
+ private javax.swing.JButton removeButton;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptions.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptions.java
new file mode 100644
index 000000000000..0a1aa80864e1
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptions.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.options;
+
+import at.ssw.visualizer.bc.options.icons.Icons;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import org.netbeans.spi.options.OptionsCategory;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.ImageUtilities;
+
+/**
+ * This class configures the OptionPanel.
+ *
+ * @author Alexander Reder
+ */
+public final class BCOptions extends OptionsCategory {
+
+ public OptionsPanelController create() {
+ return new BCOptionsPanelController();
+ }
+
+ public String getCategoryName() {
+ return "Bytecodes";
+ }
+
+ public String getTitle() {
+ return "Bytecodes";
+ }
+
+ @Override
+ public Icon getIcon() {
+ return new ImageIcon(ImageUtilities.loadImage(Icons.BC_OPTION));
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionsPanelController.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionsPanelController.java
new file mode 100644
index 000000000000..d023bce84249
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/BCOptionsPanelController.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.options;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import javax.swing.JComponent;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+
+/**
+ * Controlls the communication.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+final class BCOptionsPanelController extends OptionsPanelController {
+
+ private BCOptionPanel panel;
+ private boolean changed;
+ private PropertyChangeSupport prop;
+
+ public BCOptionsPanelController() {
+ prop = new PropertyChangeSupport(this);
+ panel = new BCOptionPanel(this);
+ panel.update();
+ }
+
+ public void changed() {
+ if (!changed) {
+ changed = true;
+ prop.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
+ }
+ }
+
+ public void update() {
+ panel.update();
+ changed = false;
+ }
+
+ public void applyChanges() {
+ panel.applyChanges();
+ changed = false;
+ }
+
+ public void cancel() {
+ // Nothing to do.
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public boolean isChanged() {
+ return changed;
+ }
+
+ public HelpCtx getHelpCtx() {
+ return null;
+ }
+
+ public JComponent getComponent(Lookup masterLookup) {
+ return panel;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ prop.addPropertyChangeListener(l);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ prop.removePropertyChangeListener(l);
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/icons/Icons.java b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/icons/Icons.java
new file mode 100644
index 000000000000..3831fdf952ff
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/java/at/ssw/visualizer/bc/options/icons/Icons.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.options.icons;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class Icons {
+
+ private static final String PATH = "at/ssw/visualizer/bc/options/icons/";
+
+ public static final String BC_OPTION = PATH + "package.gif";
+}
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/nbm/manifest.mf b/visualizer/C1Visualizer/BytecodeModel/src/main/nbm/manifest.mf
new file mode 100644
index 000000000000..58cd5a764430
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/nbm/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.bc.model
+OpenIDE-Module-Layer: at/ssw/visualizer/bc/model/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/bc/model/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/resources/META-INF/services/at.ssw.visualizer.bc.model.BytecodeModel b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/META-INF/services/at.ssw.visualizer.bc.model.BytecodeModel
new file mode 100644
index 000000000000..595e968b5da9
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/META-INF/services/at.ssw.visualizer.bc.model.BytecodeModel
@@ -0,0 +1 @@
+at.ssw.visualizer.bc.modelimpl.BytecodeModelImpl
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/model/Bundle.properties b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/model/Bundle.properties
new file mode 100644
index 000000000000..4100074e983f
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/model/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=Bytecode Model
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/model/layer.xml b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/model/layer.xml
new file mode 100644
index 000000000000..98fb647182a8
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/model/layer.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/options/icons/package.gif b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/options/icons/package.gif
new file mode 100644
index 000000000000..ced7996a76b0
Binary files /dev/null and b/visualizer/C1Visualizer/BytecodeModel/src/main/resources/at/ssw/visualizer/bc/options/icons/package.gif differ
diff --git a/visualizer/C1Visualizer/BytecodeView/pom.xml b/visualizer/C1Visualizer/BytecodeView/pom.xml
new file mode 100644
index 000000000000..7e964ddccf19
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/pom.xml
@@ -0,0 +1,117 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ BytecodeView
+ 1.14-SNAPSHOT
+ nbm
+ BytecodeView
+
+ UTF-8
+
+
+
+ at.ssw.visualizer
+ VisualizerUI
+ ${project.version}
+
+
+ at.ssw.visualizer
+ BytecodeEditor
+ ${project.version}
+
+
+ at.ssw.visualizer
+ BytecodeModel
+ ${project.version}
+
+
+ at.ssw.visualizer
+ CompilationModel
+ ${project.version}
+
+
+ at.ssw.visualizer
+ TextEditor
+ ${project.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-editor
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-editor-lib
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-loaders
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-nodes
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-windows
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.BytecodeView
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/java/at/ssw/visualizer/bc/view/BCViewTopComponent.java b/visualizer/C1Visualizer/BytecodeView/src/main/java/at/ssw/visualizer/bc/view/BCViewTopComponent.java
new file mode 100644
index 000000000000..25b95b5580bd
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/java/at/ssw/visualizer/bc/view/BCViewTopComponent.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.view;
+
+import at.ssw.visualizer.bc.BCEditorKit;
+import at.ssw.visualizer.bc.model.BCTextBuilder;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.texteditor.view.AbstractTextViewTopComponent;
+import java.io.Serializable;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * Top component which displays the bytecode for a selected block.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+final class BCViewTopComponent extends AbstractTextViewTopComponent {
+
+ private BCViewTopComponent() {
+ super(new BCEditorKit());
+ setName("Bytecodes");
+ setToolTipText("Bytecodes");
+ }
+
+ @Override
+ protected String getContent(ControlFlowGraph cfg, BasicBlock[] blocks) {
+ BCTextBuilder builder = new BCTextBuilder();
+ return builder.buildView(cfg, blocks);
+ }
+
+ //
+ private static final String PREFERRED_ID = "BCViewTopComponent";
+ private static BCViewTopComponent instance;
+
+ public static synchronized BCViewTopComponent getDefault() {
+ if (instance == null) {
+ instance = new BCViewTopComponent();
+ }
+ return instance;
+ }
+
+ public static synchronized BCViewTopComponent findInstance() {
+ return (BCViewTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+ }
+
+ @Override
+ public int getPersistenceType() {
+ return TopComponent.PERSISTENCE_ALWAYS;
+ }
+
+ @Override
+ protected String preferredID() {
+ return PREFERRED_ID;
+ }
+
+ @Override
+ public Object writeReplace() {
+ return new ResolvableHelper();
+ }
+
+ static final class ResolvableHelper implements Serializable {
+ private static final long serialVersionUID = 1L;
+ public Object readResolve() {
+ return BCViewTopComponent.getDefault();
+ }
+ }
+ //
+}
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/java/at/ssw/visualizer/bc/view/ShowBCViewAction.java b/visualizer/C1Visualizer/BytecodeView/src/main/java/at/ssw/visualizer/bc/view/ShowBCViewAction.java
new file mode 100644
index 000000000000..a0fc80984833
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/java/at/ssw/visualizer/bc/view/ShowBCViewAction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.bc.view;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.windows.TopComponent;
+
+/**
+ * Action which shows BCView component.
+ *
+ * @author Alexander Reder
+ */
+public class ShowBCViewAction extends AbstractAction {
+ public ShowBCViewAction() {
+ super("Bytecodes");
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ TopComponent win = BCViewTopComponent.findInstance();
+ win.open();
+ win.requestActive();
+ }
+}
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/nbm/manifest.mf b/visualizer/C1Visualizer/BytecodeView/src/main/nbm/manifest.mf
new file mode 100644
index 000000000000..46ad11a92fab
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/nbm/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.bc.view
+OpenIDE-Module-Layer: at/ssw/visualizer/bc/view/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/bc/view/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/BCViewTopComponentSettings.xml b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/BCViewTopComponentSettings.xml
new file mode 100644
index 000000000000..85c9b6995abc
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/BCViewTopComponentSettings.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/BCViewTopComponentWstcref.xml b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/BCViewTopComponentWstcref.xml
new file mode 100644
index 000000000000..7b4d85758d7b
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/BCViewTopComponentWstcref.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/Bundle.properties b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/Bundle.properties
new file mode 100644
index 000000000000..f1df38cceb82
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=Bytecode View
diff --git a/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/layer.xml b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/layer.xml
new file mode 100644
index 000000000000..2710385d20bf
--- /dev/null
+++ b/visualizer/C1Visualizer/BytecodeView/src/main/resources/at/ssw/visualizer/bc/view/layer.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/CompilationModel/pom.xml b/visualizer/C1Visualizer/CompilationModel/pom.xml
new file mode 100644
index 000000000000..894e98598682
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/pom.xml
@@ -0,0 +1,99 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ CompilationModel
+ 1.14-SNAPSHOT
+ nbm
+ CompilationModel
+
+ UTF-8
+
+
+
+ org.netbeans.api
+ org-netbeans-api-progress
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-netbeans-api-progress-nb
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.model
+ at.ssw.visualizer.model.bc
+ at.ssw.visualizer.model.nc
+ at.ssw.visualizer.model.cfg
+ at.ssw.visualizer.model.interval
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.5.0
+
+
+ generate-sources
+
+ add-source
+
+
+
+ ${project.build.directory}/generated-sources/cocor
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/Compilation.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/Compilation.java
new file mode 100644
index 000000000000..151cb6eba296
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/Compilation.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model;
+
+import java.util.Date;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface Compilation extends CompilationElement {
+ public CompilationModel getCompilationModel();
+
+ public String getMethod();
+
+ public Date getDate();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/CompilationElement.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/CompilationElement.java
new file mode 100644
index 000000000000..40a28ceb7872
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/CompilationElement.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface CompilationElement {
+ public Compilation getCompilation();
+
+ public CompilationElement getParent();
+
+ public List getElements();
+
+ public String getShortName();
+
+ public String getName();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/CompilationModel.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/CompilationModel.java
new file mode 100644
index 000000000000..c208e3c54ec8
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/CompilationModel.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model;
+
+import java.util.List;
+import javax.swing.event.ChangeListener;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface CompilationModel {
+ public List getCompilations();
+
+ public String parseInputFile(String fileName);
+
+ public void removeCompilation(Compilation compilation);
+
+ public void clear();
+
+ public void addChangedListener(ChangeListener listener);
+
+ public void removeChangedListener(ChangeListener listener);
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/bc/Bytecodes.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/bc/Bytecodes.java
new file mode 100644
index 000000000000..944d8f36830a
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/bc/Bytecodes.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.bc;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+
+/**
+ * This class holds the bytecode of a method and provides severel methods
+ * accessing the details.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public interface Bytecodes {
+ /**
+ * Back-link to the control flow graph where the bytecodes were loaded from.
+ */
+ public ControlFlowGraph getControlFlowGraph();
+
+ /**
+ * Called before the first call of getBytecodes() or getEpilogue(). Can be called multiple times.
+ */
+ public void parseBytecodes();
+
+ /**
+ * The bytecodes of the method in the given bytecode range.
+ *
+ * @param fromBCI starting BCI (including this bci)
+ * @param toBCI ending BCI (not including this bci)
+ * @return string representation of the bytecodes
+ */
+ public String getBytecodes(int fromBCI, int toBCI);
+
+ public String getEpilogue();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/BasicBlock.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/BasicBlock.java
new file mode 100644
index 000000000000..2091934f3f11
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/BasicBlock.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.cfg;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface BasicBlock {
+ public ControlFlowGraph getParent();
+
+ public String getName();
+
+ public int getFromBci();
+
+ public int getToBci();
+
+ public List getPredecessors();
+
+ public List getSuccessors();
+
+ public List getXhandlers();
+
+ public List getFlags();
+
+ public BasicBlock getDominator();
+
+ public int getLoopIndex();
+
+ public int getLoopDepth();
+
+ public int getFirstLirId();
+
+ public int getLastLirId();
+
+ public double getProbability();
+
+ public boolean hasState();
+
+ public List getStates();
+
+ public boolean hasHir();
+
+ public List getHirInstructions();
+
+ public boolean hasLir();
+
+ public List getLirOperations();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/ControlFlowGraph.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/ControlFlowGraph.java
new file mode 100644
index 000000000000..4eb63b25affd
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/ControlFlowGraph.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.cfg;
+
+import at.ssw.visualizer.model.CompilationElement;
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.nc.NativeMethod;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface ControlFlowGraph extends CompilationElement {
+ public List getBasicBlocks();
+
+ public BasicBlock getBasicBlockByName(String name);
+
+ public Bytecodes getBytecodes();
+
+ public NativeMethod getNativeMethod();
+
+ public boolean hasState();
+
+ public boolean hasHir();
+
+ public boolean hasLir();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/IRInstruction.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/IRInstruction.java
new file mode 100644
index 000000000000..4efff579aa95
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/IRInstruction.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.cfg;
+
+import java.util.Collection;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface IRInstruction {
+ public static String HIR_NAME = "tid";
+ public static String HIR_TEXT = "instruction";
+ public static String HIR_OPERAND = "result";
+
+ public static String LIR_NUMBER = "nr";
+ public static String LIR_TEXT = "instruction";
+
+ public Collection getNames();
+ public String getValue(String name);
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/State.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/State.java
new file mode 100644
index 000000000000..63ff4772ad8d
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/State.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.cfg;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface State {
+ public String getKind();
+
+ public int getSize();
+
+ public String getMethod();
+
+ public List getEntries();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/StateEntry.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/StateEntry.java
new file mode 100644
index 000000000000..d893177cfbdc
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/cfg/StateEntry.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.cfg;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface StateEntry {
+ public int getIndex();
+
+ public String getName();
+
+ public boolean hasPhiOperands();
+
+ public List getPhiOperands();
+
+ public String getOperand();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/ChildInterval.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/ChildInterval.java
new file mode 100644
index 000000000000..2aff9f6395c1
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/ChildInterval.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.interval;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface ChildInterval {
+ public Interval getParent();
+
+ public String getRegNum();
+
+ public String getType();
+
+ public String getOperand();
+
+ public String getSpillState();
+
+ public ChildInterval getRegisterHint();
+
+ public List getRanges();
+
+ public List getUsePositions();
+
+ public int getFrom();
+
+ public int getTo();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/Interval.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/Interval.java
new file mode 100644
index 000000000000..e3bebdd9101f
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/Interval.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.interval;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface Interval {
+ public IntervalList getParent();
+
+ public List getChildren();
+
+ public String getRegNum();
+
+ public int getFrom();
+
+ public int getTo();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/IntervalList.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/IntervalList.java
new file mode 100644
index 000000000000..afc96422b622
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/IntervalList.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.interval;
+
+import at.ssw.visualizer.model.CompilationElement;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface IntervalList extends CompilationElement {
+ public List getIntervals();
+
+ public ControlFlowGraph getControlFlowGraph();
+
+ public int getNumLIROperations();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/Range.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/Range.java
new file mode 100644
index 000000000000..9e2e60c3c149
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/Range.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.interval;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface Range {
+ public int getFrom();
+
+ public int getTo();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/UsePosition.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/UsePosition.java
new file mode 100644
index 000000000000..a36a7a8ed2b6
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/interval/UsePosition.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.interval;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface UsePosition {
+ public char getKind();
+
+ public int getPosition();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/nc/NativeMethod.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/nc/NativeMethod.java
new file mode 100644
index 000000000000..75fc0e89bc55
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/model/nc/NativeMethod.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.model.nc;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public interface NativeMethod {
+
+ public ControlFlowGraph getControlFlowGraph();
+
+ public String getMethodText();
+
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationElementImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationElementImpl.java
new file mode 100644
index 000000000000..57a58a28160d
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationElementImpl.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl;
+
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.CompilationElement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CompilationElementImpl implements CompilationElement {
+ private Compilation compilation;
+ private CompilationElement parent;
+ private CompilationElement[] elements;
+ private String shortName;
+ private String name;
+
+ public CompilationElementImpl(String shortName, String name) {
+ this.shortName = shortName;
+ this.name = name;
+ this.elements = new CompilationElement[0];
+ }
+
+ public Compilation getCompilation() {
+ return compilation;
+ }
+
+ public CompilationElement getParent() {
+ return parent;
+ }
+
+ public List getElements() {
+ return Collections.unmodifiableList(Arrays.asList(elements));
+ }
+
+ public void setElements(CompilationElementImpl[] elements, Compilation compilation) {
+ this.elements = elements;
+ for (CompilationElementImpl ce : elements) {
+ ce.parent = this;
+ ce.compilation = compilation;
+ }
+ }
+
+ public String getShortName() {
+ return shortName;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationImpl.java
new file mode 100644
index 000000000000..25c151a7886e
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl;
+
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.CompilationElement;
+import at.ssw.visualizer.model.CompilationModel;
+import java.util.Date;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CompilationImpl extends CompilationElementImpl implements Compilation {
+ private CompilationModel compilationModel;
+ private String method;
+ private Date date;
+
+ public CompilationImpl(String shortName, String name, String method, Date date) {
+ super(shortName, name);
+ this.method = method;
+ this.date = date;
+ }
+
+ public CompilationModel getCompilationModel() {
+ return compilationModel;
+ }
+
+ public void setCompilationModel(CompilationModelImpl compilationModel) {
+ this.compilationModel = compilationModel;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append(" Name: ").append(getName());
+ result.append("\n Method: ").append(method);
+ result.append("\n Date: ").append(date);
+ result.append("\n Elements: ").append(getElements().size());
+ result.append("\n");
+ for (CompilationElement element : getElements()) {
+ result.append(element);
+ }
+ return result.toString();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationModelImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationModelImpl.java
new file mode 100644
index 000000000000..296f23deab6d
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/CompilationModelImpl.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl;
+
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.CompilationModel;
+import at.ssw.visualizer.parser.CompilationParser;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CompilationModelImpl implements CompilationModel {
+ private List compilations = new ArrayList();
+ private List listeners = new ArrayList();
+
+ private boolean parsing;
+
+ public List getCompilations() {
+ return Collections.unmodifiableList(compilations);
+ }
+
+ public String parseInputFile(String fileName) {
+ parsing = true;
+ String result;
+ try {
+ result = CompilationParser.parseInputFile(fileName, this);
+ } finally {
+ parsing = false;
+ notifyListeners();
+ }
+ return result;
+ }
+
+ public void addCompilation(CompilationImpl compilation) {
+ this.compilations.add(compilation);
+ compilation.setCompilationModel(this);
+
+ if (!parsing || this.compilations.size() % 40 == 0) {
+ notifyListeners();
+ }
+ }
+
+ public void removeCompilation(Compilation compilation) {
+ compilations.remove(compilation);
+ notifyListeners();
+ }
+
+ public void clear() {
+ compilations.clear();
+ notifyListeners();
+ }
+
+
+ public void addChangedListener(ChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeChangedListener(ChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ private void notifyListeners() {
+ ChangeEvent event = new ChangeEvent(this);
+ for (ChangeListener listener : listeners) {
+ listener.stateChanged(event);
+ }
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append("Compilations: ");
+ result.append(compilations.size());
+ result.append("\n");
+ for (Compilation compilation : compilations) {
+ result.append(compilation);
+ }
+ return result.toString();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/bc/BytecodesImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/bc/BytecodesImpl.java
new file mode 100644
index 000000000000..5bf2fae4bf85
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/bc/BytecodesImpl.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.bc;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.modelimpl.cfg.BasicBlockImpl;
+import java.util.Arrays;
+
+/**
+ * This class holds the bytecode of a method and provides severel methods
+ * accessing the details.
+ *
+ * @author Christian Wimmer
+ */
+public class BytecodesImpl implements Bytecodes {
+ private ControlFlowGraph controlFlowGraph;
+ private String bytecodeString;
+
+ private String[] bytecodes;
+ private String epilogue;
+
+
+ public BytecodesImpl(ControlFlowGraph controlFlowGraph, String bytecodeString) {
+ this.controlFlowGraph = controlFlowGraph;
+ this.bytecodeString = bytecodeString;
+ }
+
+ public void parseBytecodes() {
+ String[] lines = bytecodeString.split("\n");
+
+ boolean inPrologue = true;
+ String[] result = new String[lines.length * 3];
+ int lastBci = -1;
+ int lnr = 0;
+ for (; lnr < lines.length; lnr++) {
+ String line = lines[lnr];
+
+ line = line.trim();
+ if (line.startsWith("[")) {
+ int end = line.indexOf(']');
+ if (end != -1) {
+ line = line.substring(end + 1, line.length());
+ }
+ }
+
+ line = line.trim();
+ int space1 = line.indexOf(' ');
+ if (space1 <= 0) {
+ if (inPrologue) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ String bciStr = line.substring(0, space1);
+ if (bciStr.endsWith(":")) {
+ bciStr = bciStr.substring(0, bciStr.length() - 1);
+ }
+
+ int bci;
+ try {
+ bci = Integer.parseInt(bciStr);
+ } catch (NumberFormatException ex) {
+ // Ignore invalid lines.
+ if (inPrologue) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ String opcode = line.substring(space1 + 1);
+ String params = "";
+ int space2 = opcode.indexOf(' ');
+ if (space2 > 0) {
+ params = opcode.substring(space2 + 1).trim();
+ opcode = opcode.substring(0, space2);
+ }
+ String tail = "";
+ int space3 = params.indexOf('|');
+ if (space3 >= 0) {
+ tail = params.substring(space3);
+ params = params.substring(0, space3);
+ }
+
+// if (!"ldc".equals(opcode) || !params.startsWith("\"")) {
+// // Separate packages with "." instead of "/"
+// params = params.replace('/', '.');
+// }
+
+ String printLine = bciStr + ":" + " ".substring(Math.min(bciStr.length(), 3)) +
+ opcode + " ".substring(Math.min(opcode.length(), 13)) +
+ params + " ".substring(Math.min(params.length(), 8)) +
+ tail;
+
+
+ if (bci >= result.length) {
+ result = Arrays.copyOf(result, Math.max(bci + 1, result.length * 2));
+ }
+ result[bci] = printLine;
+ inPrologue = false;
+ lastBci = Math.max(lastBci, bci);
+ }
+
+ StringBuilder epilogueBuilder = new StringBuilder();
+ for (; lnr < lines.length; lnr++) {
+ epilogueBuilder.append(lines[lnr]).append("\n");
+ }
+ epilogue = epilogueBuilder.toString();
+ bytecodes = Arrays.copyOf(result, lastBci + 1);
+
+
+ BasicBlockImpl[] blocks = new BasicBlockImpl[bytecodes.length];
+ for (BasicBlock b : controlFlowGraph.getBasicBlocks()) {
+ if (b instanceof BasicBlockImpl) {
+ BasicBlockImpl block = (BasicBlockImpl) b;
+ if (block.getToBci() != -1) {
+ // Do not override existing values.
+ return;
+ }
+ if (block.getFromBci() >= 0 && block.getFromBci() < blocks.length) {
+ blocks[block.getFromBci()] = block;
+ }
+ }
+ }
+
+ int curToBci = -1;
+ for (int i = blocks.length - 1; i >= 0; i--) {
+ if (bytecodes[i] != null && curToBci == -1) {
+ curToBci = i;
+ }
+ if (blocks[i] != null) {
+ blocks[i].setToBci(curToBci);
+ curToBci = -1;
+ }
+ }
+ }
+
+ public ControlFlowGraph getControlFlowGraph() {
+ return controlFlowGraph;
+ }
+
+ public String getBytecodes(int fromBCI, int toBCI) {
+ if (fromBCI < 0) {
+ return "";
+ }
+ toBCI = Math.min(toBCI, bytecodes.length);
+ StringBuilder sb = new StringBuilder();
+ for (int i = fromBCI; i < toBCI; i++) {
+ if (bytecodes[i] != null) {
+ sb.append(bytecodes[i]).append("\n");
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String getEpilogue() {
+ return epilogue;
+ }
+
+ @Override
+ public String toString() {
+ return "Bytecodes " + getControlFlowGraph().getName();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/BasicBlockImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/BasicBlockImpl.java
new file mode 100644
index 000000000000..83f6f2c2e4be
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/BasicBlockImpl.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import at.ssw.visualizer.model.cfg.State;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class BasicBlockImpl implements BasicBlock {
+
+ private ControlFlowGraph parent;
+ private String name;
+ private int fromBci;
+ private int toBci;
+ private BasicBlock[] predecessors;
+ private BasicBlock[] successors;
+ private BasicBlock[] xhandlers;
+ private String[] flags;
+ private BasicBlock dominator;
+ private int loopIndex;
+ private int loopDepth;
+ private int firstLirId;
+ private int lastLirId;
+ private double probability;
+ private State[] states;
+ private IRInstruction[] hirInstructions;
+ private IRInstruction[] lirOperations;
+
+ public void setValues(String name, int fromBci, int toBci, BasicBlock[] predecessors, BasicBlock[] successors, BasicBlock[] xhandlers, String[] flags, BasicBlock dominator, int loopIndex, int loopDepth, int firstLirId, int lastLirId, double probability, State[] states, IRInstruction[] hirInstructions, IRInstruction[] lirOperations) {
+ this.name = name;
+ this.fromBci = fromBci;
+ this.toBci = toBci;
+
+ this.predecessors = predecessors;
+ this.successors = successors;
+ this.xhandlers = xhandlers;
+
+ this.flags = flags;
+ this.dominator = dominator;
+ this.loopIndex = loopIndex;
+ this.loopDepth = loopDepth;
+ this.firstLirId = firstLirId;
+ this.lastLirId = lastLirId;
+ this.probability = probability;
+
+ this.states = states;
+ this.hirInstructions = hirInstructions;
+ this.lirOperations = lirOperations;
+ }
+
+ public ControlFlowGraph getParent() {
+ return parent;
+ }
+
+ protected void setParent(ControlFlowGraphImpl parent) {
+ this.parent = parent;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getFromBci() {
+ return fromBci;
+ }
+
+ public int getToBci() {
+ return toBci;
+ }
+
+ public void setToBci(int toBci) {
+ this.toBci = toBci;
+ }
+
+ public List getPredecessors() {
+ return Collections.unmodifiableList(Arrays.asList(predecessors));
+ }
+
+ public List getSuccessors() {
+ return Collections.unmodifiableList(Arrays.asList(successors));
+ }
+
+ public List getXhandlers() {
+ return Collections.unmodifiableList(Arrays.asList(xhandlers));
+ }
+
+ public List getFlags() {
+ return Collections.unmodifiableList(Arrays.asList(flags));
+ }
+
+ public BasicBlock getDominator() {
+ return dominator;
+ }
+
+ public int getLoopIndex() {
+ return loopIndex;
+ }
+
+ public int getLoopDepth() {
+ return loopDepth;
+ }
+
+ public int getFirstLirId() {
+ return firstLirId;
+ }
+
+ public int getLastLirId() {
+ return lastLirId;
+ }
+
+ public double getProbability() {
+ return probability;
+ }
+
+ public boolean hasState() {
+ return states != null;
+ }
+
+ public List getStates() {
+ return Collections.unmodifiableList(Arrays.asList(states));
+ }
+
+ public boolean hasHir() {
+ return hirInstructions != null;
+ }
+
+ public List getHirInstructions() {
+ return Collections.unmodifiableList(Arrays.asList(hirInstructions));
+ }
+
+ public boolean hasLir() {
+ return lirOperations != null;
+ }
+
+ public List getLirOperations() {
+ return Collections.unmodifiableList(Arrays.asList(lirOperations));
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/ControlFlowGraphImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/ControlFlowGraphImpl.java
new file mode 100644
index 000000000000..c87d9974a194
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/ControlFlowGraphImpl.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.nc.NativeMethod;
+import at.ssw.visualizer.modelimpl.CompilationElementImpl;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class ControlFlowGraphImpl extends CompilationElementImpl implements ControlFlowGraph {
+ private BasicBlock[] basicBlocks;
+ private Map blockNames;
+ private Bytecodes bytecodes;
+ private NativeMethod nativeMethod;
+ private boolean hasState;
+ private boolean hasHir;
+ private boolean hasLir;
+
+ public ControlFlowGraphImpl(String shortName, String name, BasicBlockImpl[] basicBlocks) {
+ super(shortName, name);
+ this.basicBlocks = basicBlocks;
+
+ blockNames = new HashMap(basicBlocks.length);
+ nativeMethod = null;
+ for (BasicBlockImpl block : basicBlocks) {
+ block.setParent(this);
+ blockNames.put(block.getName(), block);
+ hasState |= block.hasState();
+ hasHir |= block.hasHir();
+ hasLir |= block.hasLir();
+ }
+ }
+
+ public List getBasicBlocks() {
+ return Collections.unmodifiableList(Arrays.asList(basicBlocks));
+ }
+
+ public BasicBlock getBasicBlockByName(String name) {
+ return blockNames.get(name);
+ }
+
+ public Bytecodes getBytecodes() {
+ return bytecodes;
+ }
+
+ public void setBytecodes(Bytecodes bytecodes) {
+ this.bytecodes = bytecodes;
+ }
+
+ public NativeMethod getNativeMethod() {
+ return nativeMethod;
+ }
+
+ public void setNativeMethod(NativeMethod nativeMethod) {
+ this.nativeMethod = nativeMethod;
+ }
+
+ public boolean hasState() {
+ return hasState;
+ }
+
+ public boolean hasHir() {
+ return hasHir;
+ }
+
+ public boolean hasLir() {
+ return hasLir;
+ }
+
+ @Override
+ public String toString() {
+ return " CFG \"" + getName() + "\": " + basicBlocks.length + " blocks\n";
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/IRInstructionImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/IRInstructionImpl.java
new file mode 100644
index 000000000000..31927e3b9413
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/IRInstructionImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+
+public class IRInstructionImpl implements IRInstruction {
+
+ private final String[] keys;
+ private final String[] values;
+
+ public IRInstructionImpl(LinkedHashMap data) {
+ String[] skeys = new String[data.size()];
+ String[] svalues = new String[data.size()];
+ int index = 0;
+ for (Entry e : data.entrySet()) {
+ skeys[index] = e.getKey().intern();
+ svalues[index++] = e.getValue().intern();
+ }
+ if (Arrays.equals(skeys, twoKeys)) {
+ keys = twoKeys;
+ } else {
+ keys = skeys;
+ }
+ values = svalues;
+ }
+
+ public IRInstructionImpl(String pinned, int bci, int useCount, String name, String text, String operand) {
+ final String p = checkIntern(pinned);
+ final String b = Integer.toString(bci).intern();
+ final String u = Integer.toString(useCount).intern();
+ final String n = checkIntern(name);
+ final String i = checkIntern(text);
+ if (operand != null) {
+ keys = withOperandKeys;
+ values = new String[]{p, b, u, n, checkIntern(operand), i};
+ } else {
+ keys = noOperandKeys;
+ values = new String[]{p, b, u, n, i};
+ }
+ }
+
+ public IRInstructionImpl(int number, String text) {
+ keys = twoKeys;
+ values = new String[]{Integer.toString(number).intern(), checkIntern(text)};
+ }
+
+ static final String[] twoKeys = new String[]{LIR_NUMBER, LIR_TEXT};
+ static final String[] noOperandKeys = new String[]{"p", "bci", "use", HIR_NAME, HIR_TEXT};
+ static final String[] withOperandKeys = new String[]{"p", "bci", "use", HIR_NAME, HIR_OPERAND, HIR_TEXT};
+
+ public Collection getNames() {
+ return Collections.unmodifiableList(Arrays.asList(keys));
+ }
+
+ public String getValue(String name) {
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i].equals(name)) {
+ return values[i];
+ }
+ }
+ return null;
+ }
+
+ private String checkIntern(String s) {
+ if (s != s.intern()) {
+ throw new InternalError("non-interned String passed to IRInstructionImpl constructor");
+ }
+ return s;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/StateEntryImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/StateEntryImpl.java
new file mode 100644
index 000000000000..2446fa1e4b95
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/StateEntryImpl.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.StateEntry;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class StateEntryImpl implements StateEntry {
+ private int index;
+ private String name;
+ private String[] phiOperands;
+ private String operand;
+
+ public StateEntryImpl(int index, String name, String[] phiOperands, String operand) {
+ this.index = index;
+ this.name = name;
+ this.phiOperands = phiOperands;
+ this.operand = operand;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean hasPhiOperands() {
+ return phiOperands != null;
+ }
+
+ public List getPhiOperands() {
+ return Collections.unmodifiableList(Arrays.asList(phiOperands));
+ }
+
+ public String getOperand() {
+ return operand;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/StateImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/StateImpl.java
new file mode 100644
index 000000000000..64b328f4f5f7
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/cfg/StateImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.State;
+import at.ssw.visualizer.model.cfg.StateEntry;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class StateImpl implements State {
+ private String kind;
+ private int size;
+ private String method;
+ private StateEntry[] entries;
+
+ public StateImpl(String kind, int size, String method, StateEntryImpl[] entries) {
+ this.kind = kind;
+ this.size = size;
+ this.method = method;
+ this.entries = entries;
+ }
+
+ public String getKind() {
+ return kind;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public List getEntries() {
+ return Collections.unmodifiableList(Arrays.asList(entries));
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/ChildIntervalImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/ChildIntervalImpl.java
new file mode 100644
index 000000000000..4c2f40459b79
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/ChildIntervalImpl.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.ChildInterval;
+import at.ssw.visualizer.model.interval.Interval;
+import at.ssw.visualizer.model.interval.Range;
+import at.ssw.visualizer.model.interval.UsePosition;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class ChildIntervalImpl implements ChildInterval, Comparable {
+ private Interval parent;
+ private String regNum;
+ private String type;
+ private String operand;
+ private String spillState;
+ private ChildInterval registerHint;
+ private Range[] ranges;
+ private UsePosition[] usePositions;
+
+ public void setValues(String regNum, String type, String operand, String spillState, ChildInterval registerHint, Range[] ranges, UsePosition[] usePositions) {
+ this.regNum = regNum;
+ this.type = type;
+ this.operand = operand;
+ this.spillState = spillState;
+ this.registerHint = registerHint;
+ this.ranges = ranges;
+ this.usePositions = usePositions;
+ }
+
+ public Interval getParent() {
+ return parent;
+ }
+
+ protected void setParent(IntervalImpl parent) {
+ this.parent = parent;
+ }
+
+ public String getRegNum() {
+ return regNum;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getOperand() {
+ return operand;
+ }
+
+ public String getSpillState() {
+ return spillState;
+ }
+
+ public ChildInterval getRegisterHint() {
+ return registerHint;
+ }
+
+ public List getRanges() {
+ return Collections.unmodifiableList(Arrays.asList(ranges));
+ }
+
+ public List getUsePositions() {
+ return Collections.unmodifiableList(Arrays.asList(usePositions));
+ }
+
+
+ public int getFrom() {
+ return ranges[0].getFrom();
+ }
+
+ public int getTo() {
+ return ranges[ranges.length - 1].getTo();
+ }
+
+
+ public int compareTo(ChildIntervalImpl other) {
+ return getFrom() - other.getFrom();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append(regNum);
+ result.append(": ");
+ result.append(getType());
+ result.append(", ");
+ result.append(getOperand());
+ result.append(", ");
+ if (registerHint != null) {
+ result.append(registerHint.getRegNum());
+ } else {
+ result.append("null");
+ }
+
+ result.append(" ");
+ for (int i = 0; i < ranges.length; i++) {
+ if (i > 0) {
+ result.append(", ");
+ }
+ result.append(ranges[i]);
+ }
+
+ result.append(" ");
+ for (int i = 0; i < usePositions.length; i++) {
+ if (i > 0) {
+ result.append(", ");
+ }
+ result.append(usePositions[i]);
+ }
+
+ return result.toString();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/IntervalImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/IntervalImpl.java
new file mode 100644
index 000000000000..fc7c3d2d4a1b
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/IntervalImpl.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.ChildInterval;
+import at.ssw.visualizer.model.interval.Interval;
+import at.ssw.visualizer.model.interval.IntervalList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class IntervalImpl implements Interval {
+ private IntervalList parent;
+ private ChildInterval[] children;
+
+ public IntervalImpl(ChildIntervalImpl[] children) {
+ this.children = children;
+ for (ChildIntervalImpl child : children) {
+ child.setParent(this);
+ }
+ }
+
+ public IntervalList getParent() {
+ return parent;
+ }
+
+ protected void setParent(IntervalListImpl parent) {
+ this.parent = parent;
+ }
+
+ public List getChildren() {
+ return Collections.unmodifiableList(Arrays.asList(children));
+ }
+
+ public String getRegNum() {
+ return children[0].getRegNum();
+ }
+
+ public int getFrom() {
+ return children[0].getFrom();
+ }
+
+ public int getTo() {
+ return children[children.length - 1].getTo();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < children.length; i++) {
+ if (i > 0) {
+ result.append("\n ");
+ }
+ result.append(children[i]);
+ }
+ return result.toString();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/IntervalListImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/IntervalListImpl.java
new file mode 100644
index 000000000000..819294eba126
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/IntervalListImpl.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.interval.Interval;
+import at.ssw.visualizer.model.interval.IntervalList;
+import at.ssw.visualizer.modelimpl.CompilationElementImpl;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class IntervalListImpl extends CompilationElementImpl implements IntervalList {
+ private Interval[] intervals;
+ private ControlFlowGraph controlFlowGraph;
+ private int numLIROperations;
+
+ public IntervalListImpl(String shortName, String name, IntervalImpl[] intervals, ControlFlowGraph controlFlowGraph) {
+ super(shortName, name);
+ this.intervals = intervals;
+ this.controlFlowGraph = controlFlowGraph;
+
+ for (IntervalImpl interval : intervals) {
+ interval.setParent(this);
+ numLIROperations = Math.max(numLIROperations, interval.getTo());
+ }
+ for (BasicBlock basicBlock : controlFlowGraph.getBasicBlocks()) {
+ numLIROperations = Math.max(numLIROperations, basicBlock.getLastLirId() + 2);
+ }
+ }
+
+
+ public List getIntervals() {
+ return Collections.unmodifiableList(Arrays.asList(intervals));
+ }
+
+ public ControlFlowGraph getControlFlowGraph() {
+ return controlFlowGraph;
+ }
+
+ public int getNumLIROperations() {
+ return numLIROperations;
+ }
+
+
+ @Override
+ public String toString() {
+ return " Intervals \"" + getName() + "\": " + intervals.length + " intervals\n";
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/RangeImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/RangeImpl.java
new file mode 100644
index 000000000000..9d39e551ae35
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/RangeImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.Range;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class RangeImpl implements Range, Comparable {
+ private int from;
+ private int to;
+
+ public RangeImpl(int from, int to) {
+ this.from = from;
+ this.to = to;
+ }
+
+
+ public int getFrom() {
+ return from;
+ }
+
+ public int getTo() {
+ return to;
+ }
+
+
+ public int compareTo(RangeImpl other) {
+ return getFrom() - other.getFrom();
+ }
+
+ @Override
+ public String toString() {
+ return "[" + from + ", " + to + "]";
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/UsePositionImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/UsePositionImpl.java
new file mode 100644
index 000000000000..2e9a1e6719a3
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/interval/UsePositionImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.UsePosition;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class UsePositionImpl implements UsePosition, Comparable {
+ private int position;
+ private char kind;
+
+ public UsePositionImpl(int position, char kind) {
+ this.position = position;
+ this.kind = kind;
+ }
+
+
+ public char getKind() {
+ return kind;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+
+ public int compareTo(UsePositionImpl other) {
+ return getPosition() - other.getPosition();
+ }
+
+ @Override
+ public String toString() {
+ return position + "(" + kind + ")";
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/nc/NativeMethodImpl.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/nc/NativeMethodImpl.java
new file mode 100644
index 000000000000..523fdbbb7bd1
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/modelimpl/nc/NativeMethodImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.modelimpl.nc;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.nc.NativeMethod;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public class NativeMethodImpl implements NativeMethod {
+
+ private ControlFlowGraph controlFlowGraph;
+ private String methodText;
+
+ public NativeMethodImpl(ControlFlowGraph controlFlowGraph, String methodText) {
+ this.controlFlowGraph = controlFlowGraph;
+ this.methodText = methodText;
+ }
+
+ public ControlFlowGraph getControlFlowGraph() {
+ return controlFlowGraph;
+ }
+
+ public String getMethodText() {
+ return methodText;
+ }
+
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/BBHelper.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/BBHelper.java
new file mode 100644
index 000000000000..955e804cb12d
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/BBHelper.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import at.ssw.visualizer.model.cfg.State;
+import at.ssw.visualizer.modelimpl.cfg.BasicBlockImpl;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class BBHelper {
+
+ protected String name;
+ protected int fromBci;
+ protected int toBci;
+ protected String[] predecessors;
+ protected String[] successors;
+ protected String[] xhandlers;
+ protected String[] flags;
+ protected String dominator;
+ protected int loopIndex;
+ protected int loopDepth;
+ protected int firstLirId;
+ protected int lastLirId;
+ protected double probability = Double.NaN;
+ protected List states = new ArrayList();
+ protected List hirInstructions = new ArrayList();
+ protected List lirOperations = new ArrayList();
+ protected BasicBlockImpl basicBlock = new BasicBlockImpl();
+ protected List defPredecessorsList = new ArrayList();
+ protected List calcPredecessorsList = new ArrayList();
+ protected List successorsList = new ArrayList();
+ protected List xhandlersList = new ArrayList();
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CFGHelper.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CFGHelper.java
new file mode 100644
index 000000000000..c6ed49ec5d9b
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CFGHelper.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import at.ssw.visualizer.model.cfg.State;
+import at.ssw.visualizer.modelimpl.cfg.BasicBlockImpl;
+import at.ssw.visualizer.modelimpl.cfg.ControlFlowGraphImpl;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CFGHelper {
+
+ protected String shortName;
+ protected String name;
+ protected int id;
+ protected int parentId;
+ private Map helpers = new HashMap();
+ private List helpersList = new ArrayList();
+ protected List elements = new ArrayList();
+ protected ControlFlowGraphImpl resolved;
+
+ public void add(BBHelper helper) {
+ helpers.put(helper.name, helper);
+ helpersList.add(helper);
+ }
+
+ public ControlFlowGraphImpl resolve(CompilationHelper lastComp, Parser parser) {
+ for (BBHelper helper : helpersList) {
+ for (String predecessorName : helper.predecessors) {
+ BBHelper predecessor = helpers.get(predecessorName);
+ if (predecessor != null) {
+ helper.defPredecessorsList.add(predecessor.basicBlock);
+ } else {
+ // ignore
+ // parser.SemErr("Undefined predecessor: " + predecessorName);
+ }
+ }
+
+ for (String successorName : helper.successors) {
+ BBHelper successor = helpers.get(successorName);
+ if (successor != null) {
+ helper.successorsList.add(successor.basicBlock);
+ successor.calcPredecessorsList.add(helper.basicBlock);
+ } else {
+ // ignore
+ // parser.SemErr("Undefined successor: " + successorName);
+ }
+ }
+
+ for (String xhandlerName : helper.xhandlers) {
+ BBHelper xhandler = helpers.get(xhandlerName);
+ if (xhandler != null) {
+ helper.xhandlersList.add(xhandler.basicBlock);
+ xhandler.calcPredecessorsList.add(helper.basicBlock);
+ } else {
+ // ignore
+ // parser.SemErr("Undefined xhandler: " + xhandlerName);
+ }
+ }
+ }
+
+ BasicBlockImpl[] basicBlocks = new BasicBlockImpl[helpersList.size()];
+ int idx = 0;
+ for (BBHelper helper : helpersList) {
+ basicBlocks[idx++] = helper.basicBlock;
+
+ List predecessorsList;
+ if (helper.defPredecessorsList.size() > 0) {
+ // check if defined and calculated predecessors are equal
+ if (helper.defPredecessorsList.size() != helper.calcPredecessorsList.size()) {
+ parser.SemErr("Defined and calculated predecessors size different: " + helper.name);
+ } else {
+ for (BasicBlock block : helper.defPredecessorsList) {
+ if (!helper.calcPredecessorsList.remove(block)) {
+ parser.SemErr("Defined and calculated predecessors not matching: " + helper.name);
+ }
+ }
+ if (helper.calcPredecessorsList.size() > 0) {
+ // should never come here, but just checking...
+ parser.SemErr("Defined and calculated predecessors not matching: " + helper.name);
+ }
+ }
+ predecessorsList = helper.defPredecessorsList;
+ } else {
+ predecessorsList = helper.calcPredecessorsList;
+ }
+
+ BasicBlock[] predecessors = predecessorsList.toArray(new BasicBlock[predecessorsList.size()]);
+ BasicBlock[] successors = helper.successorsList.toArray(new BasicBlock[helper.successorsList.size()]);
+ BasicBlock[] xhandlers = helper.xhandlersList.toArray(new BasicBlock[helper.xhandlersList.size()]);
+
+ BasicBlock dominator = null;
+ if (helpers.get(helper.dominator) != null) {
+ dominator = helpers.get(helper.dominator).basicBlock;
+ }
+
+ State[] states = null;
+ if (helper.states.size() > 0) {
+ states = helper.states.toArray(new State[helper.states.size()]);
+ }
+
+ IRInstruction[] hirInstructions = null;
+ if (helper.hirInstructions.size() > 0) {
+ hirInstructions = helper.hirInstructions.toArray(new IRInstruction[helper.hirInstructions.size()]);
+ }
+ IRInstruction[] lirOperations = null;
+ if (helper.lirOperations.size() > 0) {
+ lirOperations = helper.lirOperations.toArray(new IRInstruction[helper.lirOperations.size()]);
+
+ if (helper.firstLirId == 0) {
+ try {
+ helper.firstLirId = Integer.parseInt(lirOperations[0].getValue(IRInstruction.LIR_NUMBER));
+ } catch (NumberFormatException ex) {
+ // Silently ignore invalid numbers.
+ }
+ }
+ if (helper.lastLirId == 0) {
+ try {
+ helper.lastLirId = Integer.parseInt(lirOperations[lirOperations.length - 1].getValue(IRInstruction.LIR_NUMBER));
+ } catch (NumberFormatException ex) {
+ // Silently ignore invalid numbers.
+ }
+ }
+ }
+
+ helper.basicBlock.setValues(helper.name, helper.fromBci, helper.toBci, predecessors, successors, xhandlers, helper.flags, dominator, helper.loopIndex, helper.loopDepth, helper.firstLirId, helper.lastLirId, helper.probability, states, hirInstructions, lirOperations);
+ }
+
+ resolved = new ControlFlowGraphImpl(shortName, name, basicBlocks);
+
+ if (parentId == 0) {
+ lastComp.elements.add(resolved);
+ } else {
+ CFGHelper parent = lastComp.idToCFG.get(parentId);
+ if (parent != null) {
+ parent.elements.add(resolved);
+ } else {
+ parser.SemErr("Undefined compilation id: " + parentId);
+ }
+ }
+ if (id != 0) {
+ lastComp.idToCFG.put(id, this);
+ }
+
+ return resolved;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilationHelper.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilationHelper.java
new file mode 100644
index 000000000000..d9ad0ee362ab
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilationHelper.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import at.ssw.visualizer.modelimpl.CompilationElementImpl;
+import at.ssw.visualizer.modelimpl.CompilationImpl;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CompilationHelper {
+ protected String shortName;
+ protected String name;
+ protected String method;
+ protected Date date;
+ protected List elements = new ArrayList();
+
+ protected Map idToCFG = new HashMap();
+
+ protected CompilationImpl resolve() {
+ CompilationImpl compilation = new CompilationImpl(shortName, name, method, date);
+
+ compilation.setElements(elements.toArray(new CompilationElementImpl[elements.size()]), compilation);
+ for (CFGHelper cfg : idToCFG.values()) {
+ cfg.resolved.setElements(cfg.elements.toArray(new CompilationElementImpl[cfg.elements.size()]), compilation);
+ }
+
+ return compilation;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilationParser.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilationParser.java
new file mode 100644
index 000000000000..1b698a886de6
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilationParser.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import at.ssw.visualizer.modelimpl.CompilationModelImpl;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
+import org.openide.util.Cancellable;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CompilationParser {
+ public static String parseInputFile(String fileName, CompilationModelImpl compilationData) {
+ ProgressHandle progressHandle = ProgressHandleFactory.createHandle("Parsing input file \"" + fileName + "\"", new CancelParsing());
+ Scanner scanner = null;
+ try {
+ scanner = new Scanner(fileName, progressHandle);
+ Parser parser = new Parser(scanner);
+ parser.setCompilationModel(compilationData);
+ parser.Parse();
+
+ if (parser.hasErrors()) {
+ return parser.getErrors();
+ } else {
+ return null;
+ }
+ } catch (UserCanceledError ex) {
+ // user canceled parsing, so report no error
+ return null;
+ } catch (Error ex) {
+ return ex.getMessage();
+ } catch (Throwable ex) {
+ // catch everything else that might happen
+ return ex.getClass().getName() + (ex.getMessage() != null ? ": " + ex.getMessage() : "");
+ } finally {
+ progressHandle.finish();
+ }
+ }
+
+ private static class CancelParsing implements Cancellable {
+ public boolean cancel() {
+ throw new UserCanceledError();
+ }
+ }
+
+ private static class UserCanceledError extends Error {
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilerOutput.atg b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilerOutput.atg
new file mode 100644
index 000000000000..3929bbd11eae
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/CompilerOutput.atg
@@ -0,0 +1,357 @@
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.Date;
+import java.util.List;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.modelimpl.CompilationImpl;
+import at.ssw.visualizer.modelimpl.CompilationModelImpl;
+import at.ssw.visualizer.modelimpl.cfg.ControlFlowGraphImpl;
+import at.ssw.visualizer.modelimpl.cfg.IRInstructionImpl;
+import at.ssw.visualizer.modelimpl.cfg.StateImpl;
+import at.ssw.visualizer.modelimpl.cfg.StateEntryImpl;
+import at.ssw.visualizer.modelimpl.interval.IntervalListImpl;
+import at.ssw.visualizer.modelimpl.interval.RangeImpl;
+import at.ssw.visualizer.modelimpl.interval.UsePositionImpl;
+import at.ssw.visualizer.modelimpl.nc.NativeMethodImpl;
+import at.ssw.visualizer.modelimpl.bc.BytecodesImpl;
+
+COMPILER InputFile
+
+private CompilationModelImpl compilationModel;
+
+public void setCompilationModel(CompilationModelImpl compilationModel) {
+ this.compilationModel = compilationModel;
+}
+
+private String simpleName(String className) {
+ int index = className.lastIndexOf('.');
+ if (index < 0) {
+ return className;
+ }
+ return className.substring(index + 1);
+}
+
+private String shortName(String name) {
+ name = longName(name);
+ String params = "";
+
+ int openParam = name.indexOf('(');
+ if (openParam >= 0) {
+ int closeParam = name.indexOf(')', openParam);
+ if (closeParam >= 0) {
+ String[] parts = name.substring(openParam + 1, closeParam).split(", *");
+ for (int i = 0; i < parts.length; i++) {
+ if (!params.isEmpty()) {
+ params += ",";
+ }
+ params += simpleName(parts[i]);
+ }
+ params = "(" + params + ")";
+ }
+ name = name.substring(0, openParam);
+ }
+
+ int methodPoint = name.lastIndexOf(".");
+ if (methodPoint < 0) {
+ return name + params;
+ }
+ int classPoint = name.lastIndexOf(".", methodPoint - 1);
+ if (classPoint < 0) {
+ return name + params;
+ }
+ return name.substring(classPoint + 1) + params;
+}
+
+private String longName(String name) {
+ return name.replace("::", ".");
+}
+
+CHARACTERS
+ identCh = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-|:*".
+ cr = '\r'.
+ lf = '\n'.
+
+TOKENS
+ ident = identCh { identCh }.
+
+IGNORE cr + lf
+
+/*-------------------------------------------------------------------------*/
+
+PRODUCTIONS
+
+
+InputFile = (. CompilationHelper lastComp = null;
+ ControlFlowGraphImpl lastCFG = null;
+ IntervalListImpl lastIL = null; .)
+{
+ Compilation (. if (lastComp != null) compilationModel.addCompilation(lastComp.resolve());
+ lastComp = curComp; .)
+|
+ CFG
+|
+ IntervalList (. lastComp.elements.add(lastIL); .)
+|
+ NativeMethod
+|
+ Bytecodes
+} (. if (lastComp != null) compilationModel.addCompilation(lastComp.resolve()); .)
+
+.
+
+
+Compilation = (. helper = new CompilationHelper(); .)
+"begin_compilation"
+ "name" StringValue (. helper.name = longName(name); helper.shortName = shortName(name); .)
+ "method" StringValue (. helper.method = longName(method); .)
+ "date" DateValue
+"end_compilation".
+
+
+
+CFG = (. CFGHelper helper = new CFGHelper(); .)
+"begin_cfg"
+ "name" StringValue (. helper.name = longName(name); helper.shortName = shortName(name); .)
+ [
+ "id" IntegerValue
+ "caller_id" IntegerValue
+ ]
+ {
+ BasicBlock (. helper.add(basicBlock); .)
+ } (. res = helper.resolve(lastComp, this); .)
+"end_cfg".
+
+
+BasicBlock = (. helper = new BBHelper(); .)
+"begin_block"
+ "name" StringValue
+ "from_bci" IntegerValue
+ "to_bci" IntegerValue
+
+ "predecessors" StringList
+ "successors" StringList
+ "xhandlers" StringList
+ "flags" StringList
+
+ [ "dominator" StringValue ]
+ [ "loop_index" IntegerValue ]
+ [ "loop_depth" IntegerValue ]
+ [ "first_lir_id" IntegerValue ]
+ [ "last_lir_id" IntegerValue ]
+ [ "probability" DoubleValue ]
+
+ [ StateList ]
+ [ HIR ]
+ [ LIR ]
+ { IR }
+"end_block".
+
+
+StateList =
+"begin_states"
+ {
+ "begin_stack"
+ State (. helper.states.add(state); .)
+ "end_stack"
+ |
+ "begin_locks"
+ State (. helper.states.add(state); .)
+ "end_locks"
+ |
+ "begin_locals"
+ State (. helper.states.add(state); .)
+ "end_locals"
+ }
+"end_states".
+
+
+State = (. String method = ""; ArrayList entries = new ArrayList(); .)
+ "size" IntegerValue
+ [ "method" StringValue ]
+ {
+ StateEntry (. entries.add(entry); .)
+ } (. res = new StateImpl(kind, size, longName(method), entries.toArray(new StateEntryImpl[entries.size()])); .)
+.
+
+StateEntry = (. String[] operands = null; String operand = null; .)
+ IntegerValue
+ HIRName
+ [
+ "[" (. ArrayList operandsList = new ArrayList(); .)
+ {
+ HIRName (. operandsList.add(opd); .)
+ }
+ "]" (. operands = operandsList.toArray(new String[operandsList.size()]); .)
+ ]
+ [
+ StringValue
+ ] (. res = new StateEntryImpl(index, name, operands, operand); .)
+.
+
+
+HIR =
+"begin_HIR"
+ {
+ HIRInstruction (. helper.hirInstructions.add(ins); .)
+ }
+"end_HIR".
+
+
+HIRInstruction = (. String pinned = ""; String operand = null; .)
+ [
+ "." (. pinned = "."; .)
+ ]
+ IntegerValue
+ IntegerValue
+ [
+ StringValue
+ ]
+ HIRName
+ FreeValue (. res = new IRInstructionImpl(pinned, bci, useCount, name, text, operand); .)
+.
+
+HIRName =
+ IdentValue (. if (res.charAt(0) >= '0' && res.charAt(0) <= '9') { res = "v" + res; res = res.intern(); } .)
+.
+
+
+LIR =
+"begin_LIR"
+ {
+ LIROperation (. helper.lirOperations.add(op); .)
+ }
+"end_LIR".
+
+
+LIROperation =
+ IntegerValue
+ FreeValue (. res = new IRInstructionImpl(number, text); .)
+.
+
+IR =
+"begin_IR"
+(
+ "HIR"
+ {
+ IRInstruction (. helper.hirInstructions.add(op); .)
+ }
+|
+ "LIR"
+ {
+ IRInstruction (. helper.lirOperations.add(op); .)
+ }
+)
+"end_IR".
+
+IRInstruction = (. LinkedHashMap data = new LinkedHashMap(); .)
+ {
+ IdentValue
+ FreeValue (. data.put(name.intern(), value.intern()); .)
+ }
+ "<|@" (. res = new IRInstructionImpl(data); .)
+.
+
+
+
+IntervalList =
+ (. IntervalListHelper helper = new IntervalListHelper(); IntervalHelper interval;
+ if (controlFlowGraph == null) SemErr("must have CFG before intervals"); .)
+"begin_intervals"
+ "name" StringValue (. helper.name = longName(name); helper.shortName = shortName(name); .)
+ {
+ Interval (. helper.add(interval); .)
+ } (. res = helper.resolve(this, controlFlowGraph); .)
+"end_intervals".
+
+
+Interval = (. helper = new IntervalHelper(); RangeImpl range; UsePositionImpl usePosition; .)
+ IdentValue
+ IdentValue
+ [ StringValue ]
+ IdentValue
+ IdentValue
+
+ Range (. helper.ranges.add(range); .)
+ {
+ Range (. helper.ranges.add(range); .)
+ }
+ {
+ UsePosition (. helper.usePositions.add(usePosition); .)
+ }
+
+ StringValue
+.
+
+
+Range =
+ "[" IntegerValue
+ "," IntegerValue "[" (. res = new RangeImpl(from, to); .)
+.
+
+
+UsePosition =
+ IntegerValue
+ IdentValue (. res = new UsePositionImpl(position, kindStr.charAt(0)); .)
+.
+
+
+NativeMethod =
+"begin_nmethod"
+ NoTrimFreeValue (. cfg.setNativeMethod(new NativeMethodImpl(cfg, res)); .)
+"end_nmethod"
+.
+
+
+Bytecodes =
+"begin_bytecodes"
+ FreeValue (. cfg.setBytecodes(new BytecodesImpl(cfg, res)); .)
+"end_bytecodes"
+.
+
+
+StringList = (. ArrayList list = new ArrayList(); String item; .)
+ {
+ StringValue (. list.add(item); .)
+ } (. res = list.toArray(new String[list.size()]); .)
+.
+
+
+StringValue =
+ "\"" (. int beg = la.pos; .)
+ { ANY } (. res = scanner.buffer.GetString(beg, la.pos).trim().intern(); .)
+ "\""
+.
+
+
+IdentValue =
+ ident (. res = t.val.trim().intern(); .)
+.
+
+
+IntegerValue = (. res = 0; .)
+ ident (. try { res = Integer.parseInt(t.val); } catch (NumberFormatException ex) { SemErr(t.val); } .)
+.
+
+
+DoubleValue = (. res = Double.NaN; .)
+ ident (. try { res = Double.longBitsToDouble(Long.parseLong(t.val)); } catch (NumberFormatException ex) { SemErr(t.val); } .)
+.
+
+
+DateValue = (. res = null; .)
+ ident (. try { res = new Date(Long.parseLong(t.val)); } catch (NumberFormatException ex) { SemErr(t.val); } .)
+.
+
+
+FreeValue = (. int beg = la.pos; .)
+ { ANY } (. res = scanner.buffer.GetString(beg, la.pos).trim(); if (res.indexOf('\r') != -1) { res = res.replace("\r\n", "\n"); } res = res.intern(); .)
+ "<|@"
+.
+
+NoTrimFreeValue = (. int beg = la.pos; .)
+ { ANY } (. res = scanner.buffer.GetString(beg, la.pos); if (res.indexOf('\r') != -1) { res = res.replace("\r\n", "\n"); } res = res.intern(); .)
+ "<|@"
+.
+
+END InputFile.
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/IntervalHelper.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/IntervalHelper.java
new file mode 100644
index 000000000000..77402a43e8f5
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/IntervalHelper.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+import at.ssw.visualizer.model.interval.Range;
+import at.ssw.visualizer.model.interval.UsePosition;
+import at.ssw.visualizer.modelimpl.interval.ChildIntervalImpl;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class IntervalHelper implements Comparable {
+ protected String regNum;
+ protected String type;
+ protected String operand = ""; // avoid null values if not defined
+ protected String splitParent;
+ protected String spillState;
+ protected String registerHint;
+
+ protected SortedSet ranges = new TreeSet();
+ protected SortedSet usePositions = new TreeSet();
+
+ protected ChildIntervalImpl childInterval = new ChildIntervalImpl();
+ protected SortedSet splitChildren = new TreeSet();
+
+ public int compareTo(IntervalHelper other) {
+ return ranges.first().getFrom() - other.ranges.first().getFrom();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/IntervalListHelper.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/IntervalListHelper.java
new file mode 100644
index 000000000000..118d1478856e
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/IntervalListHelper.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.util.Collection;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.interval.ChildInterval;
+import at.ssw.visualizer.model.interval.Range;
+import at.ssw.visualizer.model.interval.UsePosition;
+import at.ssw.visualizer.modelimpl.interval.ChildIntervalImpl;
+import at.ssw.visualizer.modelimpl.interval.IntervalImpl;
+import at.ssw.visualizer.modelimpl.interval.IntervalListImpl;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class IntervalListHelper {
+ protected String shortName;
+ protected String name;
+ protected LinkedHashMap helpers = new LinkedHashMap();
+
+ public void add(IntervalHelper helper) {
+ helpers.put(helper.regNum, helper);
+ }
+
+
+ public IntervalListImpl resolve(Parser parser, ControlFlowGraph controlFlowGraph) {
+ for (IntervalHelper helper : helpers.values()) {
+ ChildInterval registerHint = null;
+ if (helpers.containsKey(helper.registerHint)) {
+ registerHint = helpers.get(helper.registerHint).childInterval;
+ }
+ Range[] ranges = helper.ranges.toArray(new Range[helper.ranges.size()]);
+ UsePosition[] usePositions = helper.usePositions.toArray(new UsePosition[helper.usePositions.size()]);
+
+ helper.childInterval.setValues(helper.regNum, helper.type, helper.operand, helper.spillState, registerHint, ranges, usePositions);
+
+
+ IntervalHelper parent = helpers.get(helper.splitParent);
+ if (parent != null) {
+ parent.splitChildren.add(helper.childInterval);
+ } else {
+ parser.SemErr("Unknown split parent: " + helper.splitParent);
+ }
+ }
+
+ Collection intervals = new ArrayList();
+ for (IntervalHelper helper : helpers.values()) {
+ if (helper.splitChildren.size() > 0) {
+ ChildIntervalImpl[] children = helper.splitChildren.toArray(new ChildIntervalImpl[helper.splitChildren.size()]);
+ intervals.add(new IntervalImpl(children));
+ }
+ }
+
+ return new IntervalListImpl(shortName, name, intervals.toArray(new IntervalImpl[intervals.size()]), controlFlowGraph);
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Parser.frame b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Parser.frame
new file mode 100644
index 000000000000..638d40c26e97
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Parser.frame
@@ -0,0 +1,179 @@
+/*-------------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+ported from C# to Java by Wolfgang Ahorner
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program 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
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than
+Coco/R itself) does not fall under the GNU General Public License.
+------------------------------------------------------------------------*/
+-->begin
+
+public class Parser {
+-->constants
+ static final boolean _T = true;
+ static final boolean _x = false;
+ static final int minErrDist = 2;
+
+ public Token t; // last recognized token
+ public Token la; // lookahead token
+ int errDist = minErrDist;
+
+ public Scanner scanner;
+ public Errors errors;
+
+ public boolean hasErrors() {
+ return errors.errors.size() > 0;
+ }
+
+ public String getErrors() {
+ StringBuilder sb = new StringBuilder();
+ for (String s : errors.errors) {
+ sb.append(s);
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+
+ -->declarations
+
+ public Parser(Scanner scanner) {
+ this.scanner = scanner;
+ errors = new Errors();
+ }
+
+ void SynErr (int n) {
+ if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public void SemErr (String msg) {
+ if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ void Get () {
+ for (;;) {
+ t = la;
+ la = scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; }
+-->pragmas
+ la = t;
+ }
+ }
+
+ void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ boolean StartOf (int s) {
+ return set[s][la.kind];
+ }
+
+ void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+ boolean WeakSeparator (int n, int syFol, int repFol) {
+ int kind = la.kind;
+ if (kind == n) { Get(); return true; }
+ else if (StartOf(repFol)) return false;
+ else {
+ SynErr(n);
+ while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) {
+ Get();
+ kind = la.kind;
+ }
+ return StartOf(syFol);
+ }
+ }
+
+-->productions
+
+ public void Parse() {
+ la = new Token();
+ la.val = "";
+ Get();
+-->parseRoot
+ Expect(0);
+ }
+
+ private boolean[][] set = {
+-->initialization
+ };
+} // end Parser
+
+
+class Errors {
+ public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+ public ArrayList errors = new ArrayList();
+
+ protected void printMsg(int line, int column, String msg) {
+ StringBuffer b = new StringBuffer(errMsgFormat);
+ int pos = b.indexOf("{0}");
+ if (pos >= 0) { b.delete(pos, pos+3); b.insert(pos, line); }
+ pos = b.indexOf("{1}");
+ if (pos >= 0) { b.delete(pos, pos+3); b.insert(pos, column); }
+ pos = b.indexOf("{2}");
+ if (pos >= 0) b.replace(pos, pos+3, msg);
+ printMsg(b.toString());
+ }
+
+ protected void printMsg(String msg) {
+ if (errors.size() < 10) {
+ errors.add(msg);
+ }
+ }
+
+ public void SynErr (int line, int col, int n) {
+ String s;
+ switch (n) {-->errors
+ default: s = "error " + n; break;
+ }
+ printMsg(line, col, s);
+ }
+
+ public void SemErr (int line, int col, String s) {
+ printMsg(line, col, s);
+ }
+
+ public void SemErr (String s) {
+ printMsg(s);
+ }
+
+ public void Warning (int line, int col, String s) {
+ printMsg(line, col, s);
+ }
+
+ public void Warning (String s) {
+ printMsg(s);
+ }
+} // Errors
+
+
+class FatalError extends RuntimeException {
+ public FatalError(String s) { super(s); }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Parser.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Parser.java
new file mode 100644
index 000000000000..38b1ba9de1ae
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Parser.java
@@ -0,0 +1,721 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.Date;
+import java.util.List;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.modelimpl.CompilationImpl;
+import at.ssw.visualizer.modelimpl.CompilationModelImpl;
+import at.ssw.visualizer.modelimpl.cfg.ControlFlowGraphImpl;
+import at.ssw.visualizer.modelimpl.cfg.IRInstructionImpl;
+import at.ssw.visualizer.modelimpl.cfg.StateImpl;
+import at.ssw.visualizer.modelimpl.cfg.StateEntryImpl;
+import at.ssw.visualizer.modelimpl.interval.IntervalListImpl;
+import at.ssw.visualizer.modelimpl.interval.RangeImpl;
+import at.ssw.visualizer.modelimpl.interval.UsePositionImpl;
+import at.ssw.visualizer.modelimpl.nc.NativeMethodImpl;
+import at.ssw.visualizer.modelimpl.bc.BytecodesImpl;
+
+
+
+public class Parser {
+ public static final int _EOF = 0;
+ public static final int _ident = 1;
+ public static final int maxT = 54;
+
+ static final boolean _T = true;
+ static final boolean _x = false;
+ static final int minErrDist = 2;
+
+ public Token t; // last recognized token
+ public Token la; // lookahead token
+ int errDist = minErrDist;
+
+ public Scanner scanner;
+ public Errors errors;
+
+ public boolean hasErrors() {
+ return errors.errors.size() > 0;
+ }
+
+ public String getErrors() {
+ StringBuilder sb = new StringBuilder();
+ for (String s : errors.errors) {
+ sb.append(s);
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+
+ private CompilationModelImpl compilationModel;
+
+public void setCompilationModel(CompilationModelImpl compilationModel) {
+ this.compilationModel = compilationModel;
+}
+
+private String simpleName(String className) {
+ int index = className.lastIndexOf('.');
+ if (index < 0) {
+ return className;
+ }
+ return className.substring(index + 1);
+}
+
+private String shortName(String name) {
+ name = longName(name);
+ String params = "";
+
+ int openParam = name.indexOf('(');
+ if (openParam >= 0) {
+ int closeParam = name.indexOf(')', openParam);
+ if (closeParam >= 0) {
+ String[] parts = name.substring(openParam + 1, closeParam).split(", *");
+ for (int i = 0; i < parts.length; i++) {
+ if (!params.isEmpty()) {
+ params += ",";
+ }
+ params += simpleName(parts[i]);
+ }
+ params = "(" + params + ")";
+ }
+ name = name.substring(0, openParam);
+ }
+
+ int methodPoint = name.lastIndexOf(".");
+ if (methodPoint < 0) {
+ return name + params;
+ }
+ int classPoint = name.lastIndexOf(".", methodPoint - 1);
+ if (classPoint < 0) {
+ return name + params;
+ }
+ return name.substring(classPoint + 1) + params;
+}
+
+private String longName(String name) {
+ return name.replace("::", ".");
+}
+
+
+
+ public Parser(Scanner scanner) {
+ this.scanner = scanner;
+ errors = new Errors();
+ }
+
+ void SynErr (int n) {
+ if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
+ errDist = 0;
+ }
+
+ public void SemErr (String msg) {
+ if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
+ errDist = 0;
+ }
+
+ void Get () {
+ for (;;) {
+ t = la;
+ la = scanner.Scan();
+ if (la.kind <= maxT) { ++errDist; break; }
+
+ la = t;
+ }
+ }
+
+ void Expect (int n) {
+ if (la.kind==n) Get(); else { SynErr(n); }
+ }
+
+ boolean StartOf (int s) {
+ return set[s][la.kind];
+ }
+
+ void ExpectWeak (int n, int follow) {
+ if (la.kind == n) Get();
+ else {
+ SynErr(n);
+ while (!StartOf(follow)) Get();
+ }
+ }
+
+ boolean WeakSeparator (int n, int syFol, int repFol) {
+ int kind = la.kind;
+ if (kind == n) { Get(); return true; }
+ else if (StartOf(repFol)) return false;
+ else {
+ SynErr(n);
+ while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) {
+ Get();
+ kind = la.kind;
+ }
+ return StartOf(syFol);
+ }
+ }
+
+ void InputFile() {
+ CompilationHelper lastComp = null;
+ ControlFlowGraphImpl lastCFG = null;
+ IntervalListImpl lastIL = null;
+ while (StartOf(1)) {
+ if (la.kind == 2) {
+ CompilationHelper curComp = Compilation();
+ if (lastComp != null) compilationModel.addCompilation(lastComp.resolve());
+ lastComp = curComp;
+ } else if (la.kind == 7) {
+ lastCFG = CFG(lastComp);
+ } else if (la.kind == 46) {
+ lastIL = IntervalList(lastCFG);
+ lastComp.elements.add(lastIL);
+ } else if (la.kind == 49) {
+ NativeMethod(lastCFG);
+ } else {
+ Bytecodes(lastCFG);
+ }
+ }
+ if (lastComp != null) compilationModel.addCompilation(lastComp.resolve());
+ }
+
+ CompilationHelper Compilation() {
+ CompilationHelper helper;
+ helper = new CompilationHelper();
+ Expect(2);
+ Expect(3);
+ String name = StringValue();
+ helper.name = longName(name); helper.shortName = shortName(name);
+ Expect(4);
+ String method = StringValue();
+ helper.method = longName(method);
+ Expect(5);
+ helper.date = DateValue();
+ Expect(6);
+ return helper;
+ }
+
+ ControlFlowGraphImpl CFG(CompilationHelper lastComp) {
+ ControlFlowGraphImpl res;
+ CFGHelper helper = new CFGHelper();
+ Expect(7);
+ Expect(3);
+ String name = StringValue();
+ helper.name = longName(name); helper.shortName = shortName(name);
+ if (la.kind == 8) {
+ Get();
+ helper.id = IntegerValue();
+ Expect(9);
+ helper.parentId = IntegerValue();
+ }
+ while (la.kind == 11) {
+ BBHelper basicBlock = BasicBlock();
+ helper.add(basicBlock);
+ }
+ res = helper.resolve(lastComp, this);
+ Expect(10);
+ return res;
+ }
+
+ IntervalListImpl IntervalList(ControlFlowGraph controlFlowGraph) {
+ IntervalListImpl res;
+ IntervalListHelper helper = new IntervalListHelper(); IntervalHelper interval;
+ if (controlFlowGraph == null) SemErr("must have CFG before intervals");
+ Expect(46);
+ Expect(3);
+ String name = StringValue();
+ helper.name = longName(name); helper.shortName = shortName(name);
+ while (la.kind == 1) {
+ interval = Interval();
+ helper.add(interval);
+ }
+ res = helper.resolve(this, controlFlowGraph);
+ Expect(47);
+ return res;
+ }
+
+ void NativeMethod(ControlFlowGraphImpl cfg) {
+ Expect(49);
+ String res = NoTrimFreeValue();
+ cfg.setNativeMethod(new NativeMethodImpl(cfg, res));
+ Expect(50);
+ }
+
+ void Bytecodes(ControlFlowGraphImpl cfg) {
+ Expect(51);
+ String res = FreeValue();
+ cfg.setBytecodes(new BytecodesImpl(cfg, res));
+ Expect(52);
+ }
+
+ String StringValue() {
+ String res;
+ Expect(53);
+ long beg = la.pos;
+ while (StartOf(2)) {
+ Get();
+ }
+ res = scanner.buffer.GetString(beg, la.pos).trim().intern();
+ Expect(53);
+ return res;
+ }
+
+ Date DateValue() {
+ Date res;
+ res = null;
+ Expect(1);
+ try { res = new Date(Long.parseLong(t.val)); } catch (NumberFormatException ex) { SemErr(t.val); }
+ return res;
+ }
+
+ int IntegerValue() {
+ int res;
+ res = 0;
+ Expect(1);
+ try { res = Integer.parseInt(t.val); } catch (NumberFormatException ex) { SemErr(t.val); }
+ return res;
+ }
+
+ BBHelper BasicBlock() {
+ BBHelper helper;
+ helper = new BBHelper();
+ Expect(11);
+ Expect(3);
+ helper.name = StringValue();
+ Expect(12);
+ helper.fromBci = IntegerValue();
+ Expect(13);
+ helper.toBci = IntegerValue();
+ Expect(14);
+ helper.predecessors = StringList();
+ Expect(15);
+ helper.successors = StringList();
+ Expect(16);
+ helper.xhandlers = StringList();
+ Expect(17);
+ helper.flags = StringList();
+ if (la.kind == 18) {
+ Get();
+ helper.dominator = StringValue();
+ }
+ if (la.kind == 19) {
+ Get();
+ helper.loopIndex = IntegerValue();
+ }
+ if (la.kind == 20) {
+ Get();
+ helper.loopDepth = IntegerValue();
+ }
+ if (la.kind == 21) {
+ Get();
+ helper.firstLirId = IntegerValue();
+ }
+ if (la.kind == 22) {
+ Get();
+ helper.lastLirId = IntegerValue();
+ }
+ if (la.kind == 23) {
+ Get();
+ helper.probability = DoubleValue();
+ }
+ if (la.kind == 25) {
+ StateList(helper);
+ }
+ if (la.kind == 36) {
+ HIR(helper);
+ }
+ if (la.kind == 39) {
+ LIR(helper);
+ }
+ while (la.kind == 41) {
+ IR(helper);
+ }
+ Expect(24);
+ return helper;
+ }
+
+ String[] StringList() {
+ String[] res;
+ ArrayList list = new ArrayList(); String item;
+ while (la.kind == 53) {
+ item = StringValue();
+ list.add(item);
+ }
+ res = list.toArray(new String[list.size()]);
+ return res;
+ }
+
+ double DoubleValue() {
+ double res;
+ res = Double.NaN;
+ Expect(1);
+ try { res = Double.longBitsToDouble(Long.parseLong(t.val)); } catch (NumberFormatException ex) { SemErr(t.val); }
+ return res;
+ }
+
+ void StateList(BBHelper helper) {
+ Expect(25);
+ while (la.kind == 26 || la.kind == 28 || la.kind == 30) {
+ if (la.kind == 26) {
+ Get();
+ StateImpl state = State("Operands");
+ helper.states.add(state);
+ Expect(27);
+ } else if (la.kind == 28) {
+ Get();
+ StateImpl state = State("Locks");
+ helper.states.add(state);
+ Expect(29);
+ } else {
+ Get();
+ StateImpl state = State("Locals");
+ helper.states.add(state);
+ Expect(31);
+ }
+ }
+ Expect(32);
+ }
+
+ void HIR(BBHelper helper) {
+ Expect(36);
+ while (la.kind == 1 || la.kind == 38) {
+ IRInstructionImpl ins = HIRInstruction();
+ helper.hirInstructions.add(ins);
+ }
+ Expect(37);
+ }
+
+ void LIR(BBHelper helper) {
+ Expect(39);
+ while (la.kind == 1) {
+ IRInstructionImpl op = LIROperation();
+ helper.lirOperations.add(op);
+ }
+ Expect(40);
+ }
+
+ void IR(BBHelper helper) {
+ Expect(41);
+ if (la.kind == 42) {
+ Get();
+ while (la.kind == 1 || la.kind == 45) {
+ IRInstructionImpl op = IRInstruction();
+ helper.hirInstructions.add(op);
+ }
+ } else if (la.kind == 43) {
+ Get();
+ while (la.kind == 1 || la.kind == 45) {
+ IRInstructionImpl op = IRInstruction();
+ helper.lirOperations.add(op);
+ }
+ } else SynErr(55);
+ Expect(44);
+ }
+
+ StateImpl State(String kind) {
+ StateImpl res;
+ String method = ""; ArrayList entries = new ArrayList();
+ Expect(33);
+ int size = IntegerValue();
+ if (la.kind == 4) {
+ Get();
+ method = StringValue();
+ }
+ while (la.kind == 1) {
+ StateEntryImpl entry = StateEntry();
+ entries.add(entry);
+ }
+ res = new StateImpl(kind, size, longName(method), entries.toArray(new StateEntryImpl[entries.size()]));
+ return res;
+ }
+
+ StateEntryImpl StateEntry() {
+ StateEntryImpl res;
+ String[] operands = null; String operand = null;
+ int index = IntegerValue();
+ String name = HIRName();
+ if (la.kind == 34) {
+ Get();
+ ArrayList operandsList = new ArrayList();
+ while (la.kind == 1) {
+ String opd = HIRName();
+ operandsList.add(opd);
+ }
+ Expect(35);
+ operands = operandsList.toArray(new String[operandsList.size()]);
+ }
+ if (la.kind == 53) {
+ operand = StringValue();
+ }
+ res = new StateEntryImpl(index, name, operands, operand);
+ return res;
+ }
+
+ String HIRName() {
+ String res;
+ res = IdentValue();
+ if (res.charAt(0) >= '0' && res.charAt(0) <= '9') { res = "v" + res; res = res.intern(); }
+ return res;
+ }
+
+ IRInstructionImpl HIRInstruction() {
+ IRInstructionImpl res;
+ String pinned = ""; String operand = null;
+ if (la.kind == 38) {
+ Get();
+ pinned = ".";
+ }
+ int bci = IntegerValue();
+ int useCount = IntegerValue();
+ if (la.kind == 53) {
+ operand = StringValue();
+ }
+ String name = HIRName();
+ String text = FreeValue();
+ res = new IRInstructionImpl(pinned, bci, useCount, name, text, operand);
+ return res;
+ }
+
+ String FreeValue() {
+ String res;
+ long beg = la.pos;
+ while (StartOf(3)) {
+ Get();
+ }
+ res = scanner.buffer.GetString(beg, la.pos).trim(); if (res.indexOf('\r') != -1) { res = res.replace("\r\n", "\n"); } res = res.intern();
+ Expect(45);
+ return res;
+ }
+
+ String IdentValue() {
+ String res;
+ Expect(1);
+ res = t.val.trim().intern();
+ return res;
+ }
+
+ IRInstructionImpl LIROperation() {
+ IRInstructionImpl res;
+ int number = IntegerValue();
+ String text = FreeValue();
+ res = new IRInstructionImpl(number, text);
+ return res;
+ }
+
+ IRInstructionImpl IRInstruction() {
+ IRInstructionImpl res;
+ LinkedHashMap data = new LinkedHashMap();
+ while (la.kind == 1) {
+ String name = IdentValue();
+ String value = FreeValue();
+ data.put(name.intern(), value.intern());
+ }
+ Expect(45);
+ res = new IRInstructionImpl(data);
+ return res;
+ }
+
+ IntervalHelper Interval() {
+ IntervalHelper helper;
+ helper = new IntervalHelper(); RangeImpl range; UsePositionImpl usePosition;
+ helper.regNum = IdentValue();
+ helper.type = IdentValue();
+ if (la.kind == 53) {
+ helper.operand = StringValue();
+ }
+ helper.splitParent = IdentValue();
+ helper.registerHint = IdentValue();
+ range = Range();
+ helper.ranges.add(range);
+ while (la.kind == 34) {
+ range = Range();
+ helper.ranges.add(range);
+ }
+ while (la.kind == 1) {
+ usePosition = UsePosition();
+ helper.usePositions.add(usePosition);
+ }
+ helper.spillState = StringValue();
+ return helper;
+ }
+
+ RangeImpl Range() {
+ RangeImpl res;
+ Expect(34);
+ int from = IntegerValue();
+ Expect(48);
+ int to = IntegerValue();
+ Expect(34);
+ res = new RangeImpl(from, to);
+ return res;
+ }
+
+ UsePositionImpl UsePosition() {
+ UsePositionImpl res;
+ int position = IntegerValue();
+ String kindStr = IdentValue();
+ res = new UsePositionImpl(position, kindStr.charAt(0));
+ return res;
+ }
+
+ String NoTrimFreeValue() {
+ String res;
+ long beg = la.pos;
+ while (StartOf(3)) {
+ Get();
+ }
+ res = scanner.buffer.GetString(beg, la.pos); if (res.indexOf('\r') != -1) { res = res.replace("\r\n", "\n"); } res = res.intern();
+ Expect(45);
+ return res;
+ }
+
+
+
+ public void Parse() {
+ la = new Token();
+ la.val = "";
+ Get();
+ InputFile();
+ Expect(0);
+
+ Expect(0);
+ }
+
+ private boolean[][] set = {
+ {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x},
+ {_x,_x,_T,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_T,_x,_T, _x,_x,_x,_x},
+ {_x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_T,_x},
+ {_x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x}
+
+ };
+} // end Parser
+
+
+class Errors {
+ public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
+ public ArrayList errors = new ArrayList();
+
+ protected void printMsg(int line, int column, String msg) {
+ StringBuffer b = new StringBuffer(errMsgFormat);
+ int pos = b.indexOf("{0}");
+ if (pos >= 0) { b.delete(pos, pos+3); b.insert(pos, line); }
+ pos = b.indexOf("{1}");
+ if (pos >= 0) { b.delete(pos, pos+3); b.insert(pos, column); }
+ pos = b.indexOf("{2}");
+ if (pos >= 0) b.replace(pos, pos+3, msg);
+ printMsg(b.toString());
+ }
+
+ protected void printMsg(String msg) {
+ if (errors.size() < 10) {
+ errors.add(msg);
+ }
+ }
+
+ public void SynErr (int line, int col, int n) {
+ String s;
+ switch (n) {
+ case 0: s = "EOF expected"; break;
+ case 1: s = "ident expected"; break;
+ case 2: s = "\"begin_compilation\" expected"; break;
+ case 3: s = "\"name\" expected"; break;
+ case 4: s = "\"method\" expected"; break;
+ case 5: s = "\"date\" expected"; break;
+ case 6: s = "\"end_compilation\" expected"; break;
+ case 7: s = "\"begin_cfg\" expected"; break;
+ case 8: s = "\"id\" expected"; break;
+ case 9: s = "\"caller_id\" expected"; break;
+ case 10: s = "\"end_cfg\" expected"; break;
+ case 11: s = "\"begin_block\" expected"; break;
+ case 12: s = "\"from_bci\" expected"; break;
+ case 13: s = "\"to_bci\" expected"; break;
+ case 14: s = "\"predecessors\" expected"; break;
+ case 15: s = "\"successors\" expected"; break;
+ case 16: s = "\"xhandlers\" expected"; break;
+ case 17: s = "\"flags\" expected"; break;
+ case 18: s = "\"dominator\" expected"; break;
+ case 19: s = "\"loop_index\" expected"; break;
+ case 20: s = "\"loop_depth\" expected"; break;
+ case 21: s = "\"first_lir_id\" expected"; break;
+ case 22: s = "\"last_lir_id\" expected"; break;
+ case 23: s = "\"probability\" expected"; break;
+ case 24: s = "\"end_block\" expected"; break;
+ case 25: s = "\"begin_states\" expected"; break;
+ case 26: s = "\"begin_stack\" expected"; break;
+ case 27: s = "\"end_stack\" expected"; break;
+ case 28: s = "\"begin_locks\" expected"; break;
+ case 29: s = "\"end_locks\" expected"; break;
+ case 30: s = "\"begin_locals\" expected"; break;
+ case 31: s = "\"end_locals\" expected"; break;
+ case 32: s = "\"end_states\" expected"; break;
+ case 33: s = "\"size\" expected"; break;
+ case 34: s = "\"[\" expected"; break;
+ case 35: s = "\"]\" expected"; break;
+ case 36: s = "\"begin_HIR\" expected"; break;
+ case 37: s = "\"end_HIR\" expected"; break;
+ case 38: s = "\".\" expected"; break;
+ case 39: s = "\"begin_LIR\" expected"; break;
+ case 40: s = "\"end_LIR\" expected"; break;
+ case 41: s = "\"begin_IR\" expected"; break;
+ case 42: s = "\"HIR\" expected"; break;
+ case 43: s = "\"LIR\" expected"; break;
+ case 44: s = "\"end_IR\" expected"; break;
+ case 45: s = "\"<|@\" expected"; break;
+ case 46: s = "\"begin_intervals\" expected"; break;
+ case 47: s = "\"end_intervals\" expected"; break;
+ case 48: s = "\",\" expected"; break;
+ case 49: s = "\"begin_nmethod\" expected"; break;
+ case 50: s = "\"end_nmethod\" expected"; break;
+ case 51: s = "\"begin_bytecodes\" expected"; break;
+ case 52: s = "\"end_bytecodes\" expected"; break;
+ case 53: s = "\"\\\"\" expected"; break;
+ case 54: s = "??? expected"; break;
+ case 55: s = "invalid IR"; break;
+ default: s = "error " + n; break;
+ }
+ printMsg(line, col, s);
+ }
+
+ public void SemErr (int line, int col, String s) {
+ printMsg(line, col, s);
+ }
+
+ public void SemErr (String s) {
+ printMsg(s);
+ }
+
+ public void Warning (int line, int col, String s) {
+ printMsg(line, col, s);
+ }
+
+ public void Warning (String s) {
+ printMsg(s);
+ }
+} // Errors
+
+
+class FatalError extends RuntimeException {
+ public FatalError(String s) { super(s); }
+}
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Scanner.frame b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Scanner.frame
new file mode 100644
index 000000000000..fd8793afda2c
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Scanner.frame
@@ -0,0 +1,463 @@
+/*-------------------------------------------------------------------------
+Compiler Generator Coco/R,
+Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
+extended by M. Loeberbauer & A. Woess, Univ. of Linz
+ported from C# to Java by Wolfgang Ahorner
+with improvements by Pat Terry, Rhodes University
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program 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
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As an exception, it is allowed to write an extension of Coco/R that is
+used as a plugin in non-free software.
+
+If not otherwise stated, any source code generated by Coco/R (other than
+Coco/R itself) does not fall under the GNU General Public License.
+------------------------------------------------------------------------*/
+-->begin
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.HashMap;
+import org.netbeans.api.progress.ProgressHandle;
+
+class Token {
+ public int kind; // token kind
+ public int pos; // token position in bytes in the source text (starting at 0)
+ public int charPos; // token position in characters in the source text (starting at 0)
+ public int col; // token column (starting at 1)
+ public int line; // token line (starting at 1)
+ public String val; // token value
+ public Token next; // ML 2005-03-11 Peek tokens are kept in linked list
+}
+
+//-----------------------------------------------------------------------------------
+// Buffer
+//-----------------------------------------------------------------------------------
+class Buffer {
+ // This Buffer supports the following cases:
+ // 1) seekable stream (file)
+ // a) whole stream in buffer
+ // b) part of stream in buffer
+ // 2) non seekable stream (network, console)
+
+ public static final int EOF = Character.MAX_VALUE + 1;
+ private static final int MIN_BUFFER_LENGTH = 1024; // 1KB
+ private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+ private byte[] buf; // input buffer
+ private int bufStart; // position of first byte in buffer relative to input stream
+ private int bufLen; // length of buffer
+ private int fileLen; // length of input stream (may change if stream is no file)
+ private int bufPos; // current position in buffer
+ private RandomAccessFile file; // input stream (seekable)
+ private InputStream stream; // growing input stream (e.g.: console, network)
+ ProgressHandle progressHandle;
+ int maxSetPosValue;
+
+ public Buffer(InputStream s) {
+ stream = s;
+ fileLen = bufLen = bufStart = bufPos = 0;
+ buf = new byte[MIN_BUFFER_LENGTH];
+ }
+
+ public Buffer(String fileName, ProgressHandle progressHandle) {
+ this.progressHandle = progressHandle;
+ try {
+ file = new RandomAccessFile(fileName, "r");
+ fileLen = (int) file.length();
+ if (progressHandle != null) {
+ progressHandle.start((int)(fileLen / MAX_BUFFER_LENGTH));
+ }
+ bufLen = Math.min(fileLen, MAX_BUFFER_LENGTH);
+ buf = new byte[bufLen];
+ bufStart = Integer.MAX_VALUE; // nothing in buffer so far
+ if (fileLen > 0) setPos(0); // setup buffer to position 0 (start)
+ else bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid
+ if (bufLen == fileLen) Close();
+ } catch (IOException e) {
+ throw new FatalError("Could not open file " + fileName);
+ }
+ }
+
+ // don't use b after this call anymore
+ // called in UTF8Buffer constructor
+ protected Buffer(Buffer b) {
+ buf = b.buf;
+ bufStart = b.bufStart;
+ bufLen = b.bufLen;
+ fileLen = b.fileLen;
+ bufPos = b.bufPos;
+ file = b.file;
+ stream = b.stream;
+ // keep finalize from closing the file
+ b.file = null;
+ }
+
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Close();
+ }
+
+ protected void Close() {
+ if (file != null) {
+ try {
+ file.close();
+ file = null;
+ } catch (IOException e) {
+ throw new FatalError(e.getMessage());
+ }
+ }
+ }
+
+ public int Read() {
+ if (bufPos < bufLen) {
+ return buf[bufPos++] & 0xff; // mask out sign bits
+ } else if (getPos() < fileLen) {
+ setPos(getPos()); // shift buffer start to pos
+ return buf[bufPos++] & 0xff; // mask out sign bits
+ } else if (stream != null && ReadNextStreamChunk() > 0) {
+ return buf[bufPos++] & 0xff; // mask out sign bits
+ } else {
+ return EOF;
+ }
+ }
+
+ public int Peek() {
+ int curPos = getPos();
+ int ch = Read();
+ setPos(curPos);
+ return ch;
+ }
+
+ // beg .. begin, zero-based, inclusive, in byte
+ // end .. end, zero-based, exclusive, in byte
+ public String GetString(int beg, int end) {
+ int len = 0;
+ char[] buf = new char[end - beg];
+ int oldPos = getPos();
+ setPos(beg);
+ while (getPos() < end) buf[len++] = (char) Read();
+ setPos(oldPos);
+ return new String(buf, 0, len);
+ }
+
+ public int getPos() {
+ return bufPos + bufStart;
+ }
+
+ public void setPos(int value) {
+ if (value >= fileLen && stream != null) {
+ // Wanted position is after buffer and the stream
+ // is not seek-able e.g. network or console,
+ // thus we have to read the stream manually till
+ // the wanted position is in sight.
+ while (value >= fileLen && ReadNextStreamChunk() > 0);
+ }
+
+ if (value < 0 || value > fileLen) {
+ throw new FatalError("buffer out of bounds access, position: " + value);
+ }
+
+ if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+ bufPos = value - bufStart;
+ } else if (file != null) { // must be swapped in
+ try {
+ file.seek(value);
+ bufLen = file.read(buf);
+ bufStart = value; bufPos = 0;
+ } catch(IOException e) {
+ throw new FatalError(e.getMessage());
+ }
+ int newPosValue = (int)(value / MAX_BUFFER_LENGTH);
+ if (progressHandle != null && newPosValue > maxSetPosValue) {
+ progressHandle.progress(newPosValue);
+ maxSetPosValue = newPosValue;
+ }
+ } else {
+ // set the position to the end of the file, Pos will return fileLen.
+ bufPos = fileLen - bufStart;
+ }
+ }
+
+ // Read the next chunk of bytes from the stream, increases the buffer
+ // if needed and updates the fields fileLen and bufLen.
+ // Returns the number of bytes read.
+ private int ReadNextStreamChunk() {
+ int free = buf.length - bufLen;
+ if (free == 0) {
+ // in the case of a growing input stream
+ // we can neither seek in the stream, nor can we
+ // foresee the maximum length, thus we must adapt
+ // the buffer size on demand.
+ byte[] newBuf = new byte[bufLen * 2];
+ System.arraycopy(buf, 0, newBuf, 0, bufLen);
+ buf = newBuf;
+ free = bufLen;
+ }
+
+ int read;
+ try { read = stream.read(buf, bufLen, free); }
+ catch (IOException ioex) { throw new FatalError(ioex.getMessage()); }
+
+ if (read > 0) {
+ fileLen = bufLen = (bufLen + read);
+ return read;
+ }
+ // end of stream reached
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// UTF8Buffer
+//-----------------------------------------------------------------------------------
+class UTF8Buffer extends Buffer {
+ UTF8Buffer(Buffer b) { super(b); }
+
+ public int Read() {
+ int ch;
+ do {
+ ch = super.Read();
+ // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+ } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+ if (ch < 128 || ch == EOF) {
+ // nothing to do, first 127 chars are the same in ascii and utf8
+ // 0xxxxxxx or end of file character
+ } else if ((ch & 0xF0) == 0xF0) {
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x07; ch = super.Read();
+ int c2 = ch & 0x3F; ch = super.Read();
+ int c3 = ch & 0x3F; ch = super.Read();
+ int c4 = ch & 0x3F;
+ ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+ } else if ((ch & 0xE0) == 0xE0) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x0F; ch = super.Read();
+ int c2 = ch & 0x3F; ch = super.Read();
+ int c3 = ch & 0x3F;
+ ch = (((c1 << 6) | c2) << 6) | c3;
+ } else if ((ch & 0xC0) == 0xC0) {
+ // 110xxxxx 10xxxxxx
+ int c1 = ch & 0x1F; ch = super.Read();
+ int c2 = ch & 0x3F;
+ ch = (c1 << 6) | c2;
+ }
+ return ch;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// StartStates -- maps characters to start states of tokens
+//-----------------------------------------------------------------------------------
+class StartStates {
+ private static class Elem {
+ public int key, val;
+ public Elem next;
+ public Elem(int key, int val) { this.key = key; this.val = val; }
+ }
+
+ private Elem[] tab = new Elem[128];
+
+ public void set(int key, int val) {
+ Elem e = new Elem(key, val);
+ int k = key % 128;
+ e.next = tab[k]; tab[k] = e;
+ }
+
+ public int state(int key) {
+ Elem e = tab[key % 128];
+ while (e != null && e.key != key) e = e.next;
+ return e == null ? 0: e.val;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// Scanner
+//-----------------------------------------------------------------------------------
+public class Scanner {
+ static final char EOL = '\n';
+ static final int eofSym = 0;
+-->declarations
+
+ public Buffer buffer; // scanner buffer
+
+ Token t; // current token
+ int ch; // current input character
+ int pos; // byte position of current character
+ int charPos; // position by unicode characters starting with 0
+ int col; // column number of current character
+ int line; // line number of current character
+ int oldEols; // EOLs that appeared in a comment;
+ static final StartStates start; // maps initial token character to start state
+ static final Map literals; // maps literal strings to literal kinds
+ static int maxLiteral;
+ static boolean[] literalFirstChar;
+
+ Token tokens; // list of tokens already peeked (first token is a dummy)
+ Token pt; // current peek token
+
+ char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged
+ int tlen; // length of current token
+
+
+ static {
+ start = new StartStates();
+ literals = new HashMap();
+-->initialization
+ literalFirstChar = new boolean[0];
+ for (String literal : literals.keySet()) {
+ maxLiteral = Math.max(literal.length(), maxLiteral);
+ char c = literal.charAt(0);
+ if (c >= literalFirstChar.length) {
+ literalFirstChar = Arrays.copyOf(literalFirstChar, c + 1);
+ }
+ literalFirstChar[c] = true;
+ }
+ maxLiteral = 0;
+ literalFirstChar = null;
+ }
+
+ public Scanner (String fileName, ProgressHandle progressHandle) {
+ buffer = new Buffer(fileName, progressHandle);
+ Init();
+ }
+
+ public Scanner(InputStream s) {
+ buffer = new Buffer(s);
+ Init();
+ }
+
+ void Init () {
+ pos = -1; line = 1; col = 0; charPos = -1;
+ oldEols = 0;
+ NextCh();
+ if (ch == 0xEF) { // check optional byte order mark for UTF-8
+ NextCh(); int ch1 = ch;
+ NextCh(); int ch2 = ch;
+ if (ch1 != 0xBB || ch2 != 0xBF) {
+ throw new FatalError("Illegal byte order mark at start of file");
+ }
+ buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
+ NextCh();
+ }
+ pt = tokens = new Token(); // first token is a dummy
+ }
+
+ void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ pos = buffer.getPos();
+ // buffer reads unicode chars, if UTF8 has been detected
+ ch = buffer.Read(); col++; charPos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
+ if (ch == EOL) { line++; col = 0; }
+ }
+-->casing
+ }
+
+ void AddCh() {
+ if (tlen >= tval.length) {
+ char[] newBuf = new char[2 * tval.length];
+ System.arraycopy(tval, 0, newBuf, 0, tval.length);
+ tval = newBuf;
+ }
+ if (ch != Buffer.EOF) {
+-->casing2
+ NextCh();
+ }
+
+ }
+
+-->comments
+
+ void CheckLiteral() {
+ String val = t.val;
+-->casing3
+// if (maxLiteral == 0 || val.length() <= maxLiteral && val.length() > 0) {
+// char c = val.charAt(0);
+// if (literalFirstChar == null || c < literalFirstChar.length && literalFirstChar[c]) {
+ Object kind = literals.get(val);
+ if (kind != null) {
+ t.kind = ((Integer) kind).intValue();
+ }
+// }
+// }
+ }
+
+ Token NextToken() {
+ while (ch == ' ' ||
+-->scan1
+ ) NextCh();
+-->scan2
+ int recKind = noSym;
+ int recEnd = pos;
+ t = new Token();
+ t.pos = pos; t.col = col; t.line = line; t.charPos = charPos;
+ int state = start.state(ch);
+ tlen = 0; AddCh();
+
+ loop: for (;;) {
+ switch (state) {
+ case -1: { t.kind = eofSym; break loop; } // NextCh already done
+ case 0: {
+ if (recKind != noSym) {
+ tlen = recEnd - t.pos;
+ SetScannerBehindT();
+ }
+ t.kind = recKind; break loop;
+ } // NextCh already done
+-->scan3
+ }
+ }
+ t.val = new String(tval, 0, tlen);
+ return t;
+ }
+
+ private void SetScannerBehindT() {
+ buffer.setPos(t.pos);
+ NextCh();
+ line = t.line; col = t.col; charPos = t.charPos;
+ for (int i = 0; i < tlen; i++) NextCh();
+ }
+
+ // get the next token (possibly a token already seen during peeking)
+ public Token Scan () {
+ if (tokens.next == null) {
+ return NextToken();
+ } else {
+ pt = tokens = tokens.next;
+ return tokens;
+ }
+ }
+
+ // get the next token, ignore pragmas
+ public Token Peek () {
+ do {
+ if (pt.next == null) {
+ pt.next = NextToken();
+ }
+ pt = pt.next;
+ } while (pt.kind > maxT); // skip pragmas
+
+ return pt;
+ }
+
+ // make sure that peeking starts at current scan position
+ public void ResetPeek () { pt = tokens; }
+
+} // end Scanner
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Scanner.java b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Scanner.java
new file mode 100644
index 000000000000..3d312d3b811c
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/java/at/ssw/visualizer/parser/Scanner.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.parser;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.HashMap;
+import org.netbeans.api.progress.ProgressHandle;
+
+class Token {
+ public int kind; // token kind
+ public long pos; // token position in bytes in the source text (starting at 0)
+ public long charPos; // token position in characters in the source text (starting at 0)
+ public int col; // token column (starting at 1)
+ public int line; // token line (starting at 1)
+ public String val; // token value
+ public Token next; // ML 2005-03-11 Peek tokens are kept in linked list
+}
+
+//-----------------------------------------------------------------------------------
+// Buffer
+//-----------------------------------------------------------------------------------
+class Buffer {
+ // This Buffer supports the following cases:
+ // 1) seekable stream (file)
+ // a) whole stream in buffer
+ // b) part of stream in buffer
+ // 2) non seekable stream (network, console)
+
+ public static final int EOF = Character.MAX_VALUE + 1;
+ private static final int MIN_BUFFER_LENGTH = 1024; // 1KB
+ private static final int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
+ private byte[] buf; // input buffer
+ private long bufStart; // position of first byte in buffer relative to input stream
+ private int bufLen; // length of buffer
+ private long fileLen; // length of input stream (may change if stream is no file)
+ private int bufPos; // current position in buffer
+ private RandomAccessFile file; // input stream (seekable)
+ private InputStream stream; // growing input stream (e.g.: console, network)
+ ProgressHandle progressHandle;
+ int maxSetPosValue;
+
+ public Buffer(InputStream s) {
+ stream = s;
+ fileLen = 0;
+ bufLen = 0;
+ bufStart = 0;
+ bufPos = 0;
+ buf = new byte[MIN_BUFFER_LENGTH];
+ }
+
+ public Buffer(String fileName, ProgressHandle progressHandle) {
+ this.progressHandle = progressHandle;
+ try {
+ file = new RandomAccessFile(fileName, "r");
+ fileLen = file.length();
+ if (progressHandle != null) {
+ progressHandle.start((int)(fileLen / MAX_BUFFER_LENGTH));
+ }
+ bufLen = (int) Math.min(fileLen, MAX_BUFFER_LENGTH);
+ buf = new byte[bufLen];
+ bufStart = Long.MAX_VALUE; // nothing in buffer so far
+ if (fileLen > 0) setPos(0); // setup buffer to position 0 (start)
+ else bufPos = 0; // index 0 is already after the file, thus setPos(0) is invalid
+ if (bufLen == fileLen) Close();
+ } catch (IOException e) {
+ throw new FatalError("Could not open file " + fileName);
+ }
+ }
+
+ // don't use b after this call anymore
+ // called in UTF8Buffer constructor
+ protected Buffer(Buffer b) {
+ buf = b.buf;
+ bufStart = b.bufStart;
+ bufLen = b.bufLen;
+ fileLen = b.fileLen;
+ bufPos = b.bufPos;
+ file = b.file;
+ stream = b.stream;
+ // keep finalize from closing the file
+ b.file = null;
+ }
+
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Close();
+ }
+
+ protected void Close() {
+ if (file != null) {
+ try {
+ file.close();
+ file = null;
+ } catch (IOException e) {
+ throw new FatalError(e.getMessage());
+ }
+ }
+ }
+
+ public int Read() {
+ if (bufPos < bufLen) {
+ return buf[bufPos++] & 0xff; // mask out sign bits
+ } else if (getPos() < fileLen) {
+ setPos(getPos()); // shift buffer start to pos
+ return buf[bufPos++] & 0xff; // mask out sign bits
+ } else if (stream != null && ReadNextStreamChunk() > 0) {
+ return buf[bufPos++] & 0xff; // mask out sign bits
+ } else {
+ return EOF;
+ }
+ }
+
+ public int Peek() {
+ long curPos = getPos();
+ int ch = Read();
+ setPos(curPos);
+ return ch;
+ }
+
+ // beg .. begin, zero-based, inclusive, in byte
+ // end .. end, zero-based, exclusive, in byte
+ public String GetString(long beg, long end) {
+ int len = 0;
+ char[] buf = new char[(int) (end - beg)];
+ long oldPos = getPos();
+ setPos(beg);
+ while (getPos() < end) buf[len++] = (char) Read();
+ setPos(oldPos);
+ return new String(buf, 0, len);
+ }
+
+ public long getPos() {
+ return bufPos + bufStart;
+ }
+
+ public void setPos(long value) {
+ if (value >= fileLen && stream != null) {
+ // Wanted position is after buffer and the stream
+ // is not seek-able e.g. network or console,
+ // thus we have to read the stream manually till
+ // the wanted position is in sight.
+ while (value >= fileLen && ReadNextStreamChunk() > 0);
+ }
+
+ if (value < 0 || value > fileLen) {
+ throw new FatalError("buffer out of bounds access, position: " + value);
+ }
+
+ if (value >= bufStart && value < bufStart + bufLen) { // already in buffer
+ bufPos = (int) (value - bufStart);
+ } else if (file != null) { // must be swapped in
+ try {
+ file.seek(value);
+ bufLen = file.read(buf);
+ bufStart = value; bufPos = 0;
+ } catch(IOException e) {
+ throw new FatalError(e.getMessage());
+ }
+ int newPosValue = (int)(value / MAX_BUFFER_LENGTH);
+ if (progressHandle != null && newPosValue > maxSetPosValue) {
+ progressHandle.progress(newPosValue);
+ maxSetPosValue = newPosValue;
+ }
+ } else {
+ // set the position to the end of the file, Pos will return fileLen.
+ throw new InternalError();
+ }
+ }
+
+ // Read the next chunk of bytes from the stream, increases the buffer
+ // if needed and updates the fields fileLen and bufLen.
+ // Returns the number of bytes read.
+ private int ReadNextStreamChunk() {
+ int free = buf.length - bufLen;
+ if (free == 0) {
+ // in the case of a growing input stream
+ // we can neither seek in the stream, nor can we
+ // foresee the maximum length, thus we must adapt
+ // the buffer size on demand.
+ byte[] newBuf = new byte[bufLen * 2];
+ System.arraycopy(buf, 0, newBuf, 0, bufLen);
+ buf = newBuf;
+ free = bufLen;
+ }
+
+ int read;
+ try { read = stream.read(buf, bufLen, free); }
+ catch (IOException ioex) { throw new FatalError(ioex.getMessage()); }
+
+ if (read > 0) {
+ fileLen = bufLen = (bufLen + read);
+ return read;
+ }
+ // end of stream reached
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// UTF8Buffer
+//-----------------------------------------------------------------------------------
+class UTF8Buffer extends Buffer {
+ UTF8Buffer(Buffer b) { super(b); }
+
+ public int Read() {
+ int ch;
+ do {
+ ch = super.Read();
+ // until we find a utf8 start (0xxxxxxx or 11xxxxxx)
+ } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
+ if (ch < 128 || ch == EOF) {
+ // nothing to do, first 127 chars are the same in ascii and utf8
+ // 0xxxxxxx or end of file character
+ } else if ((ch & 0xF0) == 0xF0) {
+ // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x07; ch = super.Read();
+ int c2 = ch & 0x3F; ch = super.Read();
+ int c3 = ch & 0x3F; ch = super.Read();
+ int c4 = ch & 0x3F;
+ ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
+ } else if ((ch & 0xE0) == 0xE0) {
+ // 1110xxxx 10xxxxxx 10xxxxxx
+ int c1 = ch & 0x0F; ch = super.Read();
+ int c2 = ch & 0x3F; ch = super.Read();
+ int c3 = ch & 0x3F;
+ ch = (((c1 << 6) | c2) << 6) | c3;
+ } else if ((ch & 0xC0) == 0xC0) {
+ // 110xxxxx 10xxxxxx
+ int c1 = ch & 0x1F; ch = super.Read();
+ int c2 = ch & 0x3F;
+ ch = (c1 << 6) | c2;
+ }
+ return ch;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// StartStates -- maps characters to start states of tokens
+//-----------------------------------------------------------------------------------
+class StartStates {
+ private static class Elem {
+ public int key, val;
+ public Elem next;
+ public Elem(int key, int val) { this.key = key; this.val = val; }
+ }
+
+ private Elem[] tab = new Elem[128];
+
+ public void set(int key, int val) {
+ Elem e = new Elem(key, val);
+ int k = key % 128;
+ e.next = tab[k]; tab[k] = e;
+ }
+
+ public int state(int key) {
+ Elem e = tab[key % 128];
+ while (e != null && e.key != key) e = e.next;
+ return e == null ? 0: e.val;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// Scanner
+//-----------------------------------------------------------------------------------
+public class Scanner {
+ static final char EOL = '\n';
+ static final int eofSym = 0;
+ static final int maxT = 54;
+ static final int noSym = 54;
+
+
+ public Buffer buffer; // scanner buffer
+
+ Token t; // current token
+ int ch; // current input character
+ long pos; // byte position of current character
+ long charPos; // position by unicode characters starting with 0
+ int col; // column number of current character
+ int line; // line number of current character
+ int oldEols; // EOLs that appeared in a comment;
+ static final StartStates start; // maps initial token character to start state
+ static final Map literals; // maps literal strings to literal kinds
+ static int maxLiteral;
+ static boolean[] literalFirstChar;
+
+ Token tokens; // list of tokens already peeked (first token is a dummy)
+ Token pt; // current peek token
+
+ char[] tval = new char[16]; // token text used in NextToken(), dynamically enlarged
+ int tlen; // length of current token
+
+
+ static {
+ start = new StartStates();
+ literals = new HashMap();
+ for (int i = 42; i <= 42; ++i) start.set(i, 1);
+ for (int i = 45; i <= 45; ++i) start.set(i, 1);
+ for (int i = 48; i <= 58; ++i) start.set(i, 1);
+ for (int i = 65; i <= 90; ++i) start.set(i, 1);
+ for (int i = 95; i <= 95; ++i) start.set(i, 1);
+ for (int i = 97; i <= 122; ++i) start.set(i, 1);
+ for (int i = 124; i <= 124; ++i) start.set(i, 1);
+ start.set(91, 2);
+ start.set(93, 3);
+ start.set(46, 4);
+ start.set(60, 5);
+ start.set(44, 8);
+ start.set(34, 9);
+ start.set(Buffer.EOF, -1);
+ literals.put("begin_compilation", 2);
+ literals.put("name", 3);
+ literals.put("method", 4);
+ literals.put("date", 5);
+ literals.put("end_compilation", 6);
+ literals.put("begin_cfg", 7);
+ literals.put("id", 8);
+ literals.put("caller_id", 9);
+ literals.put("end_cfg", 10);
+ literals.put("begin_block", 11);
+ literals.put("from_bci", 12);
+ literals.put("to_bci", 13);
+ literals.put("predecessors", 14);
+ literals.put("successors", 15);
+ literals.put("xhandlers", 16);
+ literals.put("flags", 17);
+ literals.put("dominator", 18);
+ literals.put("loop_index", 19);
+ literals.put("loop_depth", 20);
+ literals.put("first_lir_id", 21);
+ literals.put("last_lir_id", 22);
+ literals.put("probability", 23);
+ literals.put("end_block", 24);
+ literals.put("begin_states", 25);
+ literals.put("begin_stack", 26);
+ literals.put("end_stack", 27);
+ literals.put("begin_locks", 28);
+ literals.put("end_locks", 29);
+ literals.put("begin_locals", 30);
+ literals.put("end_locals", 31);
+ literals.put("end_states", 32);
+ literals.put("size", 33);
+ literals.put("begin_HIR", 36);
+ literals.put("end_HIR", 37);
+ literals.put("begin_LIR", 39);
+ literals.put("end_LIR", 40);
+ literals.put("begin_IR", 41);
+ literals.put("HIR", 42);
+ literals.put("LIR", 43);
+ literals.put("end_IR", 44);
+ literals.put("begin_intervals", 46);
+ literals.put("end_intervals", 47);
+ literals.put("begin_nmethod", 49);
+ literals.put("end_nmethod", 50);
+ literals.put("begin_bytecodes", 51);
+ literals.put("end_bytecodes", 52);
+
+ literalFirstChar = new boolean[0];
+ for (String literal : literals.keySet()) {
+ maxLiteral = Math.max(literal.length(), maxLiteral);
+ char c = literal.charAt(0);
+ if (c >= literalFirstChar.length) {
+ literalFirstChar = Arrays.copyOf(literalFirstChar, c + 1);
+ }
+ literalFirstChar[c] = true;
+ }
+ maxLiteral = 0;
+ literalFirstChar = null;
+ }
+
+ public Scanner (String fileName, ProgressHandle progressHandle) {
+ buffer = new Buffer(fileName, progressHandle);
+ Init();
+ }
+
+ public Scanner(InputStream s) {
+ buffer = new Buffer(s);
+ Init();
+ }
+
+ void Init () {
+ pos = -1; line = 1; col = 0; charPos = -1;
+ oldEols = 0;
+ NextCh();
+ if (ch == 0xEF) { // check optional byte order mark for UTF-8
+ NextCh(); int ch1 = ch;
+ NextCh(); int ch2 = ch;
+ if (ch1 != 0xBB || ch2 != 0xBF) {
+ throw new FatalError("Illegal byte order mark at start of file");
+ }
+ buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
+ NextCh();
+ }
+ pt = tokens = new Token(); // first token is a dummy
+ }
+
+ void NextCh() {
+ if (oldEols > 0) { ch = EOL; oldEols--; }
+ else {
+ pos = buffer.getPos();
+ // buffer reads unicode chars, if UTF8 has been detected
+ ch = buffer.Read(); col++; charPos++;
+ // replace isolated '\r' by '\n' in order to make
+ // eol handling uniform across Windows, Unix and Mac
+ if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
+ if (ch == EOL) { line++; col = 0; }
+ }
+
+ }
+
+ void AddCh() {
+ if (tlen >= tval.length) {
+ char[] newBuf = new char[2 * tval.length];
+ System.arraycopy(tval, 0, newBuf, 0, tval.length);
+ tval = newBuf;
+ }
+ if (ch != Buffer.EOF) {
+ tval[tlen++] = (char)ch;
+
+ NextCh();
+ }
+
+ }
+
+
+
+ void CheckLiteral() {
+ String val = t.val;
+
+// if (maxLiteral == 0 || val.length() <= maxLiteral && val.length() > 0) {
+// char c = val.charAt(0);
+// if (literalFirstChar == null || c < literalFirstChar.length && literalFirstChar[c]) {
+ Object kind = literals.get(val);
+ if (kind != null) {
+ t.kind = ((Integer) kind).intValue();
+ }
+// }
+// }
+ }
+
+ Token NextToken() {
+ while (ch == ' ' ||
+ ch == 10 || ch == 13
+ ) NextCh();
+
+ int recKind = noSym;
+ long recEnd = pos;
+ t = new Token();
+ t.pos = pos; t.col = col; t.line = line; t.charPos = charPos;
+ int state = start.state(ch);
+ tlen = 0; AddCh();
+
+ loop: for (;;) {
+ switch (state) {
+ case -1: { t.kind = eofSym; break loop; } // NextCh already done
+ case 0: {
+ if (recKind != noSym) {
+ tlen = Math.toIntExact(recEnd - t.pos);
+ SetScannerBehindT();
+ }
+ t.kind = recKind; break loop;
+ } // NextCh already done
+ case 1:
+ recEnd = pos; recKind = 1;
+ if (ch == '*' || ch == '-' || ch >= '0' && ch <= ':' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z' || ch == '|') {AddCh(); state = 1; break;}
+ else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
+ case 2:
+ {t.kind = 34; break loop;}
+ case 3:
+ {t.kind = 35; break loop;}
+ case 4:
+ {t.kind = 38; break loop;}
+ case 5:
+ if (ch == '|') {AddCh(); state = 6; break;}
+ else {state = 0; break;}
+ case 6:
+ if (ch == '@') {AddCh(); state = 7; break;}
+ else {state = 0; break;}
+ case 7:
+ {t.kind = 45; break loop;}
+ case 8:
+ {t.kind = 48; break loop;}
+ case 9:
+ {t.kind = 53; break loop;}
+
+ }
+ }
+ t.val = new String(tval, 0, tlen);
+ return t;
+ }
+
+ private void SetScannerBehindT() {
+ buffer.setPos(t.pos);
+ NextCh();
+ line = t.line; col = t.col; charPos = t.charPos;
+ for (int i = 0; i < tlen; i++) NextCh();
+ }
+
+ // get the next token (possibly a token already seen during peeking)
+ public Token Scan () {
+ if (tokens.next == null) {
+ return NextToken();
+ } else {
+ pt = tokens = tokens.next;
+ return tokens;
+ }
+ }
+
+ // get the next token, ignore pragmas
+ public Token Peek () {
+ do {
+ if (pt.next == null) {
+ pt.next = NextToken();
+ }
+ pt = pt.next;
+ } while (pt.kind > maxT); // skip pragmas
+
+ return pt;
+ }
+
+ // make sure that peeking starts at current scan position
+ public void ResetPeek () { pt = tokens; }
+
+} // end Scanner
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/nbm/manifest.mf b/visualizer/C1Visualizer/CompilationModel/src/main/nbm/manifest.mf
new file mode 100644
index 000000000000..9a47908b4c88
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/nbm/manifest.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.model
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/model/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/resources/META-INF/services/at.ssw.visualizer.model.CompilationModel b/visualizer/C1Visualizer/CompilationModel/src/main/resources/META-INF/services/at.ssw.visualizer.model.CompilationModel
new file mode 100644
index 000000000000..5c61a429118c
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/resources/META-INF/services/at.ssw.visualizer.model.CompilationModel
@@ -0,0 +1 @@
+at.ssw.visualizer.modelimpl.CompilationModelImpl
\ No newline at end of file
diff --git a/visualizer/C1Visualizer/CompilationModel/src/main/resources/at/ssw/visualizer/model/Bundle.properties b/visualizer/C1Visualizer/CompilationModel/src/main/resources/at/ssw/visualizer/model/Bundle.properties
new file mode 100644
index 000000000000..876abe05faf5
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationModel/src/main/resources/at/ssw/visualizer/model/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=Compilation Model
diff --git a/visualizer/C1Visualizer/CompilationView/pom.xml b/visualizer/C1Visualizer/CompilationView/pom.xml
new file mode 100644
index 000000000000..97286b56757b
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/pom.xml
@@ -0,0 +1,137 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ CompilationView
+ 1.14-SNAPSHOT
+ nbm
+ CompilationView
+
+ UTF-8
+
+
+
+ at.ssw.visualizer
+ VisualizerUI
+ ${project.version}
+
+
+ at.ssw.visualizer
+ CompilationModel
+ ${project.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-editor-mimelookup
+ ${netbeans.version}
+
+
+ org.netbeans.modules
+ org-netbeans-modules-editor-mimelookup-impl
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-sendopts
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-actions
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-awt
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-dialogs
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-explorer
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-filesystems
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-loaders
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-nodes
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-ui
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-windows
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.CompilationView
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/CompilationModelNode.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/CompilationModelNode.java
new file mode 100644
index 000000000000..5acb276c769b
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/CompilationModelNode.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view;
+
+import at.ssw.visualizer.compilation.view.icons.Icons;
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.CompilationElement;
+import at.ssw.visualizer.model.CompilationModel;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import javax.swing.Action;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.ImageUtilities;
+import org.openide.util.lookup.Lookups;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class CompilationModelNode extends AbstractNode {
+ protected Image ImageFolder = ImageUtilities.loadImage(Icons.FOLDER);
+ protected Image ImageCfg = ImageUtilities.loadImage(Icons.CFG);
+ protected Image ImageIntervals = ImageUtilities.loadImage(Icons.INTERVALS);
+ protected boolean sortCompilations;
+ protected boolean filterCfg;
+ protected boolean shortNames;
+
+ public CompilationModelNode(CompilationModel model) {
+ super(Children.LEAF);
+ setChildren(new CompilationModelChildren(model));
+ }
+
+ public void doRefresh(boolean sortCompilations, boolean filterCfg, boolean shortNames) {
+ this.sortCompilations = sortCompilations;
+ this.filterCfg = filterCfg;
+ this.shortNames = shortNames;
+
+ ((CompilationModelChildren) getChildren()).doRefresh();
+ }
+
+ @Override
+ public Action[] getActions(boolean context) {
+ return new Action[0];
+ }
+
+ class CompilationModelChildren extends Children.Keys {
+ private CompilationModel model;
+ private ChangeListener changeListener = new ChangeListener() {
+ public void stateChanged(ChangeEvent event) {
+ addNotify();
+ }
+
+ };
+
+ public CompilationModelChildren(CompilationModel model) {
+ this.model = model;
+ model.addChangedListener(changeListener);
+ }
+
+ public void doRefresh() {
+ addNotify();
+ for (Node n : getNodes()) {
+ ((CompilationNode) n).doRefresh();
+ }
+ }
+
+ @Override
+ protected void addNotify() {
+ Compilation[] compilations = model.getCompilations().toArray(new Compilation[0]);
+ if (sortCompilations) {
+ Arrays.sort(compilations, new Comparator() {
+ public int compare(Compilation o1, Compilation o2) {
+ if (shortNames) {
+ return o1.getShortName().compareToIgnoreCase(o2.getShortName());
+ }
+ return o1.getName().compareToIgnoreCase(o2.getName());
+ }
+
+ });
+ }
+ setKeys(compilations);
+ }
+
+ protected Node[] createNodes(Compilation key) {
+ return new Node[]{new CompilationNode(key)};
+ }
+
+ }
+
+ class CompilationElementNode extends AbstractNode {
+ private CompilationElement element;
+
+ public CompilationElementNode(CompilationElement element) {
+ super(element.getElements().size() > 0 ? new CompilationElementChildren(element) : Children.LEAF, Lookups.singleton(element));
+ this.element = element;
+ }
+
+ public void doRefresh() {
+ fireNameChange(null, null);
+ if (getChildren() instanceof CompilationElementChildren) {
+ ((CompilationElementChildren) getChildren()).doRefresh();
+ }
+ }
+
+ @Override
+ public String getName() {
+ if (shortNames) {
+ return element.getShortName();
+ }
+ return element.getName();
+ }
+
+ @Override
+ public String getShortDescription() {
+ return element.getName();
+ }
+
+ @Override
+ public Image getIcon(int type) {
+ return element instanceof ControlFlowGraph ? ImageCfg : ImageIntervals;
+ }
+
+ @Override
+ public Image getOpenedIcon(int type) {
+ return getIcon(type);
+ }
+
+ @Override
+ public Action[] getActions(boolean context) {
+ String path = element instanceof ControlFlowGraph ? CompilationViewTopComponent.ACTIONS_CFG : CompilationViewTopComponent.ACTIONS_INTERVALS;
+ return Lookups.forPath(path).lookupAll(Action.class).toArray(new Action[0]);
+ }
+
+ @Override
+ public Action getPreferredAction() {
+ for (Action action : getActions(false)) {
+ if (action.isEnabled()) {
+ return action;
+ }
+ }
+ return null;
+ }
+
+ }
+
+ class CompilationNode extends CompilationElementNode {
+ public CompilationNode(Compilation compilation) {
+ super(compilation);
+ }
+
+ @Override
+ public Image getIcon(int type) {
+ return ImageFolder;
+ }
+
+ @Override
+ public Action[] getActions(boolean context) {
+ return Lookups.forPath(CompilationViewTopComponent.ACTIONS_COMPILATION).lookupAll(Action.class).toArray(new Action[0]);
+ }
+
+ @Override
+ public Action getPreferredAction() {
+ return null;
+ }
+
+ }
+
+ class CompilationElementChildren extends Children.Keys {
+ private CompilationElement compilation;
+
+ public CompilationElementChildren(CompilationElement compilation) {
+ this.compilation = compilation;
+ }
+
+ public void doRefresh() {
+ addNotify();
+ for (Node n : getNodes()) {
+ ((CompilationElementNode) n).doRefresh();
+ }
+ }
+
+ @Override
+ protected void addNotify() {
+ List elements = new ArrayList();
+ for (CompilationElement element : compilation.getElements()) {
+ if (!filterCfg || element.getCompilation() != element.getParent() || !(element instanceof ControlFlowGraph) || ((ControlFlowGraph) element).hasHir() || ((ControlFlowGraph) element).hasLir()|| ((ControlFlowGraph) element).getNativeMethod() != null) {
+ elements.add(element);
+ }
+ }
+ setKeys(elements);
+ }
+
+ protected Node[] createNodes(CompilationElement key) {
+ return new Node[]{new CompilationElementNode(key)};
+ }
+
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/CompilationViewTopComponent.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/CompilationViewTopComponent.java
new file mode 100644
index 000000000000..e96743d23bb9
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/CompilationViewTopComponent.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view;
+
+import at.ssw.visualizer.compilation.view.action.OpenCompilationAction;
+import at.ssw.visualizer.compilation.view.icons.Icons;
+import at.ssw.visualizer.model.CompilationModel;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyVetoException;
+import java.io.Serializable;
+import java.util.Collection;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import org.openide.awt.Toolbar;
+import org.openide.awt.ToolbarPool;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.nodes.Node;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+import org.openide.util.actions.Presenter;
+import org.openide.util.lookup.Lookups;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * Explorer-like view of all compiled methods.
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+public final class CompilationViewTopComponent extends TopComponent implements ExplorerManager.Provider {
+
+ public static final String ACTIONS_COMPILATION = "at-ssw-visualizer-actions-compilation";
+ public static final String ACTIONS_CFG = "at-ssw-visualizer-actions-cfg";
+ public static final String ACTIONS_INTERVALS = "at-ssw-visualizer-actions-intervals";
+ protected ExplorerManager manager;
+ protected BeanTreeView view;
+ protected CompilationModelNode rootNode;
+ protected JToggleButton sortButton;
+ protected JToggleButton filterButton;
+ protected JToggleButton packageButton;
+
+ private CompilationViewTopComponent() {
+ setName("Compiled Methods");
+ setToolTipText("List of Compiled Methods");
+ setIcon(ImageUtilities.loadImage(Icons.COMPILATIONS));
+
+ manager = new ExplorerManager();
+ view = new BeanTreeView();
+ view.setRootVisible(false);
+
+ setLayout(new BorderLayout());
+ add(createToolbar(), BorderLayout.NORTH);
+ add(view, BorderLayout.CENTER);
+
+ CompilationModel model = Lookup.getDefault().lookup(CompilationModel.class);
+ rootNode = new CompilationModelNode(model);
+ manager.setRootContext(rootNode);
+ associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+
+ configButtonListener.actionPerformed(null);
+ }
+
+ private Toolbar createToolbar() {
+ ToolbarPool.getDefault().setPreferredIconSize(16);
+
+ Toolbar toolBar = new Toolbar();
+ toolBar.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border"));
+
+ toolBar.add(new OpenCompilationAction());
+ toolBar.addSeparator();
+ addElements(toolBar, Lookups.forPath(CompilationViewTopComponent.ACTIONS_COMPILATION).lookupAll(Action.class));
+ toolBar.addSeparator();
+ addElements(toolBar, Lookups.forPath(CompilationViewTopComponent.ACTIONS_CFG).lookupAll(Action.class));
+ toolBar.addSeparator();
+ addElements(toolBar, Lookups.forPath(CompilationViewTopComponent.ACTIONS_INTERVALS).lookupAll(Action.class));
+
+ toolBar.addSeparator();
+ sortButton = new JToggleButton(new ImageIcon(ImageUtilities.loadImage(Icons.SORT)), false);
+ sortButton.setToolTipText("Sort List of Compilations");
+ sortButton.addActionListener(configButtonListener);
+ toolBar.add(sortButton);
+ filterButton = new JToggleButton(new ImageIcon(ImageUtilities.loadImage(Icons.FILTER)), true);
+ filterButton.addActionListener(configButtonListener);
+ filterButton.setToolTipText("Filter Control Flow Graphs that have no IR (generated during bytecode parsing phase)");
+ toolBar.add(filterButton);
+ packageButton = new JToggleButton(new ImageIcon(ImageUtilities.loadImage(Icons.PACKAGE)), false);
+ packageButton.addActionListener(configButtonListener);
+ packageButton.setToolTipText("Show Package Names");
+ toolBar.add(packageButton);
+ toolBar.addSeparator();
+ JButton collapseAllButton = new JButton(new ImageIcon(ImageUtilities.loadImage(Icons.COLLAPSE_ALL)));
+ collapseAllButton.addActionListener(collapseAllListener);
+ collapseAllButton.setToolTipText("Collapse All");
+ toolBar.add(collapseAllButton);
+
+ return toolBar;
+ }
+
+ private void addElements(JToolBar toolBar, Collection extends Action> actions) {
+ for (Action action : actions) {
+ if (action instanceof Presenter.Toolbar) {
+ toolBar.add(((Presenter.Toolbar) action).getToolbarPresenter());
+ } else {
+ toolBar.add(action);
+ }
+ }
+ }
+
+ @Override
+ public Dimension getMinimumSize() {
+ return new Dimension(0, 0);
+ }
+
+ public ExplorerManager getExplorerManager() {
+ return manager;
+ }
+ private ActionListener configButtonListener = new ActionListener() {
+
+ public void actionPerformed(ActionEvent event) {
+ org.openide.nodes.Node[] selectedNodes = manager.getSelectedNodes();
+ rootNode.doRefresh(sortButton.isSelected(), filterButton.isSelected(), !packageButton.isSelected());
+ try {
+ manager.setSelectedNodes(selectedNodes);
+ } catch (PropertyVetoException ex) {
+ throw new Error(ex);
+ }
+ }
+ };
+ private ActionListener collapseAllListener = new ActionListener() {
+
+ public void actionPerformed(ActionEvent event) {
+ for (Node n : rootNode.getChildren().getNodes()) {
+ view.collapseNode(n);
+ }
+ }
+ };
+ //
+ private static final String PREFERRED_ID = "CompilationViewTopComponent";
+ private static CompilationViewTopComponent instance;
+
+ public static synchronized CompilationViewTopComponent getDefault() {
+ if (instance == null) {
+ instance = new CompilationViewTopComponent();
+ }
+ return instance;
+ }
+
+ public static synchronized CompilationViewTopComponent findInstance() {
+ return (CompilationViewTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+ }
+
+ @Override
+ public int getPersistenceType() {
+ return PERSISTENCE_ALWAYS;
+ }
+
+ @Override
+ protected String preferredID() {
+ return PREFERRED_ID;
+ }
+
+ @Override
+ public Object writeReplace() {
+ return new ResolvableHelper();
+ }
+
+ static final class ResolvableHelper implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public Object readResolve() {
+ return CompilationViewTopComponent.getDefault();
+ }
+ }
+ //
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/ShowCompilationViewAction.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/ShowCompilationViewAction.java
new file mode 100644
index 000000000000..aff1a42082a2
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/ShowCompilationViewAction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.windows.TopComponent;
+
+/**
+ * Action which shows Compilation component.
+ *
+ * @author Bernhard Stiftner
+ */
+public class ShowCompilationViewAction extends AbstractAction {
+ public ShowCompilationViewAction() {
+ super("Compiled Methods");
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ TopComponent win = CompilationViewTopComponent.findInstance();
+ win.open();
+ win.requestActive();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/C1VisualizerDataObject.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/C1VisualizerDataObject.java
new file mode 100644
index 000000000000..37adb7d10508
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/C1VisualizerDataObject.java
@@ -0,0 +1,100 @@
+/*
+ * 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 at.ssw.visualizer.compilation.view.action;
+
+import at.ssw.visualizer.model.CompilationModel;
+import org.netbeans.api.actions.Openable;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.cookies.OpenCookie;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.MIMEResolver;
+import org.openide.loaders.DataObject;
+import org.openide.loaders.DataObjectExistsException;
+import org.openide.loaders.MultiDataObject;
+import org.openide.loaders.MultiFileLoader;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+import org.openide.util.RequestProcessor;
+
+import java.io.File;
+
+/**
+ * DataObject that represents a .CFG file. This object is NOT designed for presentation
+ * as is usual for NB dataobjects. It just serves to provide Open file from commandline
+ * feature, nothing more.
+ */
+@NbBundle.Messages(
+ "LBL_GraalVMC1VisualizerFile=GraalVM C1Visualizer File"
+)
+@MIMEResolver.ExtensionRegistration(
+ displayName = "#LBL_GraalVMC1VisualizerFile",
+ mimeType = C1VisualizerDataObject.GRAAL_CFG_MIME_TYPE,
+ position = 3232,
+ extension = {"cfg"}
+)
+@DataObject.Registration(
+ displayName = "LBL_GraalVMC1VisualizerFile",
+ mimeType = C1VisualizerDataObject.GRAAL_CFG_MIME_TYPE,
+ position = 400
+)
+public class C1VisualizerDataObject extends MultiDataObject {
+ /**
+ * MIME type for CFG dumps
+ */
+ public static final String GRAAL_CFG_MIME_TYPE = "application/x-c1visualizer"; // NOI18N
+
+ public C1VisualizerDataObject(FileObject fo, MultiFileLoader loader) throws DataObjectExistsException {
+ super(fo, loader);
+ getCookieSet().assign(Openable.class, new OpenImpl());
+ }
+
+ private class OpenImpl implements OpenCookie {
+ @Override
+ public void open() {
+ importPrimaryFile();
+ }
+ }
+
+ public void importPrimaryFile() {
+ FileObject fo = getPrimaryFile();
+ File f = FileUtil.toFile(fo);
+ if (f == null) {
+ return;
+ }
+
+ final String fileName = f.getAbsolutePath();
+ RequestProcessor.getDefault().post(new Runnable() {
+ public void run() {
+ CompilationModel model = Lookup.getDefault().lookup(CompilationModel.class);
+ String errorMsg = model.parseInputFile(fileName);
+ if (errorMsg != null) {
+ NotifyDescriptor d = new NotifyDescriptor.Message("Errors while parsing input:\n" + errorMsg, NotifyDescriptor.ERROR_MESSAGE);
+ DialogDisplayer.getDefault().notify(d);
+ }
+ }
+ });
+ }
+}
+
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/OpenCompilationAction.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/OpenCompilationAction.java
new file mode 100644
index 000000000000..204e4af25f40
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/OpenCompilationAction.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view.action;
+
+import at.ssw.visualizer.compilation.view.icons.Icons;
+import at.ssw.visualizer.model.CompilationModel;
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.util.prefs.Preferences;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JFileChooser;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+import org.openide.util.RequestProcessor;
+import org.openide.windows.WindowManager;
+
+/**
+ * Action opening a CFG file and loading it into the workspace.
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+public final class OpenCompilationAction extends AbstractAction {
+ public OpenCompilationAction() {
+ super("&Open Compiled Methods...", new ImageIcon(ImageUtilities.loadImage(Icons.OPEN)));
+ putValue(Action.SHORT_DESCRIPTION, "Open Compiled Methods");
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ JFileChooser ch = new JFileChooser();
+ ch.setCurrentDirectory(getLastDirectory());
+ ch.setFileFilter(new FileNameExtensionFilter("Compiled methods (*.cfg)", "cfg"));
+ if (ch.showOpenDialog(WindowManager.getDefault().getMainWindow()) != JFileChooser.APPROVE_OPTION || ch.getSelectedFile() == null) {
+ return;
+ }
+ setLastDirectory(ch.getSelectedFile());
+
+ final String fileName = ch.getSelectedFile().getAbsolutePath();
+ RequestProcessor.getDefault().post(new Runnable() {
+ public void run() {
+ CompilationModel model = Lookup.getDefault().lookup(CompilationModel.class);
+ String errorMsg = model.parseInputFile(fileName);
+ if (errorMsg != null) {
+ NotifyDescriptor d = new NotifyDescriptor.Message("Errors while parsing input:\n" + errorMsg, NotifyDescriptor.ERROR_MESSAGE);
+ DialogDisplayer.getDefault().notify(d);
+ }
+ }
+ });
+ }
+
+ private File getLastDirectory() {
+ Preferences prefs = Preferences.userNodeForPackage(getClass());
+ String fileName = prefs.get("lastDirectory", null);
+ File file = null;
+ if (fileName != null) {
+ file = new File(fileName);
+ }
+ if (file == null || !file.exists()) {
+ file = new File(System.getProperty("user.home"));
+ }
+ return file;
+ }
+
+ private void setLastDirectory(File file) {
+ Preferences prefs = Preferences.userNodeForPackage(getClass());
+ if (!file.isDirectory()) {
+ file = file.getParentFile();
+ }
+ prefs.put("lastDirectory", file.getPath());
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/RemoveAllCompilationsAction.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/RemoveAllCompilationsAction.java
new file mode 100644
index 000000000000..1b8539e43697
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/RemoveAllCompilationsAction.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view.action;
+
+import at.ssw.visualizer.compilation.view.icons.Icons;
+import at.ssw.visualizer.model.CompilationModel;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+
+/**
+ * Action for removing all compilations from the workspace.
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+public final class RemoveAllCompilationsAction extends AbstractAction {
+ public RemoveAllCompilationsAction() {
+ super("Remove All Methods", new ImageIcon(ImageUtilities.loadImage(Icons.REMOVE_ALL)));
+ putValue(Action.SHORT_DESCRIPTION, "Remove All Methods");
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ CompilationModel model = Lookup.getDefault().lookup(CompilationModel.class);
+ model.clear();
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/RemoveCompilationAction.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/RemoveCompilationAction.java
new file mode 100644
index 000000000000..24c6c3f20f0a
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/action/RemoveCompilationAction.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view.action;
+
+import at.ssw.visualizer.compilation.view.icons.Icons;
+import at.ssw.visualizer.model.Compilation;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CookieAction;
+
+/**
+ * Action for removing the currently selected compilation from the workspace.
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+public final class RemoveCompilationAction extends CookieAction {
+ protected void performAction(Node[] activatedNodes) {
+ Compilation compilation = activatedNodes[0].getLookup().lookup(Compilation.class);
+ compilation.getCompilationModel().removeCompilation(compilation);
+ }
+
+ public String getName() {
+ return "Remove Method";
+ }
+
+ @Override
+ protected String iconResource() {
+ return Icons.REMOVE;
+ }
+
+ protected int mode() {
+ return CookieAction.MODE_EXACTLY_ONE;
+ }
+
+ protected Class[] cookieClasses() {
+ return new Class[]{Compilation.class};
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ protected boolean asynchronous() {
+ return false;
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/icons/Icons.java b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/icons/Icons.java
new file mode 100644
index 000000000000..ebcbd7cf05ff
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/java/at/ssw/visualizer/compilation/view/icons/Icons.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.compilation.view.icons;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class Icons {
+ private static final String PATH = "at/ssw/visualizer/compilation/view/icons/";
+
+ public static final String OPEN = PATH + "open.gif";
+ public static final String REMOVE = PATH + "remove.gif";
+ public static final String REMOVE_ALL = PATH + "removeall.gif";
+
+ public static final String FOLDER = PATH + "folder.gif";
+ public static final String COMPILATIONS = PATH + "compilations.gif";
+ public static final String CFG = PATH + "cfg.gif";
+ public static final String INTERVALS = PATH + "intervals.gif";
+
+ public static final String FILTER = PATH + "filter.gif";
+ public static final String SORT = PATH + "sort.gif";
+ public static final String PACKAGE = PATH + "package.gif";
+ public static final String COLLAPSE_ALL = PATH + "collapseall.gif";
+
+ private Icons() {
+ }
+}
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/nbm/manifest.mf b/visualizer/C1Visualizer/CompilationView/src/main/nbm/manifest.mf
new file mode 100644
index 000000000000..fe26eac40b36
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/nbm/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.compilation.view
+OpenIDE-Module-Layer: at/ssw/visualizer/compilation/view/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/compilation/view/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/Bundle.properties b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/Bundle.properties
new file mode 100644
index 000000000000..c6f874ec5fbb
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=Compilation View
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/CompilationViewTopComponentSettings.xml b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/CompilationViewTopComponentSettings.xml
new file mode 100644
index 000000000000..0b20f777ba36
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/CompilationViewTopComponentSettings.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/CompilationViewTopComponentWstcref.xml b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/CompilationViewTopComponentWstcref.xml
new file mode 100644
index 000000000000..f725aff40389
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/CompilationViewTopComponentWstcref.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/cfg.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/cfg.gif
new file mode 100644
index 000000000000..695e5a5cfa5b
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/cfg.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/collapseall.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/collapseall.gif
new file mode 100644
index 000000000000..a2d80a9044f3
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/collapseall.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/compilations.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/compilations.gif
new file mode 100644
index 000000000000..983932fcccdf
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/compilations.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/filter.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/filter.gif
new file mode 100644
index 000000000000..6fe6f0e10a11
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/filter.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/folder.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/folder.gif
new file mode 100644
index 000000000000..51e703b1b9c6
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/folder.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/intervals.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/intervals.gif
new file mode 100644
index 000000000000..5ef0ed7f13c7
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/intervals.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/open.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/open.gif
new file mode 100644
index 000000000000..7aea894d0b60
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/open.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/package.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/package.gif
new file mode 100644
index 000000000000..b80590bb7be2
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/package.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/remove.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/remove.gif
new file mode 100644
index 000000000000..2cd9c544436c
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/remove.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/removeall.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/removeall.gif
new file mode 100644
index 000000000000..28a3785aaca7
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/removeall.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/sort.gif b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/sort.gif
new file mode 100644
index 000000000000..6311cc00f80d
Binary files /dev/null and b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/icons/sort.gif differ
diff --git a/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/layer.xml b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/layer.xml
new file mode 100644
index 000000000000..c70bed252de8
--- /dev/null
+++ b/visualizer/C1Visualizer/CompilationView/src/main/resources/at/ssw/visualizer/compilation/view/layer.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/pom.xml b/visualizer/C1Visualizer/ControlFlowEditor/pom.xml
new file mode 100644
index 000000000000..e91c6baae053
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/pom.xml
@@ -0,0 +1,139 @@
+
+ 4.0.0
+
+ C1Visualizer-parent
+ at.ssw.visualizer
+ 1.14-SNAPSHOT
+
+ at.ssw.visualizer
+ ControlFlowEditor
+ 1.14-SNAPSHOT
+ nbm
+ ControlFlowEditor
+
+ UTF-8
+
+
+
+ at.ssw.visualizer
+ VisualizerUI
+ ${project.version}
+
+
+ at.ssw.visualizer
+ CompilationModel
+ ${project.version}
+
+
+ org.eclipse
+ draw2d
+ 3.2.100-v20070529
+
+
+
+ org.apache.xmlgraphics
+ batik-dom
+ ${batik.version}
+
+
+ org.apache.xmlgraphics
+ batik-svggen
+ ${batik.version}
+
+
+
+ org.netbeans.api
+ org-netbeans-api-visual
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-netbeans-modules-options-api
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-actions
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-awt
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-dialogs
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-loaders
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-nodes
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-util-ui
+ ${netbeans.version}
+
+
+ org.netbeans.api
+ org-openide-windows
+ ${netbeans.version}
+
+
+
+
+
+ org.apache.netbeans.utilities
+ nbm-maven-plugin
+ ${nbmmvnplugin.version}
+ true
+
+
+ at.ssw.visualizer.ControlFlowEditor
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${mvncompilerplugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${mvnjarplugin.version}
+
+
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+
+
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/CfgEditorContext.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/CfgEditorContext.java
new file mode 100644
index 000000000000..ced6077b8069
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/CfgEditorContext.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg;
+
+public abstract class CfgEditorContext {
+
+ public static final int LAYOUT_HIERARCHICALNODELAYOUT = 1;
+ public static final int LAYOUT_HIERARCHICALCOMPOUNDLAYOUT = 2;
+
+ public static final int ROUTING_DIRECTLINES = 1;
+ public static final int ROUTING_BEZIER = 2;
+
+ public static final int MAX_AUTOEDGESVISIBLE = 8;
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/AbstractCfgEditorAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/AbstractCfgEditorAction.java
new file mode 100644
index 000000000000..3a7306d0b2a7
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/AbstractCfgEditorAction.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+
+import at.ssw.visualizer.cfg.graph.CfgEventListener;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.windows.TopComponent;
+
+/**
+ * The common superclass of all concrete actions related to the CFG visualizer.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public abstract class AbstractCfgEditorAction extends CallableSystemAction implements CfgEventListener , PropertyChangeListener {
+
+ CfgEditorTopComponent topComponent = null;
+
+ public AbstractCfgEditorAction() {
+ TopComponent.getRegistry().addPropertyChangeListener(this);
+ setEnabled(false);
+
+ }
+
+ protected CfgEditorTopComponent getEditor() {
+ return topComponent;
+ }
+
+ protected void setEditor(CfgEditorTopComponent newTopComponent) {
+ CfgEditorTopComponent oldTopComponent = getEditor();
+ if(newTopComponent != oldTopComponent){
+ if(oldTopComponent != null) {
+ oldTopComponent.getCfgScene().removeCfgEventListener(this);
+ }
+ this.topComponent = newTopComponent;
+ if (newTopComponent != null) {
+ newTopComponent.getCfgScene().addCfgEventListener(this);
+ selectionChanged(newTopComponent.getCfgScene());
+ }
+ this.setEnabled(newTopComponent!=null);
+ }
+ }
+
+
+ @Override
+ public JMenuItem getMenuPresenter() {
+ return new JMenuItem(this);
+ }
+
+
+ @Override
+ public JComponent getToolbarPresenter() {
+ JButton b = new JButton(this);
+ if (getIcon() != null) {
+ b.setText(null);
+ b.setToolTipText(getName());
+ }
+ return b;
+ }
+
+
+ @Override
+ public JMenuItem getPopupPresenter() {
+ return new JMenuItem(this);
+ }
+
+
+ @Override
+ protected boolean asynchronous() {
+ return false;
+ }
+
+
+ public void propertyChange(PropertyChangeEvent e) {
+ if ( e.getPropertyName().equals(TopComponent.Registry.PROP_ACTIVATED)) {
+ if(e.getNewValue() instanceof CfgEditorTopComponent){
+ CfgEditorTopComponent tc = (CfgEditorTopComponent)e.getNewValue();
+ setEditor(tc);
+ selectionChanged(tc.getCfgScene());
+ }
+ }
+ }
+
+
+ public void selectionChanged(CfgScene scene) {
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/AbstractRouterAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/AbstractRouterAction.java
new file mode 100644
index 000000000000..e5fa947df6be
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/AbstractRouterAction.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JToggleButton;
+import org.openide.util.actions.Presenter;
+
+/**
+ * Common superclass for all actions which set the link router.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public abstract class AbstractRouterAction extends AbstractCfgEditorAction implements Presenter.Menu, Presenter.Popup, Presenter.Toolbar {
+
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ setLinkRouter(tc);
+ }
+ }
+
+ protected abstract void setLinkRouter(CfgEditorTopComponent editor);
+
+ @Override
+ public JMenuItem getMenuPresenter() {
+ JMenuItem presenter = new MenuPresenter();
+ presenter.setToolTipText(getName());
+ return presenter;
+ }
+
+ @Override
+ public JMenuItem getPopupPresenter() {
+ return getMenuPresenter();
+ }
+
+ @Override
+ public JComponent getToolbarPresenter() {
+ ToolbarPresenter presenter = new ToolbarPresenter();
+ presenter.setToolTipText(getName());
+ return presenter;
+ }
+
+ class MenuPresenter extends JRadioButtonMenuItem {
+
+ public MenuPresenter() {
+ super(AbstractRouterAction.this);
+ setIcon(null);
+ }
+ }
+
+ class ToolbarPresenter extends JToggleButton {
+
+ public ToolbarPresenter() {
+ super(AbstractRouterAction.this);
+ setText(null);
+ }
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ColorAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ColorAction.java
new file mode 100644
index 000000000000..a2126791ca0f
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ColorAction.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.graph.CfgEventListener;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.image.BufferedImage;
+import java.util.Set;
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingConstants;
+import javax.swing.plaf.basic.BasicArrowButton;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.Presenter;
+
+/**
+ * Changes the background color of a node.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public class ColorAction extends AbstractCfgEditorAction implements Presenter.Menu, Presenter.Popup, Presenter.Toolbar {
+
+ public static final int IMAGE_WIDTH = 16;
+ public static final int IMAGE_HEIGHT = 16;
+
+
+ /** Names of colors shown in color select lists. */
+ private static final String[] COLOR_NAMES = {"White", "Light Gray", "Dark Gray", "Light Yellow", "Dark Yellow", "Light Green", "Dark Green", "Light Cyan", "Dark Cyan", "Light Blue", "Dark Blue", "Light Magenta", "Dark Magenta", "Light Red", "Dark Red"};
+
+ /** Values of colors shown in color select lists. */
+ private static final Color[] COLORS = {
+ new Color(0xFFFFFF), new Color(0xD4D0C8), new Color(0xA4A098), new Color(0xF0F0B0), new Color(0xE0E040),
+ new Color(0xB0F0B0), new Color(0x40E040), new Color(0xB0F0F0), new Color(0x40E0E0), new Color(0xB0B0F0),
+ new Color(0x4040E0), new Color(0xF0B0F0), new Color(0xE040E0), new Color(0xF0B0B0), new Color(0xE04040)
+ };
+
+ public void performAction() {
+ // nothing to do here, the presenters are supposed to call
+ // performAction(Color)
+ }
+
+ protected void performAction(Color color) {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ tc.getCfgScene().setSelectedNodesColor(color);
+ }
+ }
+
+ public String getName() {
+ return "Change NodeColor";
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/color.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public JMenuItem getMenuPresenter() {
+ return new MenuPresenter();
+ }
+
+ @Override
+ public JMenuItem getPopupPresenter() {
+ return new MenuPresenter();
+ }
+
+ @Override
+ public JComponent getToolbarPresenter() {
+ return new ToolbarPresenter();
+ }
+
+ class MenuPresenter extends JMenu {
+
+ public MenuPresenter() {
+ super(ColorAction.this);
+ initGUI();
+ }
+
+ protected void initGUI() {
+ CfgEditorTopComponent tc = getEditor();
+ if( tc != null && tc.getCfgScene().getSelectedNodes().size()==0) {
+ //no node selected
+ setEnabled(false);
+ } else {
+ add(new SetColorAction(null, "Automatic"));
+ for (int i = 0; i < COLORS.length; i++) {
+ add(new SetColorAction(COLORS[i], COLOR_NAMES[i]));
+ }
+ }
+ }
+ }
+
+ class ToolbarPresenter extends JButton implements CfgEventListener, MouseListener {
+
+ final int arrowSize = 5;
+ final int arrowMargin = 3;
+ JPopupMenu popup;
+
+ public ToolbarPresenter() {
+ setIcon(createIcon());
+ setToolTipText(ColorAction.this.getName());
+
+ popup = new JPopupMenu();
+ popup.add(new SetColorAction(null, "Automatic"));
+ for (int i = 0; i < COLORS.length; i++) {
+ popup.add(new SetColorAction(COLORS[i], COLOR_NAMES[i]));
+ }
+ addMouseListener(this);
+ }
+
+ public Icon createIcon() {
+ BasicArrowButton arrow = new BasicArrowButton(SwingConstants.SOUTH);
+ BufferedImage img = new BufferedImage(IMAGE_WIDTH + arrowSize + 2 * arrowMargin, IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
+ Graphics g = img.getGraphics();
+ ColorAction.this.getIcon().paintIcon(this, g, 0, 0);
+ arrow.paintTriangle(g, IMAGE_WIDTH + arrowMargin + arrowSize / 2, IMAGE_HEIGHT / 2 - arrowSize / 2, arrowSize, SwingConstants.SOUTH, true);
+ return new ImageIcon(img);
+ }
+
+
+ public void selectionChanged(CfgScene scene) {
+ Set nodes = scene.getSelectedNodes();
+ setEnabled(nodes.size() > 0);
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ if (e.getX() < getInsets().left + IMAGE_WIDTH + arrowMargin) {
+ performAction(null);
+ } else {
+ popup.show(this, 0, getSize().height);
+ }
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ public void mouseExited(MouseEvent e) {
+ }
+
+ public void mousePressed(MouseEvent e) {
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ }
+ }
+
+ protected Icon createIcon(Color color) {
+ if (color == null) {
+ return ColorAction.this.getIcon();
+ } else {
+ return new ColorIcon(color);
+ }
+ }
+
+ class ColorIcon implements Icon {
+
+ Color color;
+
+ public ColorIcon(Color color) {
+ this.color = color;
+ }
+
+ public int getIconWidth() {
+ return IMAGE_WIDTH;
+ }
+
+ public int getIconHeight() {
+ return IMAGE_HEIGHT;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ Color oldColor = g.getColor();
+ g.setColor(color);
+ g.fillRect(x, y, IMAGE_WIDTH, IMAGE_HEIGHT);
+ g.setColor(oldColor);
+ }
+ }
+
+ class SetColorAction extends AbstractAction {
+
+ Color color;
+ String name;
+ Icon icon;
+
+ public SetColorAction(Color color, String name) {
+ super(name, createIcon(color));
+ this.color = color;
+ this.name = name;
+ icon = (Icon) getValue(AbstractAction.SMALL_ICON);
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Icon getIcon() {
+ return icon;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ performAction(color);
+ }
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ExportAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ExportAction.java
new file mode 100644
index 000000000000..c363364f3c14
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ExportAction.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.io.File;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.util.HelpCtx;
+import org.apache.batik.dom.GenericDOMImplementation;
+import org.apache.batik.svggen.SVGGeneratorContext;
+import org.apache.batik.svggen.SVGGraphics2D;
+import org.w3c.dom.DOMImplementation;
+import java.io.*;
+import java.awt.Graphics2D;
+
+/**
+ * Exports Scene to various Graphics Formats
+ *
+ * @author Rumpfhuber Stefan
+ */
+public class ExportAction extends AbstractCfgEditorAction {
+
+ public static final String DESCRIPTION_SVG = "Scaleable Vector Format (.svg)";
+ public static final String EXT_SVG = "svg";
+
+ String lastDirectory = null;
+
+ @Override
+ public void performAction() {
+ CfgEditorTopComponent tc = this.getEditor();
+ CfgScene scene = tc.getCfgScene();
+ JComponent view = scene.getView();
+
+ JFileChooser chooser = new JFileChooser ();
+ chooser.setAcceptAllFileFilterUsed(false);
+ chooser.setDialogTitle (getName());
+ chooser.setDialogType (JFileChooser.SAVE_DIALOG);
+ chooser.setMultiSelectionEnabled (false);
+ chooser.setFileSelectionMode (JFileChooser.FILES_ONLY);
+ chooser.addChoosableFileFilter(new FileNameExtensionFilter(DESCRIPTION_SVG, EXT_SVG));
+ if(lastDirectory != null)
+ chooser.setCurrentDirectory(new File(lastDirectory));
+ chooser.setSelectedFile(new File(tc.getName()));
+
+
+ if (chooser.showSaveDialog (tc) != JFileChooser.APPROVE_OPTION)
+ return;
+
+ File file = chooser.getSelectedFile ();
+
+ if(file == null)
+ return;
+
+ FileNameExtensionFilter filter = (FileNameExtensionFilter) chooser.getFileFilter();
+ String fn = file.getAbsolutePath().toLowerCase();
+ String ext = filter.getExtensions()[0];
+ if(!fn.endsWith("." + ext)){
+ file = new File( file.getParentFile(), file.getName() + "." + ext);
+ }
+
+ if (file.exists ()) {
+ DialogDescriptor descriptor = new DialogDescriptor (
+ "File (" + file.getAbsolutePath () + ") already exists. Do you want to overwrite it?",
+ "File Exists", true, DialogDescriptor.YES_NO_OPTION, DialogDescriptor.NO_OPTION, null);
+ DialogDisplayer.getDefault ().createDialog (descriptor).setVisible (true);
+ if (descriptor.getValue () != DialogDescriptor.YES_OPTION)
+ return;
+ }
+
+ lastDirectory = chooser.getCurrentDirectory().getAbsolutePath();
+
+ if(ext.equals(EXT_SVG)){
+ DOMImplementation dom = GenericDOMImplementation.getDOMImplementation();
+ org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
+ SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document);
+ ctx.setEmbeddedFontsOn(true);
+ Graphics2D svgGenerator = new SVGGraphics2D(ctx, true);
+ scene.paint(svgGenerator);
+ FileOutputStream os = null;
+ try {
+ os = new FileOutputStream(file);
+ Writer out = new OutputStreamWriter(os, "UTF-8");
+ assert svgGenerator instanceof SVGGraphics2D;
+ SVGGraphics2D svgGraphics = (SVGGraphics2D)svgGenerator;
+ svgGraphics.stream(out, true);
+ } catch (IOException e) {
+ // NotifyDescriptor message = new NotifyDescriptor.Message(
+ // Bundle.EXPORT_BATIK_ErrorExportingSVG(e.getLocalizedMessage()), NotifyDescriptor.ERROR_MESSAGE);
+ // DialogDisplayer.getDefault().notifyLater(message);
+ } finally {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public String getName() {
+ return "Export CFG";
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/disk.gif";
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HideEdgesAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HideEdgesAction.java
new file mode 100644
index 000000000000..253e9166cba0
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HideEdgesAction.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.graph.EdgeWidget;
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import org.openide.util.HelpCtx;
+
+/**
+ * Hides all edges connected to the selected node.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public class HideEdgesAction extends AbstractCfgEditorAction {
+
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ tc.getCfgScene().setSelectedEdgesVisibility(false);
+ }
+ }
+
+ public String getName() {
+ return "Hide Edges";
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/hideedges.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public void selectionChanged(CfgScene scene) {
+ for (CfgNode n : scene.getSelectedNodes()) {
+ for (CfgEdge e : scene.findNodeEdges(n, true, true) ){
+ EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+ if(ew.isVisible()) {
+ setEnabled(true);
+ return;
+ }
+ }
+ }
+ setEnabled(false);
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HierarchicalCompoundLayoutAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HierarchicalCompoundLayoutAction.java
new file mode 100644
index 000000000000..11cc54ed7219
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HierarchicalCompoundLayoutAction.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import org.openide.util.HelpCtx;
+
+
+public class HierarchicalCompoundLayoutAction extends AbstractCfgEditorAction {
+
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ CfgScene scene = tc.getCfgScene();
+ scene.setSceneLayout(CfgEditorContext.LAYOUT_HIERARCHICALCOMPOUNDLAYOUT);
+ scene.applyLayout();
+ }
+ }
+
+ public String getName() {
+ return "Hierarchical Compound Layout";
+ }
+
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/arrangeloop.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HierarchicalNodeLayoutAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HierarchicalNodeLayoutAction.java
new file mode 100644
index 000000000000..a6c7563fdb4c
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/HierarchicalNodeLayoutAction.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import org.openide.util.HelpCtx;
+
+
+public class HierarchicalNodeLayoutAction extends AbstractCfgEditorAction {
+
+ @Override
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ CfgScene scene = tc.getCfgScene();
+ scene.setSceneLayout(CfgEditorContext.LAYOUT_HIERARCHICALNODELAYOUT);
+ scene.applyLayout();
+ }
+ }
+
+ public String getName() {
+ return "Hierarchical Node Layout";
+ }
+
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/arrangehier.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowAllAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowAllAction.java
new file mode 100644
index 000000000000..fdae5ce5c843
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowAllAction.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import org.openide.util.HelpCtx;
+
+
+/**
+ * Adjusts the Zoom factor of the Scene to the bounds of Scroll panel
+ * to get a clean view on the whole graph.
+ *
+ */
+public class ShowAllAction extends AbstractCfgEditorAction {
+
+ @Override
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ CfgScene scene = tc.getCfgScene();
+ scene.zoomScene();
+
+ }
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public String getName() {
+ return "Fit Scene to Window";
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/autosize.gif";
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowCFGEditorAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowCFGEditorAction.java
new file mode 100644
index 000000000000..3e85928871a7
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowCFGEditorAction.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorSupport;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.icons.Icons;
+import at.ssw.visualizer.core.focus.Focus;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CookieAction;
+
+/**
+ * Shows the CFG visualizer for the currently selected compilation.
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ */
+public final class ShowCFGEditorAction extends CookieAction {
+
+ protected void performAction(Node[] activatedNodes) {
+ ControlFlowGraph cfg = activatedNodes[0].getLookup().lookup(ControlFlowGraph.class);
+ if (!Focus.findEditor(CfgEditorTopComponent.class, cfg)) {
+ CfgEditorSupport editor = new CfgEditorSupport(cfg);
+ editor.open();
+ }
+ }
+
+ @Override
+ protected boolean enable(Node[] activatedNodes) {
+ if (!super.enable(activatedNodes)) {
+ return false;
+ }
+ ControlFlowGraph cfg = activatedNodes[0].getLookup().lookup(ControlFlowGraph.class);
+ return cfg.getBasicBlocks().size() > 0;
+ }
+
+ public String getName() {
+ return "Open Control Flow Graph";
+ }
+
+ @Override
+ protected String iconResource() {
+ return Icons.CFG;
+ }
+
+ protected int mode() {
+ return CookieAction.MODE_EXACTLY_ONE;
+ }
+
+ protected Class[] cookieClasses() {
+ return new Class[]{ControlFlowGraph.class};
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ protected boolean asynchronous() {
+ return false;
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowEdgesAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowEdgesAction.java
new file mode 100644
index 000000000000..f0c2c7d89212
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ShowEdgesAction.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.graph.EdgeWidget;
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import org.openide.util.HelpCtx;
+
+/**
+ * Shows all edges connected to the selected node.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public class ShowEdgesAction extends AbstractCfgEditorAction {
+
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ tc.getCfgScene().setSelectedEdgesVisibility(true);
+ }
+ }
+
+ public String getName() {
+ return "Show edges";
+ }
+
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/showedges.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public void selectionChanged(CfgScene scene) {
+ for (CfgNode n : scene.getSelectedNodes()) {
+ for (CfgEdge e : scene.findNodeEdges(n, true, true) ){
+ EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+ if(!ew.isVisible()) {
+ setEnabled(true);
+ return;
+ }
+ }
+ }
+ setEnabled(false);
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/SwitchLoopClustersAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/SwitchLoopClustersAction.java
new file mode 100644
index 000000000000..9a2f7f23019b
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/SwitchLoopClustersAction.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import javax.swing.JComponent;
+import javax.swing.JToggleButton;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.Presenter;
+
+public class SwitchLoopClustersAction extends AbstractCfgEditorAction implements Presenter.Toolbar {
+
+ @Override
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ CfgScene scene = tc.getCfgScene();
+ boolean visible = scene.isLoopClusterVisible();
+ scene.setLoopWidgets(!visible);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "Enable/Disable Loop Clusters";
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/cluster.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+
+ @Override
+ public JComponent getToolbarPresenter() {
+ return new ToolbarPresenter();
+ }
+
+ class ToolbarPresenter extends JToggleButton {
+ private static final String TOOLTIP_ENABLE = "Enable LoopClusters";
+ private static final String TOOLTIP_DISABLE = "Disable LoopClusters";
+
+ public ToolbarPresenter() {
+ super(SwitchLoopClustersAction.this);
+ setText(null);
+ this.setToolTipText(TOOLTIP_DISABLE);
+ this.setSelected(true);
+
+ this.addItemListener(new ItemListener(){
+ public void itemStateChanged(ItemEvent e) {
+ if(isSelected()){
+ setToolTipText(TOOLTIP_DISABLE);
+ } else {
+ setToolTipText(TOOLTIP_ENABLE);
+ }
+ }
+ });
+ }
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/UseBezierRouterAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/UseBezierRouterAction.java
new file mode 100644
index 000000000000..67317a526af3
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/UseBezierRouterAction.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import org.openide.util.HelpCtx;
+
+
+public class UseBezierRouterAction extends AbstractRouterAction {
+
+ @Override
+ protected void setLinkRouter(CfgEditorTopComponent editor) {
+ editor.getCfgScene().setRouter(CfgEditorContext.ROUTING_BEZIER);
+ }
+
+ @Override
+ public String getName() {
+ return "Use Bezier Router";
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/bezierrouter.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/UseDirectLineRouterAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/UseDirectLineRouterAction.java
new file mode 100644
index 000000000000..220b5ee1ee5e
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/UseDirectLineRouterAction.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import org.openide.util.HelpCtx;
+
+
+public class UseDirectLineRouterAction extends AbstractRouterAction {
+
+ @Override
+ protected void setLinkRouter(CfgEditorTopComponent editor) {
+ editor.getCfgScene().setRouter(CfgEditorContext.ROUTING_DIRECTLINES);
+ }
+
+ @Override
+ public String getName() {
+ return "User Direct Router";
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/fanrouter.gif";
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ZoominAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ZoominAction.java
new file mode 100644
index 000000000000..3d01c5389328
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ZoominAction.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import org.openide.util.HelpCtx;
+
+
+public class ZoominAction extends AbstractCfgEditorAction {
+
+ @Override
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ CfgScene scene = tc.getCfgScene();
+ scene.animateZoom(1.1);
+ }
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/zoomin.gif";
+ }
+
+ @Override
+ public String getName() {
+ return "Zoomin";
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ZoomoutAction.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ZoomoutAction.java
new file mode 100644
index 000000000000..fbfd30f5c591
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/action/ZoomoutAction.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import org.openide.util.HelpCtx;
+
+public class ZoomoutAction extends AbstractCfgEditorAction {
+
+ @Override
+ public void performAction() {
+ CfgEditorTopComponent tc = getEditor();
+ if (tc != null) {
+ CfgScene scene = tc.getCfgScene();
+ scene.animateZoom(0.9);
+ }
+ }
+
+ @Override
+ protected String iconResource() {
+ return "at/ssw/visualizer/cfg/icons/zoomout.gif";
+ }
+
+ @Override
+ public String getName() {
+ return "Zoomout";
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/editor/CfgEditorSupport.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/editor/CfgEditorSupport.java
new file mode 100644
index 000000000000..9231210a56ec
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/editor/CfgEditorSupport.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.editor;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.beans.VetoableChangeListener;
+import java.beans.VetoableChangeSupport;
+import java.io.IOException;
+import org.openide.cookies.OpenCookie;
+import org.openide.windows.CloneableOpenSupport;
+import org.openide.windows.CloneableTopComponent;
+
+
+public class CfgEditorSupport extends CloneableOpenSupport implements OpenCookie {
+ private ControlFlowGraph cfg;
+
+ public CfgEditorSupport(ControlFlowGraph cfg) {
+ super(new Env());
+ ((Env) env).editorSupport = this;
+ this.cfg = cfg;
+ }
+
+ protected CloneableTopComponent createCloneableTopComponent() {
+ return new CfgEditorTopComponent(cfg);
+ }
+
+ public String messageOpened() {
+ return "Opened " + cfg.getCompilation().getMethod() + " - " + cfg.getName();
+ }
+
+ public String messageOpening() {
+ return "Opening " + cfg.getCompilation().getMethod() + " - " + cfg.getName();
+ }
+
+
+ public static class Env implements CloneableOpenSupport.Env {
+ private PropertyChangeSupport prop = new PropertyChangeSupport(this);
+ private VetoableChangeSupport veto = new VetoableChangeSupport(this);
+ private CfgEditorSupport editorSupport;
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public boolean isModified() {
+ return false;
+ }
+
+ public void markModified() throws IOException {
+ throw new IOException("Editor is readonly");
+ }
+
+ public void unmarkModified() {
+ // Nothing to do.
+ }
+
+ public CloneableOpenSupport findCloneableOpenSupport() {
+ return editorSupport;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ prop.addPropertyChangeListener(l);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ prop.removePropertyChangeListener(l);
+ }
+
+ public void addVetoableChangeListener(VetoableChangeListener l) {
+ veto.addVetoableChangeListener(l);
+ }
+
+ public void removeVetoableChangeListener(VetoableChangeListener l) {
+ veto.removeVetoableChangeListener(l);
+ }
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/editor/CfgEditorTopComponent.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/editor/CfgEditorTopComponent.java
new file mode 100644
index 000000000000..1974ded48f1d
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/editor/CfgEditorTopComponent.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.editor;
+
+import at.ssw.visualizer.cfg.action.ShowAllAction;
+import at.ssw.visualizer.cfg.action.ColorAction;
+import at.ssw.visualizer.cfg.action.ExportAction;
+import at.ssw.visualizer.cfg.action.HideEdgesAction;
+import at.ssw.visualizer.cfg.action.HierarchicalCompoundLayoutAction;
+import at.ssw.visualizer.cfg.action.HierarchicalNodeLayoutAction;
+import at.ssw.visualizer.cfg.action.ShowEdgesAction;
+import at.ssw.visualizer.cfg.action.SwitchLoopClustersAction;
+import at.ssw.visualizer.cfg.action.UseBezierRouterAction;
+import at.ssw.visualizer.cfg.action.UseDirectLineRouterAction;
+import at.ssw.visualizer.cfg.action.ZoominAction;
+import at.ssw.visualizer.cfg.action.ZoomoutAction;
+import at.ssw.visualizer.cfg.graph.CfgEventListener;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.graph.EdgeWidget;
+import at.ssw.visualizer.cfg.graph.NodeWidget;
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import at.ssw.visualizer.cfg.preferences.FlagsSetting;
+import javax.swing.ScrollPaneConstants;
+import at.ssw.visualizer.core.selection.Selection;
+import at.ssw.visualizer.core.selection.SelectionManager;
+import at.ssw.visualizer.core.selection.SelectionProvider;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.JToggleButton;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import org.netbeans.api.visual.widget.Widget;
+import org.openide.awt.Toolbar;
+import org.openide.util.ImageUtilities;
+import org.openide.windows.CloneableTopComponent;
+import org.openide.windows.TopComponent;
+import org.openide.util.actions.SystemAction;
+
+public class CfgEditorTopComponent extends CloneableTopComponent implements PropertyChangeListener, SelectionProvider {
+
+ private CfgScene scene;
+ private JScrollPane jScrollPane;
+ private ControlFlowGraph cfg;
+ private JComponent myView;
+ private Selection selection;
+
+ public CfgEditorTopComponent(ControlFlowGraph cfg) {
+ this.cfg = cfg;
+
+ setIcon(ImageUtilities.loadImage("at/ssw/visualizer/cfg/icons/cfg.gif"));
+ setName(cfg.getParent().getShortName());
+ setToolTipText(cfg.getCompilation().getMethod() + " - " + cfg.getName());
+
+ //panel setup
+ this.jScrollPane = new JScrollPane();
+ this.jScrollPane.setOpaque(true);
+ this.jScrollPane.setBorder(BorderFactory.createEmptyBorder());
+ this.jScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
+ this.scene = new CfgScene(this);
+ this.myView = scene.createView();
+ this.jScrollPane.setViewportView(myView);
+ this.setLayout(new BorderLayout());
+ this.add(createToolbar(), BorderLayout.NORTH);
+ this.add(jScrollPane, BorderLayout.CENTER);
+ jScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+ jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+ jScrollPane.getVerticalScrollBar().setEnabled(true);
+ jScrollPane.getHorizontalScrollBar().setEnabled(true);
+
+ //setup enviroment,register listeners
+ selection = new Selection();
+ selection.put(cfg);
+ selection.put(scene);
+ selection.addChangeListener(scene);
+
+ scene.validate();
+ scene.applyLayout();
+ }
+
+ public Selection getSelection() {
+ return selection;
+ }
+
+ public ControlFlowGraph getCfg() {
+ return cfg;
+ }
+
+ public JScrollPane getJScrollPanel() {
+ return jScrollPane;
+ }
+
+ public CfgScene getCfgScene() {
+ return scene;
+ }
+
+ @Override
+ public int getPersistenceType() {
+ return TopComponent.PERSISTENCE_NEVER;
+ }
+
+ @Override
+ protected void componentOpened() {
+ super.componentOpened();
+ CfgPreferences.getInstance().addPropertyChangeListener(this);
+ }
+
+ @Override
+ protected void componentActivated() {
+ super.componentActivated();
+ SelectionManager.getDefault().setSelection(selection);
+ this.getCfgScene().updateGlobalSelection();
+ this.getCfgScene().fireSelectionChanged();
+ }
+
+ @Override
+ protected void componentClosed() {
+ super.componentClosed();
+ SelectionManager.getDefault().removeSelection(selection);
+ CfgPreferences.getInstance().removePropertyChangeListener(this);
+ }
+
+ @Override
+ protected CloneableTopComponent createClonedObject() {
+ CfgEditorTopComponent component = new CfgEditorTopComponent(cfg);
+ component.setActivatedNodes(getActivatedNodes());
+ return component;
+ }
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (this.scene != null) {
+
+ String propName = evt.getPropertyName();
+ CfgPreferences prefs = CfgPreferences.getInstance();
+ if (propName.equals(CfgPreferences.PROP_BACKGROUND_COLOR)) {
+ scene.setBackground(prefs.getBackgroundColor());
+ scene.revalidate();
+ } else if (propName.equals(CfgPreferences.PROP_NODE_COLOR)) {
+ for (NodeWidget nw : scene.getNodeWidgets()) {
+ //only change the node color if its not a custom color
+ if (!nw.isNodeColorCustomized()) {
+ nw.setNodeColor(prefs.getNodeColor(), false);
+ }
+ }
+ } else if (propName.equals(CfgPreferences.PROP_EDGE_COLOR)) {
+ for (CfgEdge e : scene.getEdges()) {
+ if (!e.isBackEdge() && !e.isXhandler()) {
+ EdgeWidget w = (EdgeWidget) scene.findWidget(e);
+ w.setLineColor(prefs.getEdgeColor());
+ }
+ }
+ } else if (propName.equals(CfgPreferences.PROP_BACK_EDGE_COLOR)) {
+ for (CfgEdge e : scene.getEdges()) {
+ if (e.isBackEdge()) {
+ EdgeWidget w = (EdgeWidget) scene.findWidget(e);
+ w.setLineColor(prefs.getBackedgeColor());
+ }
+ }
+ } else if (propName.equals(CfgPreferences.PROP_EXCEPTION_EDGE_COLOR)) {
+ for (CfgEdge e : scene.getEdges()) {
+ if (e.isXhandler()) {
+ EdgeWidget w = (EdgeWidget) scene.findWidget(e);
+ w.setLineColor(prefs.getExceptionEdgeColor());
+ }
+ }
+ } else if (propName.equals(CfgPreferences.PROP_BORDER_COLOR)) {
+ for (CfgNode n : scene.getNodes()) {
+ NodeWidget nw = (NodeWidget) scene.findWidget(n);
+ nw.setBorderColor(prefs.getBorderColor());
+ }
+ } else if (propName.equals(CfgPreferences.PROP_TEXT_FONT)) {
+ for (CfgNode n : scene.getNodes()) {
+ NodeWidget nw = (NodeWidget) scene.findWidget(n);
+ nw.adjustFont(prefs.getTextFont());
+ }
+ } else if (propName.equals(CfgPreferences.PROP_TEXT_COLOR)) {
+ for (CfgNode n : scene.getNodes()) {
+ NodeWidget nw = (NodeWidget) scene.findWidget(n);
+ nw.setForeground(prefs.getTextColor());
+ }
+ } else if (propName.equals(CfgPreferences.PROP_FLAGS)) {
+ FlagsSetting fs = CfgPreferences.getInstance().getFlagsSetting();
+ for (CfgNode n : scene.getNodes()) {
+ NodeWidget nw = (NodeWidget) scene.findWidget(n);
+ Color nodeColor = fs.getColor(n.getBasicBlock().getFlags());
+ if (nodeColor != null) {
+ nw.setNodeColor(nodeColor, true);
+ } else {
+ nw.setNodeColor(CfgPreferences.getInstance().getNodeColor(), false);
+ }
+ }
+ } else if (propName.equals(CfgPreferences.PROP_SELECTION_COLOR_BG) || propName.equals(CfgPreferences.PROP_SELECTION_COLOR_FG)) {
+ for (CfgNode n : scene.getNodes()) {
+ Widget w = scene.findWidget(n);
+ w.revalidate();
+ }
+ }
+ scene.validate();
+ }
+
+ }
+
+ private Toolbar createToolbar() {
+ Toolbar tb = new Toolbar("CfgToolbar");
+
+ tb.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border"));
+
+ //zoomin/zoomout buttons
+ tb.add(SystemAction.get(ZoominAction.class).getToolbarPresenter());
+ tb.add(SystemAction.get(ZoomoutAction.class).getToolbarPresenter());
+ tb.addSeparator();
+
+ //router buttons
+ ButtonGroup routerButtons = new ButtonGroup();
+ UseDirectLineRouterAction direct = SystemAction.get(UseDirectLineRouterAction.class);
+ UseBezierRouterAction bezier = SystemAction.get(UseBezierRouterAction.class);
+ JToggleButton button = (JToggleButton) direct.getToolbarPresenter();
+ button.getModel().setGroup(routerButtons);
+ button.setSelected(true);
+ tb.add(button);
+ button = (JToggleButton) bezier.getToolbarPresenter();
+ button.getModel().setGroup(routerButtons);
+ tb.add(button);
+ tb.addSeparator();
+
+ //layout buttons
+ tb.add(SystemAction.get(HierarchicalNodeLayoutAction.class).getToolbarPresenter());
+ tb.add(SystemAction.get(HierarchicalCompoundLayoutAction.class).getToolbarPresenter());
+
+ tb.addSeparator();
+ tb.add(SystemAction.get(ShowAllAction.class).getToolbarPresenter());
+ tb.addSeparator();
+
+ //cluster button
+ tb.add(SystemAction.get(SwitchLoopClustersAction.class).getToolbarPresenter());
+ tb.addSeparator();
+
+ //show/hide edge button
+ tb.add(SystemAction.get(ShowEdgesAction.class).getToolbarPresenter());
+ tb.add(SystemAction.get(HideEdgesAction.class).getToolbarPresenter());
+ tb.addSeparator();
+
+ //color button
+ JComponent colorButton = SystemAction.get(ColorAction.class).getToolbarPresenter();
+ getCfgScene().addCfgEventListener((CfgEventListener) colorButton);
+ tb.add(colorButton);
+
+ //export button
+ tb.add(SystemAction.get(ExportAction.class).getToolbarPresenter());
+ tb.doLayout();
+
+ return tb;
+ }
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/graph/CfgEventListener.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/graph/CfgEventListener.java
new file mode 100644
index 000000000000..0071fa38eb8e
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/graph/CfgEventListener.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.graph;
+
+import java.util.EventListener;
+
+
+public interface CfgEventListener extends EventListener {
+
+ /**
+ * the node or the edge selection got changed
+ */
+ public void selectionChanged(CfgScene scene);
+
+}
diff --git a/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/graph/CfgScene.java b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/graph/CfgScene.java
new file mode 100644
index 000000000000..a5a4233011ef
--- /dev/null
+++ b/visualizer/C1Visualizer/ControlFlowEditor/src/main/java/at/ssw/visualizer/cfg/graph/CfgScene.java
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2017, 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 at.ssw.visualizer.cfg.graph;
+
+
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.action.ColorAction;
+import at.ssw.visualizer.cfg.action.HideEdgesAction;
+import at.ssw.visualizer.cfg.action.ShowEdgesAction;
+import at.ssw.visualizer.cfg.editor.CfgEditorTopComponent;
+import at.ssw.visualizer.cfg.graph.layout.HierarchicalCompoundLayout;
+import at.ssw.visualizer.cfg.graph.layout.HierarchicalNodeLayout;
+import at.ssw.visualizer.cfg.model.CfgEnv;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import at.ssw.visualizer.cfg.model.LoopInfo;
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import at.ssw.visualizer.cfg.visual.PolylineRouter;
+import at.ssw.visualizer.cfg.visual.PolylineRouterV2;
+import at.ssw.visualizer.cfg.visual.WidgetCollisionCollector;
+import at.ssw.visualizer.core.selection.Selection;
+import at.ssw.visualizer.core.selection.SelectionManager;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.AbstractAction;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.MoveProvider;
+import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.RectangularSelectDecorator;
+import org.netbeans.api.visual.action.RectangularSelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.anchor.Anchor;
+import org.netbeans.api.visual.anchor.AnchorFactory;
+import org.netbeans.api.visual.graph.GraphScene;
+import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.layout.LayoutFactory;
+import org.netbeans.api.visual.layout.SceneLayout;
+import org.netbeans.api.visual.router.Router;
+import org.netbeans.api.visual.router.Router.*;
+import org.netbeans.api.visual.router.RouterFactory;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.widget.LayerWidget;
+import org.netbeans.api.visual.widget.Widget;
+import org.openide.util.actions.SystemAction;
+
+
+public class CfgScene extends GraphScene implements ChangeListener {
+ private LayerWidget mainLayer = new LayerWidget(this);
+ private LayerWidget connectionLayer = new LayerWidget(this);
+ private LayerWidget interractionLayer = new LayerWidget(this);
+ private LayerWidget clusterLayer = new LayerWidget(this);
+ private Set selectedNodes = Collections.emptySet();
+ private Map loopidx2clusterwidget = new HashMap();
+ private Map inputSwitches = new HashMap();
+ private Map outputSwitches = new HashMap();
+ private WidgetAction moveAction = ActionFactory.createMoveAction (ActionFactory.createFreeMoveStrategy(), this.createMoveProvider());
+ private SceneLayout sceneLayout;
+ private CfgEnv env;
+ private int currentLayout=-1;
+ private int currentRouter=-1;
+ private CfgEditorTopComponent cfgtc;
+ private EventListenerList listenerList = new EventListenerList();
+ private WidgetAction contextPopupAction = this.createContextMenuAction(this);
+ private List