Skip to content

Commit 92c641d

Browse files
committed
Allowing caching of filter creation and speed up colorize filter
1 parent 3029589 commit 92c641d

File tree

7 files changed

+197
-17
lines changed

7 files changed

+197
-17
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package org.graalvm.visualizer.filter;
24+
25+
import org.graalvm.visualizer.graph.Diagram;
26+
27+
import java.util.ArrayList;
28+
29+
/**
30+
* This represents a cacheable filter generated by {@link CustomFilter}. It permits a {@link CustomFilter} to build the
31+
* filter once instead of having to construct the filter for each invocation of the filter.
32+
*/
33+
public class CachedLanguageFilter extends AbstractFilter {
34+
private final ArrayList<AbstractFilter> filters = new ArrayList<>();
35+
private String name = "CachedLanguageFilter";
36+
37+
public CachedLanguageFilter() {
38+
}
39+
40+
@Override
41+
public String getName() {
42+
return name;
43+
}
44+
45+
public void setName(String name) {
46+
this.name = name;
47+
}
48+
49+
@Override
50+
public void apply(Diagram d) {
51+
for (var filter : filters) {
52+
filter.apply(d);
53+
}
54+
}
55+
56+
public void add(AbstractFilter filter) {
57+
filters.add(filter);
58+
}
59+
}

visualizer/IdealGraphVisualizer/Filter/src/main/java/org/graalvm/visualizer/filter/CustomFilter.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ public class CustomFilter extends AbstractFilter {
7777
private String code;
7878
private String name;
7979

80+
/**
81+
* A cached version of the filter chain built by the filter invocation. This permits reusing the filter instead of
82+
* constructor it from scratch each time. If the filter invocation returns an instance of {@link CachedLanguageFilter}
83+
* then that object is saved and used for all future invocations.
84+
*/
85+
private CachedLanguageFilter cachedFilter;
86+
8087
public CustomFilter(String name, String code) {
8188
this(name, code, MIME_JAVASCRIPT, Lookup.EMPTY);
8289
}
@@ -113,6 +120,7 @@ public void setCode(String s) {
113120
return;
114121
}
115122
code = s;
123+
cachedFilter = null;
116124
fireChangedEvent();
117125
}
118126

