Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ bench-results.json
jmh_result.json
/vm/src/installer/dist/
visualizer/IdealGraphVisualizer/*/target/
visualizer/C1Visualizer/*/target/
/.src-rev
*.interp
*.tokens
Expand Down
55 changes: 32 additions & 23 deletions compiler/mx.compiler/mx_graal_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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'
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions compiler/mx.compiler/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},

Expand Down
32 changes: 32 additions & 0 deletions visualizer/C1Visualizer.md
Original file line number Diff line number Diff line change
@@ -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`.
97 changes: 97 additions & 0 deletions visualizer/C1Visualizer/BlockView/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>C1Visualizer-parent</artifactId>
<groupId>at.ssw.visualizer</groupId>
<version>1.14-SNAPSHOT</version>
</parent>
<groupId>at.ssw.visualizer</groupId>
<artifactId>BlockView</artifactId>
<version>1.14-SNAPSHOT</version>
<packaging>nbm</packaging>
<name>BlockView</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>at.ssw.visualizer</groupId>
<artifactId>VisualizerUI</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>at.ssw.visualizer</groupId>
<artifactId>CompilationModel</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.netbeans.api</groupId>
<artifactId>org-openide-explorer</artifactId>
<version>${netbeans.version}</version>
</dependency>
<dependency>
<groupId>org.netbeans.api</groupId>
<artifactId>org-openide-loaders</artifactId>
<version>${netbeans.version}</version>
</dependency>
<dependency>
<groupId>org.netbeans.api</groupId>
<artifactId>org-openide-nodes</artifactId>
<version>${netbeans.version}</version>
</dependency>
<dependency>
<groupId>org.netbeans.api</groupId>
<artifactId>org-openide-util</artifactId>
<version>${netbeans.version}</version>
</dependency>
<dependency>
<groupId>org.netbeans.api</groupId>
<artifactId>org-openide-util-lookup</artifactId>
<version>${netbeans.version}</version>
</dependency>
<dependency>
<groupId>org.netbeans.api</groupId>
<artifactId>org-openide-windows</artifactId>
<version>${netbeans.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.netbeans.utilities</groupId>
<artifactId>nbm-maven-plugin</artifactId>
<version>${nbmmvnplugin.version}</version>
<extensions>true</extensions>
<configuration>
<publicPackages>
<publicPackage>at.ssw.visualizer.BlockView</publicPackage>
</publicPackages>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${mvncompilerplugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${mvnjarplugin.version}</version>
<configuration>
<!-- to have the jar plugin pickup the nbm generated manifest -->
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -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<BasicBlock> 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<String> flags) {
StringBuilder sb = new StringBuilder();
String prefix = "";
for (String flag : flags) {
sb.append(prefix).append(flag);
prefix = ", ";
}
return sb.toString();
}

private String formatBlocks(List<BasicBlock> blocks) {
StringBuilder sb = new StringBuilder();
String prefix = "";
for (BasicBlock block : blocks) {
sb.append(prefix).append(block.getName());
prefix = ", ";
}
return sb.toString();
}
}
Loading