mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-19 04:13:07 +00:00
8261336: IGV: enhance default filters
Add filters to color and hide parts of the graph based on node categories or estimated execution frequency, and simplify remaining filters. Co-authored-by: Christian Hagedorn <chagedorn@openjdk.org> Reviewed-by: vlivanov, chagedorn, thartmann
This commit is contained in:
parent
3f8819c666
commit
16bd7d381f
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 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
|
||||
@ -30,6 +30,7 @@
|
||||
#include "opto/parse.hpp"
|
||||
#include "runtime/threadCritical.hpp"
|
||||
#include "runtime/threadSMR.hpp"
|
||||
#include "utilities/stringUtils.hpp"
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -378,9 +379,39 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
|
||||
print_prop("block", C->cfg()->get_block(0)->_pre_order);
|
||||
} else {
|
||||
print_prop("block", block->_pre_order);
|
||||
// Print estimated execution frequency, normalized within a [0,1] range.
|
||||
buffer[0] = 0;
|
||||
stringStream freq(buffer, sizeof(buffer) - 1);
|
||||
// Higher precision has no practical effect in visualizations.
|
||||
freq.print("%.8f", block->_freq / _max_freq);
|
||||
assert(freq.size() < sizeof(buffer), "size in range");
|
||||
// Enforce dots as decimal separators, as required by IGV.
|
||||
StringUtils::replace_no_expand(buffer, ",", ".");
|
||||
print_prop("frequency", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
switch (t->category()) {
|
||||
case Type::Category::Data:
|
||||
print_prop("category", "data");
|
||||
break;
|
||||
case Type::Category::Memory:
|
||||
print_prop("category", "memory");
|
||||
break;
|
||||
case Type::Category::Mixed:
|
||||
print_prop("category", "mixed");
|
||||
break;
|
||||
case Type::Category::Control:
|
||||
print_prop("category", "control");
|
||||
break;
|
||||
case Type::Category::Other:
|
||||
print_prop("category", "other");
|
||||
break;
|
||||
case Type::Category::Undef:
|
||||
print_prop("category", "undef");
|
||||
break;
|
||||
}
|
||||
|
||||
const jushort flags = node->flags();
|
||||
if (flags & Node::Flag_is_Copy) {
|
||||
print_prop("is_copy", "true");
|
||||
@ -649,6 +680,16 @@ void IdealGraphPrinter::print(const char *name, Node *node) {
|
||||
VectorSet temp_set;
|
||||
|
||||
head(NODES_ELEMENT);
|
||||
if (C->cfg() != NULL) {
|
||||
// Compute the maximum estimated frequency in the current graph.
|
||||
_max_freq = 1.0e-6;
|
||||
for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) {
|
||||
Block* block = C->cfg()->get_block(i);
|
||||
if (block->_freq > _max_freq) {
|
||||
_max_freq = block->_freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
walk_nodes(node, false, &temp_set);
|
||||
tail(NODES_ELEMENT);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 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
|
||||
@ -92,6 +92,7 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
|
||||
PhaseChaitin* _chaitin;
|
||||
bool _traverse_outs;
|
||||
Compile *C;
|
||||
double _max_freq;
|
||||
|
||||
void print_method(ciMethod *method, int bci, InlineTree *tree);
|
||||
void print_inline_tree(InlineTree *tree);
|
||||
|
||||
@ -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
|
||||
@ -1113,6 +1113,73 @@ void Type::dump_stats() {
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------category---------------------------------------
|
||||
#ifndef PRODUCT
|
||||
Type::Category Type::category() const {
|
||||
const TypeTuple* tuple;
|
||||
switch (base()) {
|
||||
case Type::Int:
|
||||
case Type::Long:
|
||||
case Type::Half:
|
||||
case Type::NarrowOop:
|
||||
case Type::NarrowKlass:
|
||||
case Type::Array:
|
||||
case Type::VectorA:
|
||||
case Type::VectorS:
|
||||
case Type::VectorD:
|
||||
case Type::VectorX:
|
||||
case Type::VectorY:
|
||||
case Type::VectorZ:
|
||||
case Type::AnyPtr:
|
||||
case Type::RawPtr:
|
||||
case Type::OopPtr:
|
||||
case Type::InstPtr:
|
||||
case Type::AryPtr:
|
||||
case Type::MetadataPtr:
|
||||
case Type::KlassPtr:
|
||||
case Type::Function:
|
||||
case Type::Return_Address:
|
||||
case Type::FloatTop:
|
||||
case Type::FloatCon:
|
||||
case Type::FloatBot:
|
||||
case Type::DoubleTop:
|
||||
case Type::DoubleCon:
|
||||
case Type::DoubleBot:
|
||||
return Category::Data;
|
||||
case Type::Memory:
|
||||
return Category::Memory;
|
||||
case Type::Control:
|
||||
return Category::Control;
|
||||
case Type::Top:
|
||||
case Type::Abio:
|
||||
case Type::Bottom:
|
||||
return Category::Other;
|
||||
case Type::Bad:
|
||||
case Type::lastype:
|
||||
return Category::Undef;
|
||||
case Type::Tuple:
|
||||
// Recursive case. Return CatMixed if the tuple contains types of
|
||||
// different categories (e.g. CallStaticJavaNode's type), or the specific
|
||||
// category if all types are of the same category (e.g. IfNode's type).
|
||||
tuple = is_tuple();
|
||||
if (tuple->cnt() == 0) {
|
||||
return Category::Undef;
|
||||
} else {
|
||||
Category first = tuple->field_at(0)->category();
|
||||
for (uint i = 1; i < tuple->cnt(); i++) {
|
||||
if (tuple->field_at(i)->category() != first) {
|
||||
return Category::Mixed;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
default:
|
||||
assert(false, "unmatched base type: all base types must be categorized");
|
||||
}
|
||||
return Category::Undef;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------typerr-----------------------------------------
|
||||
void Type::typerr( const Type *t ) const {
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -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
|
||||
@ -364,6 +364,17 @@ public:
|
||||
}
|
||||
virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
|
||||
static void dump_stats();
|
||||
// Groups of types, for debugging and visualization only.
|
||||
enum class Category {
|
||||
Data,
|
||||
Memory,
|
||||
Mixed, // Tuples with types of different categories.
|
||||
Control,
|
||||
Other, // {Type::Top, Type::Abio, Type::Bottom}.
|
||||
Undef // {Type::Bad, Type::lastype}, for completeness.
|
||||
};
|
||||
// Return the category of this type.
|
||||
Category category() const;
|
||||
|
||||
static const char* str(const Type* t);
|
||||
#endif
|
||||
|
||||
@ -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,10 +63,8 @@ public class ConnectionFilter extends AbstractFilter {
|
||||
for (Figure f : figures) {
|
||||
for (OutputSlot os : f.getOutputSlots()) {
|
||||
for (Connection c : os.getConnections()) {
|
||||
if (figures.contains(c.getInputSlot().getFigure())) {
|
||||
c.setStyle(rule.getLineStyle());
|
||||
c.setColor(rule.getLineColor());
|
||||
}
|
||||
c.setStyle(rule.getLineStyle());
|
||||
c.setColor(rule.getLineColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,33 +2,5 @@
|
||||
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
|
||||
<filesystem>
|
||||
<folder name="Filters">
|
||||
<file name="Coloring" url="filters/color.filter">
|
||||
<attr name="enabled" boolvalue="true"/>
|
||||
</file>
|
||||
|
||||
|
||||
<file name="Stamp Coloring" url="filters/stampColor.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
</file>
|
||||
|
||||
<file name="Probability Coloring" url="filters/probability.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
</file>
|
||||
|
||||
<file name="Call Graph Coloring" url="filters/callgraph.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
</file>
|
||||
|
||||
<file name="Reduce Edges" url="filters/reduceEdges.filter">
|
||||
<attr name="enabled" boolvalue="true"/>
|
||||
</file>
|
||||
|
||||
<file name="Remove State" url="filters/removeState.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
</file>
|
||||
|
||||
<file name="Remove Floating" url="filters/removeFloating.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
</file>
|
||||
</folder>
|
||||
</filesystem>
|
||||
|
||||
@ -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
|
||||
@ -46,7 +46,8 @@ public class Connection implements Source.Provider, Link {
|
||||
|
||||
NORMAL,
|
||||
DASHED,
|
||||
BOLD
|
||||
BOLD,
|
||||
INVISIBLE
|
||||
}
|
||||
private InputSlot inputSlot;
|
||||
private OutputSlot outputSlot;
|
||||
|
||||
@ -1,18 +1,25 @@
|
||||
colorize("name", ".*", yellow);
|
||||
colorize("name", "Catch.*", blue);
|
||||
colorize("name", "Region|Loop|CountedLoop|Root", red);
|
||||
colorize("name", "CProj|IfFalse|IfTrue|JProj|CatchProj", magenta);
|
||||
colorize("name", "Con.*", orange);
|
||||
colorize("name", "Parm|Proj", lightGray);
|
||||
var mixedNodeColor = java.awt.Color.decode("#ffaabb");
|
||||
var controlNodeColor = java.awt.Color.decode("#ee8866");
|
||||
var otherNodeColor = java.awt.Color.decode("#eedd88");
|
||||
var dataNodeColor = java.awt.Color.decode("#adcbea");
|
||||
var memoryNodeColor = java.awt.Color.decode("#babb00");
|
||||
|
||||
// Nodes with bci
|
||||
colorize("bci", "..*", magenta);
|
||||
var mixedEdgeColor = java.awt.Color.decode("#ff7f99");
|
||||
var controlEdgeColor = java.awt.Color.decode("#e75828");
|
||||
var otherEdgeColor = java.awt.Color.decode("#dfc025");
|
||||
var dataEdgeColor = java.awt.Color.decode("#3178c2");
|
||||
var memoryEdgeColor = java.awt.Color.decode("#828200");
|
||||
|
||||
colorize("category", "data", dataNodeColor);
|
||||
colorize("category", "memory", memoryNodeColor);
|
||||
colorize("category", "mixed", mixedNodeColor);
|
||||
colorize("category", "control", controlNodeColor);
|
||||
colorize("category", "other", otherNodeColor);
|
||||
|
||||
// Line style
|
||||
var f = new ColorFilter("Line Style filter");
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "data")), null, dataEdgeColor, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "memory")), null, memoryEdgeColor, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "mixed")), null, mixedEdgeColor, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "control")), null, controlEdgeColor, null));
|
||||
f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "other")), null, otherEdgeColor, null));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,23 @@
|
||||
// Color nodes by estimated execution frequency. Applies only when control-flow
|
||||
// graph information is available (from "Global Code Motion" on).
|
||||
|
||||
// These colors are generated by running:
|
||||
// $ python3 extract-colors.py --steps 10 --colormap coolwarm
|
||||
var step0Color = java.awt.Color.decode("#3b4cc0");
|
||||
var step1Color = java.awt.Color.decode("#5977e3");
|
||||
var step2Color = java.awt.Color.decode("#7b9ff9");
|
||||
var step3Color = java.awt.Color.decode("#9ebeff");
|
||||
var step4Color = java.awt.Color.decode("#c0d4f5");
|
||||
var step5Color = java.awt.Color.decode("#dddcdc");
|
||||
var step6Color = java.awt.Color.decode("#f2cbb7");
|
||||
var step7Color = java.awt.Color.decode("#f7ac8e");
|
||||
var step8Color = java.awt.Color.decode("#ee8468");
|
||||
var step9Color = java.awt.Color.decode("#d65244");
|
||||
var step10Color = java.awt.Color.decode("#b40426");
|
||||
|
||||
var colors = [step0Color, step1Color, step2Color, step3Color, step4Color, step5Color, step6Color, step7Color, step8Color, step9Color, step10Color]
|
||||
var fractions = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
|
||||
|
||||
// The max value is set to 1.01 instead of 1.0 to workaround a (numerical?)
|
||||
// issue where nodes with frequencies close (but not equal to) 1.0 are not colored.
|
||||
colorizeGradientCustom("frequency", 0.0, 1.01, "logarithmic", colors, fractions, 1024);
|
||||
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (c) 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
|
||||
# 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.
|
||||
|
||||
import matplotlib.cm
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--steps', type=int, default=10)
|
||||
parser.add_argument('--colormap', default='coolwarm')
|
||||
args = parser.parse_args()
|
||||
|
||||
cmap = matplotlib.cm.get_cmap(args.colormap)
|
||||
n = args.steps
|
||||
|
||||
for step in range(n + 1):
|
||||
point = step / float(n)
|
||||
rgb = tuple([int(round(c * 255)) for c in cmap(point)[0:3]])
|
||||
hex = '#%02x%02x%02x' % rgb
|
||||
print("var step" + str(step) + "Color" + " = java.awt.Color.decode(\"" + \
|
||||
hex + "\");")
|
||||
@ -0,0 +1,3 @@
|
||||
var f = new RemoveFilter("Hide control subgraph");
|
||||
f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "control"))));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,5 @@
|
||||
var f = new ConnectionFilter("Hide control edges");
|
||||
f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "control")),
|
||||
white,
|
||||
Connection.ConnectionStyle.INVISIBLE));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,3 @@
|
||||
var f = new RemoveFilter("Hide data subgraph");
|
||||
f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "data"))));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,5 @@
|
||||
var f = new ConnectionFilter("Hide data edges");
|
||||
f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "data")),
|
||||
white,
|
||||
Connection.ConnectionStyle.INVISIBLE));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,3 @@
|
||||
var f = new RemoveFilter("Hide memory subgraph");
|
||||
f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "memory"))));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,5 @@
|
||||
var f = new ConnectionFilter("Hide memory edges");
|
||||
f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "memory")),
|
||||
white,
|
||||
Connection.ConnectionStyle.INVISIBLE));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,3 @@
|
||||
var f = new RemoveFilter("Hide mixed subgraph");
|
||||
f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "mixed"))));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,5 @@
|
||||
var f = new ConnectionFilter("Hide mixed edges");
|
||||
f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "mixed")),
|
||||
white,
|
||||
Connection.ConnectionStyle.INVISIBLE));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,3 @@
|
||||
var f = new RemoveFilter("Hide other subgraph");
|
||||
f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "other"))));
|
||||
f.apply(graph);
|
||||
@ -0,0 +1,5 @@
|
||||
var f = new ConnectionFilter("Hide other edges");
|
||||
f.addRule(new ConnectionFilter.ConnectionStyleRule(new MatcherSelector(new Properties.StringPropertyMatcher("category", "other")),
|
||||
white,
|
||||
Connection.ConnectionStyle.INVISIBLE));
|
||||
f.apply(graph);
|
||||
@ -1,24 +1,27 @@
|
||||
// Remove all nodes except control, mixed, and nodes of 'bottom' type that are
|
||||
// successors of control nodes (typically 'Halt', 'Return', etc.).
|
||||
|
||||
var f = new RemoveFilter("Show only control flow");
|
||||
f.addRule(
|
||||
new RemoveFilter.RemoveRule(
|
||||
new InvertSelector(
|
||||
new OrSelector(
|
||||
new OrSelector(
|
||||
new MatcherSelector(
|
||||
new Properties.RegexpPropertyMatcher("category", "control|mixed")
|
||||
),
|
||||
new AndSelector(
|
||||
new SuccessorSelector(
|
||||
new MatcherSelector(
|
||||
new Properties.StringPropertyMatcher("type", "control")
|
||||
new Properties.RegexpPropertyMatcher("type", "control")
|
||||
)
|
||||
),
|
||||
new MatcherSelector(
|
||||
new Properties.StringPropertyMatcher("type", "control")
|
||||
new MatcherSelector(
|
||||
new Properties.RegexpPropertyMatcher("type", "bottom")
|
||||
)
|
||||
),
|
||||
new MatcherSelector(
|
||||
new Properties.StringPropertyMatcher("name", "Start")
|
||||
)
|
||||
)
|
||||
), false
|
||||
),
|
||||
false
|
||||
)
|
||||
);
|
||||
f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store."))));
|
||||
f.apply(graph);
|
||||
@ -1,8 +0,0 @@
|
||||
remove("dump_spec", "FramePtr|ReturnAdr|I_O");
|
||||
removeInputs("name", "Root");
|
||||
var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
|
||||
f.apply(graph);
|
||||
removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
|
||||
removeInputs("name", "Unlock|Lock", 7);
|
||||
removeInputs("name", "Allocate", 7);
|
||||
removeInputs("name", "AllocateArray", 9);
|
||||
@ -1,6 +1,19 @@
|
||||
// Hide secondary edges.
|
||||
remove("dump_spec", "FramePtr|ReturnAdr|I_O");
|
||||
removeInputs("name", "Root");
|
||||
var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
|
||||
f.apply(graph);
|
||||
removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
|
||||
removeInputs("name", "Unlock|Lock", 7);
|
||||
removeInputs("name", "Allocate", 7);
|
||||
removeInputs("name", "AllocateArray", 9);
|
||||
|
||||
// Combine projection nodes.
|
||||
var f = new CombineFilter("Combine Filter");
|
||||
f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
|
||||
f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
|
||||
f.apply(graph);
|
||||
|
||||
// Inline (split) constant nodes.
|
||||
split("name", "BoxLock");
|
||||
split("name", "(Con.*)|(loadCon.*)", "[dump_spec]");
|
||||
@ -2,28 +2,60 @@
|
||||
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
|
||||
<filesystem>
|
||||
<folder name="Filters">
|
||||
<file name="C2 Basic Coloring" url="filters/color.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<file name="Color by category" url="filters/color.filter">
|
||||
<attr name="enabled" boolvalue="true"/>
|
||||
</file>
|
||||
<file name="C2 Matcher Flags Coloring" url="filters/matchingFlags.filter">
|
||||
<file name="Color by execution frequency" url="filters/colorFrequency.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="C2 Basic Coloring"/>
|
||||
<attr name="after" stringvalue="Color by category"/>
|
||||
</file>
|
||||
<file name="C2 Register Coloring" url="filters/register.filter">
|
||||
<file name="Simplify graph" url="filters/structural.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="C2 Matcher Flags Coloring"/>
|
||||
<attr name="after" stringvalue="Color by execution frequency"/>
|
||||
</file>
|
||||
<file name="C2 Only Control Flow" url="filters/onlyControlFlow.filter">
|
||||
<file name="Hide data subgraph" url="filters/hideData.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="C2 Register Coloring"/>
|
||||
<attr name="after" stringvalue="Simplify graph"/>
|
||||
</file>
|
||||
<file name="C2 Remove Filter" url="filters/remove.filter">
|
||||
<file name="Hide memory subgraph" url="filters/hideMemory.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="C2 Only Control Flow"/>
|
||||
<attr name="after" stringvalue="Hide data subgraph"/>
|
||||
</file>
|
||||
<file name="C2 Structural" url="filters/structural.filter">
|
||||
<file name="Hide control subgraph" url="filters/hideControl.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="C2 Remove Filter"/>
|
||||
<attr name="after" stringvalue="Hide memory subgraph"/>
|
||||
</file>
|
||||
</folder>
|
||||
<file name="Hide mixed subgraph" url="filters/hideMixed.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide control subgraph"/>
|
||||
</file>
|
||||
<file name="Hide other subgraph" url="filters/hideOther.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide mixed subgraph"/>
|
||||
</file>
|
||||
<file name="Show control flow only" url="filters/onlyControlFlow.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide other subgraph"/>
|
||||
</file>
|
||||
<file name="Hide data edges" url="filters/hideDataEdges.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Show control flow only"/>
|
||||
</file>
|
||||
<file name="Hide memory edges" url="filters/hideMemoryEdges.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide data edges"/>
|
||||
</file>
|
||||
<file name="Hide control edges" url="filters/hideControlEdges.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide memory edges"/>
|
||||
</file>
|
||||
<file name="Hide mixed edges" url="filters/hideMixedEdges.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide control edges"/>
|
||||
</file>
|
||||
<file name="Hide other edges" url="filters/hideOtherEdges.filter">
|
||||
<attr name="enabled" boolvalue="false"/>
|
||||
<attr name="after" stringvalue="Hide mixed edges"/>
|
||||
</file>
|
||||
</folder>
|
||||
</filesystem>
|
||||
|
||||
@ -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
|
||||
@ -779,6 +779,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
|
||||
|
||||
boolean isBold = false;
|
||||
boolean isDashed = true;
|
||||
boolean isVisible = true;
|
||||
|
||||
for (Connection c : connectionList) {
|
||||
|
||||
@ -789,6 +790,10 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
|
||||
if (c.getStyle() != Connection.ConnectionStyle.DASHED) {
|
||||
isDashed = false;
|
||||
}
|
||||
|
||||
if (c.getStyle() == Connection.ConnectionStyle.INVISIBLE) {
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
LineWidget newPredecessor = predecessor;
|
||||
@ -804,6 +809,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
|
||||
curAnimator = null;
|
||||
}
|
||||
LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, curAnimator, isBold, isDashed);
|
||||
w.setVisible(isVisible);
|
||||
lineCache.add(curPair);
|
||||
|
||||
newPredecessor = w;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user