@@ -265,6 +273,11 @@ private PreparedScript executeHelperScripts(FilterEnvironment env, Map<String, O
265273
})
266274
@Override
267275
public void applyWith(FilterEnvironment env) {
276+
if (cachedFilter != null) {
277+
cachedFilter.apply(env.getDiagram());
278+
return;
279+
}
280+
268281
PreparedScript previous;
269282
synchronized (this) {
270283
previous = executingScript.put(env, null);
@@ -303,7 +316,12 @@ void applyWith0(FilterEnvironment env) {
303316
if (prep == null) {
304317
throw new IllegalStateException(Bundle.ERR_CannotRunScript(name, mimeType));
305318
} else {
306-
evalScript(env, prep, b);
319+
Object result = evalScript(env, prep, b);
320+
if (result instanceof CachedLanguageFilter) {
321+
cachedFilter = (CachedLanguageFilter) result;
322+
cachedFilter.setName(name);
323+
cachedFilter.apply(env.getDiagram());
324+
}
307325
}
308326
} catch (ScriptCancelledException ex) {
309327
throw new FilterCanceledException(env, ex.getCause());

visualizer/IdealGraphVisualizer/Filter/src/main/resources/org/graalvm/visualizer/filter/resources/defaultFilters.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ ColorRule=org.graalvm.visualizer.filter.ColorFilter$ColorRule
2929
CombineFilter=org.graalvm.visualizer.filter.CombineFilter
3030
ConnectionFilter=org.graalvm.visualizer.filter.ConnectionFilter
3131
CustomFilter=org.graalvm.visualizer.filter.CustomFilter
32+
CachedLanguageFilter=org.graalvm.visualizer.filter.CachedLanguageFilter
3233
EdgeColorIndexFilter=org.graalvm.visualizer.filter.EdgeColorIndexFilter
3334
GradientColorFilter=org.graalvm.visualizer.filter.GradientColorFilter
3435
RemoveFilter=org.graalvm.visualizer.filter.RemoveFilter
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.visualizer.graal.filters;
26+
27+
import org.graalvm.visualizer.filter.AbstractFilter;
28+
import org.graalvm.visualizer.graph.Diagram;
29+
import org.graalvm.visualizer.graph.Figure;
30+
31+
import java.awt.Color;
32+
import java.util.HashMap;
33+
import java.util.Map;
34+
import java.util.Set;
35+
36+
37+
/**
38+
* A more efficient bulk coloring implementation.
39+
*/
40+
public class PropertyColorFilter extends AbstractFilter {
41+
Map<String, Map<String, Color>> stringColorMap = new HashMap<>();
42+
43+
public PropertyColorFilter() {
44+
}
45+
46+
@Override
47+
public String getName() {
48+
return getClass().getSimpleName();
49+
}
50+
51+
@Override
52+
public void apply(Diagram diagram) {
53+
applyColorMap(diagram);
54+
}
55+
56+
private void applyColorMap(Diagram diagram) {
57+
Set<String> keys = stringColorMap.keySet();
58+
for (Figure f : diagram.getFigures()) {
59+
for (String property : keys) {
60+
Object value = f.getProperties().get(property);
61+
if (value == null) {
62+
continue;
63+
}
64+
Color color = stringColorMap.get(property).get(value.toString());
65+
if (color != null) {
66+
f.setColor(color);
67+
}
68+
}
69+
}
70+
}
71+
72+
/**
73+
* Color any {@link Figure} with the {@code property} equals to {@code value} with the color {@code color}.
74+
*/
75+
public void addRule(String property, String value, Color color) {
76+
stringColorMap.computeIfAbsent(property, x -> new HashMap<>()).put(value, color);
77+
}
78+
}

visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/color.filter

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,44 @@ var gray = new Color(220, 220, 220);
88
var violet = new Color(201, 148, 199);
99
var black = new Color(0, 0, 0);
1010

11-
colorize("category", "controlSink", red);
12-
colorize("category", "controlSplit", red);
13-
colorize("category", "merge", red);
14-
colorize("category", "begin", orange);
15-
colorize("category", "end", orange);
16-
colorize("category", "fixed", yellow);
17-
colorize("category", "state", lightGreen);
18-
colorize("category", "phi", middleBlue);
19-
colorize("category", "proxy", middleBlue);
20-
colorize("category", "floating", lightBlue);
21-
colorize("class", ".*\\.nodes\\..*ParameterNode$", gray);
22-
colorize("class", ".*\\.nodes\\..*ConstantNode$", gray);
23-
colorize("class", ".*\\.nodes\\..*GuardNode$", violet);
24-
colorize("class", ".*\\.nodes\\.debug\\.BlackholeNode$", black);
11+
var cachedFilter = new CachedLanguageFilter();
12+
13+
var f = new PropertyColorFilter();
14+
f.addRule("category", "controlSink", red);
15+
f.addRule("category", "controlSplit", red);
16+
f.addRule("category", "merge", red);
17+
f.addRule("category", "begin", orange);
18+
f.addRule("category", "end", orange);
19+
f.addRule("category", "fixed", yellow);
20+
f.addRule("category", "state", lightGreen);
21+
f.addRule("category", "phi", middleBlue);
22+
f.addRule("category", "proxy", middleBlue);
23+
f.addRule("category", "floating", lightBlue);
24+
25+
f.addRule("class", "com.oracle.graal.nodes.ParameterNode", gray);
26+
f.addRule("class", "jdk.graal.compiler.nodes.ParameterNode", gray);
27+
f.addRule("class", "org.graalvm.compiler.nodes.ParameterNode", gray);
28+
29+
f.addRule("class", "com.oracle.graal.nodes.ConstantNode", gray);
30+
f.addRule("class", "jdk.graal.compiler.nodes.ConstantNode", gray);
31+
f.addRule("class", "org.graalvm.compiler.nodes.ConstantNode", gray);
32+
33+
f.addRule("class", "com.oracle.graal.nodes.GuardNode", violet);
34+
f.addRule("class", "jdk.graal.compiler.nodes.GuardNode", violet);
35+
f.addRule("class", "org.graalvm.compiler.nodes.GuardNode", violet);
36+
37+
f.addRule("class", "com.oracle.graal.nodes.debug.BlackholeNode", black);
38+
f.addRule("class", "jdk.graal.compiler.nodes.debug.BlackholeNode", black);
39+
f.addRule("class", "org.graalvm.compiler.nodes.debug.BlackholeNode", black);
40+
41+
cachedFilter.add(f);
2542

2643
var f = new GraalEdgeColorFilter();
2744
f.setUsageColor("Successor", red);
2845
f.setUsageColor("Value", blue);
2946
f.setUsageColor("Memory", new Color(0, 128, 0));
30-
f.apply(graph);
47+
48+
cachedFilter.add(f);
49+
50+
// return the cached filter
51+
cachedFilter

visualizer/IdealGraphVisualizer/Graal/src/main/resources/org/graalvm/visualizer/graal/filters/graalFilters.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
GraalCFGFilter=org.graalvm.visualizer.graal.filters.GraalCFGFilter
55
GraalColoringFilter=org.graalvm.visualizer.graal.filters.GraalColoringFilter
66
GraalEdgeColorFilter=org.graalvm.visualizer.graal.filters.GraalEdgeColorFilter
7+
PropertyColorFilter=org.graalvm.visualizer.graal.filters.PropertyColorFilter
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
remove("category", "state");
1+
// Removing orphans also removes any nodes which no longer have any uses.
2+
// This cleans up Constants which were only referenced by FrameStates
3+
removeIncludingOrphans("category", "state")

0 commit comments

Comments
 (0)