Skip to content
Permalink
Browse files
8264842: IGV: different nodes sharing idx are treated as equal
Introduce IGV-specific node identifier and encapsulate it in IGV by showing a
configurable 'short node text' string instead.

Reviewed-by: iveresov, kvn
  • Loading branch information
Roberto Castañeda Lozano committed Apr 23, 2021
1 parent 95f0fd6 commit b3a319c83441a8707fc4ddd1dc6a09d3de3097ac
Showing with 182 additions and 107 deletions.
  1. +2 −0 src/hotspot/share/opto/compile.cpp
  2. +2 −0 src/hotspot/share/opto/compile.hpp
  3. +6 −8 src/hotspot/share/opto/idealGraphPrinter.cpp
  4. +3 −1 src/hotspot/share/opto/node.cpp
  5. +4 −0 src/hotspot/share/opto/node.hpp
  6. +1 −2 src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputNode.java
  7. +33 −1 src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Properties.java
  8. +3 −3 src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/SplitFilter.java
  9. +6 −4 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Connection.java
  10. +12 −4 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java
  11. +2 −34 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Figure.java
  12. +9 −4 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Slot.java
  13. +3 −1 src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java
  14. +46 −20 src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/ViewPanel.form
  15. +38 −20 src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/ViewPanel.java
  16. +3 −1 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
  17. +3 −1 ...s/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java
  18. +2 −1 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java
  19. +4 −2 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/SlotWidget.java
@@ -553,6 +553,7 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
_do_cleanup(false),
_has_reserved_stack_access(target->has_reserved_stack_access()),
#ifndef PRODUCT
_igv_idx(0),
_trace_opto_output(directive->TraceOptoOutputOption),
_print_ideal(directive->PrintIdealOption),
#endif
@@ -859,6 +860,7 @@ Compile::Compile( ciEnv* ci_env,
_inlining_incrementally(false),
_has_reserved_stack_access(false),
#ifndef PRODUCT
_igv_idx(0),
_trace_opto_output(directive->TraceOptoOutputOption),
_print_ideal(directive->PrintIdealOption),
#endif
@@ -293,6 +293,7 @@ class Compile : public Phase {
bool _print_inlining; // True if we should print inlining for this compilation
bool _print_intrinsics; // True if we should print intrinsics for this compilation
#ifndef PRODUCT
uint _igv_idx; // Counter for IGV node identifiers
bool _trace_opto_output;
bool _print_ideal;
bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing
@@ -601,6 +602,7 @@ class Compile : public Phase {
}

#ifndef PRODUCT
uint next_igv_idx() { return _igv_idx++; }
bool trace_opto_output() const { return _trace_opto_output; }
bool print_ideal() const { return _print_ideal; }
bool parsed_irreducible_loop() const { return _parsed_irreducible_loop; }
@@ -340,14 +340,12 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {

if (edges) {

// Output edge
node_idx_t dest_id = n->_idx;
for ( uint i = 0; i < n->len(); i++ ) {
if ( n->in(i) ) {
for (uint i = 0; i < n->len(); i++) {
if (n->in(i)) {
Node *source = n->in(i);
begin_elem(EDGE_ELEMENT);
print_attr(FROM_PROPERTY, source->_idx);
print_attr(TO_PROPERTY, dest_id);
print_attr(FROM_PROPERTY, source->_igv_idx);
print_attr(TO_PROPERTY, n->_igv_idx);
print_attr(INDEX_PROPERTY, i);
end_elem();
}
@@ -357,7 +355,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {

// Output node
begin_head(NODE_ELEMENT);
print_attr(NODE_ID_PROPERTY, n->_idx);
print_attr(NODE_ID_PROPERTY, n->_igv_idx);
end_head();

head(PROPERTIES_ELEMENT);
@@ -715,7 +713,7 @@ void IdealGraphPrinter::print(const char *name, Node *node) {
head(NODES_ELEMENT);
for (uint s = 0; s < block->number_of_nodes(); s++) {
begin_elem(NODE_ELEMENT);
print_attr(NODE_ID_PROPERTY, block->get_node(s)->_idx);
print_attr(NODE_ID_PROPERTY, block->get_node(s)->_igv_idx);
end_elem();
}
tail(NODES_ELEMENT);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
@@ -303,6 +303,7 @@ static void init_node_notes(Compile* C, int idx, Node_Notes* nn) {
inline int Node::Init(int req) {
Compile* C = Compile::current();
int idx = C->next_unique();
NOT_PRODUCT(_igv_idx = C->next_igv_idx());

// Allocate memory for the necessary number of edges.
if (req > 0) {
@@ -531,6 +532,7 @@ Node *Node::clone() const {
bs->register_potential_barrier_node(n);

n->set_idx(C->next_unique()); // Get new unique index as well
NOT_PRODUCT(n->_igv_idx = C->next_igv_idx());
debug_only( n->verify_construction() );
NOT_PRODUCT(nodes_created++);
// Do not patch over the debug_idx of a clone, because it makes it
@@ -323,6 +323,10 @@ class Node {
// preserved in _parse_idx.
const node_idx_t _idx;
DEBUG_ONLY(const node_idx_t _parse_idx;)
// IGV node identifier. It is similar to Node::_debug_idx in that it is unique
// across all compilation phases, but different in that it is initialized in
// each compilation, for stability.
NOT_PRODUCT(node_idx_t _igv_idx;)

// Get the (read-only) number of input edges
uint req() const { return _cnt; }
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, 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
@@ -77,7 +77,6 @@ public InputNode(int id) {

public void setId(int id) {
this.id = id;
getProperties().setProperty("id", "" + id);
}

public int getId() {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, 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
@@ -451,4 +451,36 @@ public void remove() {
public Iterator<Property> iterator() {
return new PropertiesIterator();
}

public final String resolveString(String string) {

StringBuilder sb = new StringBuilder();
boolean inBrackets = false;
StringBuilder curIdent = new StringBuilder();

for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (inBrackets) {
if (c == ']') {
String value = get(curIdent.toString());
if (value == null) {
value = "";
}
sb.append(value);
inBrackets = false;
} else {
curIdent.append(c);
}
} else {
if (c == '[') {
inBrackets = true;
curIdent = new StringBuilder();
} else {
sb.append(c);
}
}
}

return sb.toString();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, 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
@@ -63,7 +63,7 @@ public void apply(Diagram d) {
}


String s = Figure.resolveString(propertyName, f.getProperties());
String s = f.getProperties().resolveString(propertyName);
if (s != null) {
os.setShortName(s);
}
@@ -79,7 +79,7 @@ public void apply(Diagram d) {
is.setColor(f.getColor());
}

String s = Figure.resolveString(propertyName, f.getProperties());
String s = f.getProperties().resolveString(propertyName);
if (s != null) {
is.setShortName(s);
}
@@ -128,10 +128,12 @@ public String getToolTipText() {
if (type != null) {
builder.append(type).append(" ");
}
builder.append("from ");
builder.append(getOutputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
builder.append(" to ");
builder.append(getInputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
// Resolve strings lazily every time the tooltip is shown, instead of
// eagerly as for node labels, for efficiency.
String shortNodeText = getInputSlot().getFigure().getDiagram().getShortNodeText();
builder.append(getOutputSlot().getFigure().getProperties().resolveString(shortNodeText));
builder.append("");
builder.append(getInputSlot().getFigure().getProperties().resolveString(shortNodeText));
return builder.toString();
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, 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
@@ -43,6 +43,7 @@
private InputGraph graph;
private int curId;
private String nodeText;
private String shortNodeText;
private final Font font;
private final Font slotFont;
private final Font boldFont;
@@ -63,6 +64,7 @@ private Diagram() {
figures = new ArrayList<>();
blocks = new LinkedHashMap<>(8);
this.nodeText = "";
this.shortNodeText = "";
this.font = new Font("Arial", Font.PLAIN, 12);
this.slotFont = new Font("Arial", Font.PLAIN, 10);
this.boldFont = this.font.deriveFont(Font.BOLD);
@@ -77,6 +79,10 @@ public String getNodeText() {
return nodeText;
}

public String getShortNodeText() {
return shortNodeText;
}

public void updateBlocks() {
blocks.clear();
for (InputBlock b : graph.getBlocks()) {
@@ -86,15 +92,15 @@ public void updateBlocks() {
}

public Diagram getNext() {
return Diagram.createDiagram(graph.getNext(), nodeText);
return Diagram.createDiagram(graph.getNext(), nodeText, shortNodeText);
}

public Collection<Block> getBlocks() {
return Collections.unmodifiableCollection(blocks.values());
}

public Diagram getPrev() {
return Diagram.createDiagram(graph.getPrev(), nodeText);
return Diagram.createDiagram(graph.getPrev(), nodeText, shortNodeText);
}

public List<Figure> getFigures() {
@@ -130,14 +136,16 @@ public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot, S
return map;
}

public static Diagram createDiagram(InputGraph graph, String nodeText) {
public static Diagram createDiagram(InputGraph graph, String nodeText,
String shortNodeText) {
if (graph == null) {
return null;
}

Diagram d = new Diagram();
d.graph = graph;
d.nodeText = nodeText;
d.shortNodeText = shortNodeText;

d.updateBlocks();

@@ -278,7 +278,7 @@ void removeOutputSlot(OutputSlot s) {
// search is done on the node label (without line breaks). See also
// class NodeQuickSearch in the View module.
for (InputNode n : getSource().getSourceNodes()) {
String label = resolveString(diagram.getNodeText(), n.getProperties());
String label = n.getProperties().resolveString(diagram.getNodeText());
n.getProperties().setProperty("label", label.replaceAll("\\R", " "));
}
}
@@ -290,44 +290,12 @@ public void updateLines() {
String[] result = new String[strings.length];

for (int i = 0; i < strings.length; i++) {
result[i] = resolveString(strings[i], getProperties());
result[i] = getProperties().resolveString(strings[i]);
}

lines = result;
}

public static final String resolveString(String string, Properties properties) {

StringBuilder sb = new StringBuilder();
boolean inBrackets = false;
StringBuilder curIdent = new StringBuilder();

for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (inBrackets) {
if (c == ']') {
String value = properties.get(curIdent.toString());
if (value == null) {
value = "";
}
sb.append(value);
inBrackets = false;
} else {
curIdent.append(c);
}
} else {
if (c == '[') {
inBrackets = true;
curIdent = new StringBuilder();
} else {
sb.append(c);
}
}
}

return sb.toString();
}

@Override
public Dimension getSize() {
if (VERTICAL_LAYOUT) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, 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
@@ -139,11 +139,16 @@ public String getShortName() {

public String getToolTipText() {
StringBuilder sb = new StringBuilder();
sb.append(text);
String shortNodeText = figure.getDiagram().getShortNodeText();
if (!text.isEmpty()) {
sb.append(text);
if (!shortNodeText.isEmpty()) {
sb.append(": ");
}
}

for (InputNode n : getSource().getSourceNodes()) {
sb.append(StringUtils.escapeHTML("Node (ID=" + n.getId() + "): " + n.getProperties().get("name")));
sb.append("<br>");
sb.append(StringUtils.escapeHTML(n.getProperties().resolveString(shortNodeText)));
}

return sb.toString();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,8 @@

public final static String NODE_TEXT = "nodeText";
public final static String NODE_TEXT_DEFAULT = "[idx] [name]";
public final static String NODE_SHORT_TEXT = "nodeShortText";
public final static String NODE_SHORT_TEXT_DEFAULT = "[idx] [name]";
public final static String NODE_WIDTH = "nodeWidth";
public final static String NODE_WIDTH_DEFAULT = "100";
public final static String PORT = "port";
Loading

1 comment on commit b3a319c

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on b3a319c Apr 23, 2021

Please sign in to comment.