Skip to content

Commit 771bf74

Browse files
steve-sntemmar
authored andcommitted
[GR-48816] Truffle DSL: introduce new warning 'truffle-interpreted-performance'.
PullRequest: graal/15632
2 parents 6aa1a4a + 9ef3843 commit 771bf74

File tree

16 files changed

+393
-23
lines changed

16 files changed

+393
-23
lines changed

truffle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This changelog summarizes major changes between Truffle versions relevant to lan
1313
* GR-45863 Adopted onYield() and onResume() instrumentation events in the debugger stepping logic.
1414
* [GR-21361] Remove support for legacy `<language-id>.home` system property. Only `org.graalvm.language.<language-id>.home` will be used.
1515
* GR-41302 Added the `--engine.AssertProbes` option, which asserts that enter and return are always called in pairs on ProbeNode, verifies correct behavior of wrapper nodes. Java asserts need to be turned on for this option to have an effect.
16+
* GR-48816 Added new interpreted performance warning to Truffle DSL.
1617

1718
## Version 23.1.0
1819

truffle/src/com.oracle.truffle.api.benchmark/src/com/oracle/truffle/api/benchmark/NodeInliningBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ static long do1(long v0, long v1, long v2, long v3,
331331
}
332332
}
333333

334-
@SuppressWarnings({"truffle-inlining", "truffle-sharing"})
334+
@SuppressWarnings({"truffle-inlining", "truffle-sharing", "truffle-interpreted-performance"})
335335
public abstract static class InlinedSharedExclusiveNode extends Node {
336336

337337
abstract long execute(long v0, long v1, long v2, long v3);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.api.dsl.test;
42+
43+
import java.lang.annotation.Retention;
44+
import java.lang.annotation.RetentionPolicy;
45+
46+
/**
47+
* This annotation is internally known by the dsl processor and used to expect warnings for testing
48+
* purposes. This is not part of public API.
49+
*/
50+
@Retention(RetentionPolicy.RUNTIME)
51+
public @interface ExpectWarning {
52+
53+
String[] value();
54+
55+
}

truffle/src/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GR44836_1Test.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.oracle.truffle.api.nodes.Node;
5858
import com.oracle.truffle.api.nodes.RootNode;
5959

60+
@SuppressWarnings("truffle-interpreted-performance")
6061
public class GR44836_1Test {
6162

6263
static class TestRootNode extends RootNode {

truffle/src/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GR44836_2Test.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import com.oracle.truffle.api.nodes.Node;
5353
import com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest;
5454

55+
@SuppressWarnings("truffle-interpreted-performance")
5556
public class GR44836_2Test extends AbstractPolyglotTest {
5657

5758
@Test

truffle/src/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GenerateInlineTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
import com.oracle.truffle.api.strings.TruffleString.CompactionLevel;
135135
import com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest;
136136

137-
@SuppressWarnings({"truffle-neverdefault", "truffle-sharing"})
137+
@SuppressWarnings({"truffle-neverdefault", "truffle-sharing", "truffle-interpreted-performance"})
138138
public class GenerateInlineTest extends AbstractPolyglotTest {
139139

140140
@GenerateInline
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
/*
2+
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.api.dsl.test;
42+
43+
import com.oracle.truffle.api.dsl.Bind;
44+
import com.oracle.truffle.api.dsl.Cached;
45+
import com.oracle.truffle.api.dsl.Cached.Exclusive;
46+
import com.oracle.truffle.api.dsl.Cached.Shared;
47+
import com.oracle.truffle.api.dsl.GenerateCached;
48+
import com.oracle.truffle.api.dsl.GenerateInline;
49+
import com.oracle.truffle.api.dsl.Specialization;
50+
import com.oracle.truffle.api.nodes.IndirectCallNode;
51+
import com.oracle.truffle.api.nodes.Node;
52+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
53+
54+
public class SharedAndNonSharedInlineWarningTest {
55+
private static final String EXPECTED_WARNING = "It is discouraged that specializations with specialization data class combine shared and exclusive%";
56+
57+
@GenerateInline
58+
@GenerateCached(false)
59+
public abstract static class InlineNode extends Node {
60+
public abstract Object execute(Node inliningTarget, Object arg);
61+
62+
@Specialization
63+
static Object spec1(int arg) {
64+
return arg;
65+
}
66+
67+
@Specialization
68+
static Object spec2(Object arg,
69+
@Cached(value = "arg", neverDefault = false) Object cachedArg) {
70+
return cachedArg == arg;
71+
}
72+
}
73+
74+
@GenerateInline(false)
75+
@GenerateCached
76+
public abstract static class NonInlineNode extends Node {
77+
public abstract Object execute(Object arg);
78+
79+
@Specialization
80+
static Object spec3(int arg) {
81+
return arg;
82+
}
83+
}
84+
85+
// ------------------------------------------------------------------------
86+
// Mixing WITHOUT a data-class is OK:
87+
88+
@GenerateCached
89+
@GenerateInline(false)
90+
public abstract static class MixProfilesWithoutDataClassNode extends Node {
91+
public abstract Object execute(Object arg);
92+
93+
@Specialization
94+
static Object mixProfilesWithoutDataClass(int a,
95+
@Bind("this") Node node,
96+
@Shared @Cached InlinedBranchProfile sharedBranch,
97+
@Exclusive @Cached InlinedBranchProfile exclusiveBranch) {
98+
sharedBranch.enter(node);
99+
exclusiveBranch.enter(node);
100+
return a;
101+
}
102+
103+
@Specialization
104+
static Object dummy(double a,
105+
@Bind("this") Node node,
106+
@Shared @Cached InlinedBranchProfile sharedBranch) {
107+
sharedBranch.enter(node);
108+
return a;
109+
}
110+
}
111+
112+
@GenerateCached
113+
@GenerateInline(false)
114+
public abstract static class NonMixedProfilesWithoutDataClassNode extends Node {
115+
public abstract Object execute(Object arg);
116+
117+
@Specialization
118+
static Object mixProfilesWithoutDataClass(int a,
119+
@Bind("this") Node node,
120+
@Exclusive @Cached InlinedBranchProfile sharedBranch,
121+
@Exclusive @Cached InlinedBranchProfile exclusiveBranch) {
122+
sharedBranch.enter(node);
123+
exclusiveBranch.enter(node);
124+
return a;
125+
}
126+
127+
@Specialization
128+
static Object dummy(double a,
129+
@Bind("this") Node node,
130+
@Exclusive @Cached InlinedBranchProfile sharedBranch) {
131+
sharedBranch.enter(node);
132+
return a;
133+
}
134+
}
135+
136+
@GenerateCached
137+
@GenerateInline(false)
138+
public abstract static class MixProfileAndNodeWithoutDataClassNode extends Node {
139+
public abstract Object execute(Object arg);
140+
141+
@Specialization
142+
static Object mixProfilesWithoutDataClass(int a,
143+
@Bind("this") Node node,
144+
@Shared @Cached InlinedBranchProfile sharedBranch,
145+
@Exclusive @Cached InlineNode exclusiveNode) {
146+
sharedBranch.enter(node);
147+
exclusiveNode.execute(node, a);
148+
return a;
149+
}
150+
151+
@Specialization
152+
static Object dummy(double a,
153+
@Bind("this") Node node,
154+
@Shared @Cached InlinedBranchProfile sharedBranch) {
155+
sharedBranch.enter(node);
156+
return a;
157+
}
158+
}
159+
160+
@GenerateCached
161+
@GenerateInline(false)
162+
public abstract static class MixNodesWithoutDataClassNode extends Node {
163+
public abstract Object execute(Object arg);
164+
165+
@Specialization
166+
static Object mixWithoutDataClass(int a,
167+
@Bind("this") Node node,
168+
@Shared @Cached InlineNode sharedNode,
169+
@Exclusive @Cached InlineNode exclusiveNode) {
170+
sharedNode.execute(node, a);
171+
exclusiveNode.execute(node, a);
172+
return a;
173+
}
174+
175+
@Specialization
176+
static Object dummy(double a,
177+
@Bind("this") Node node,
178+
@Shared @Cached InlineNode sharedNode) {
179+
sharedNode.execute(node, a);
180+
return a;
181+
}
182+
}
183+
184+
// ------------------------------------------------------------------------
185+
// Mixing WITH a data-class produces the warning:
186+
187+
@GenerateCached
188+
@GenerateInline(false)
189+
public abstract static class MixProfilesWithDataClassNode extends Node {
190+
public abstract Object execute(Object arg);
191+
192+
@Specialization
193+
static Object dummy(double a,
194+
@Bind("this") Node node,
195+
@Shared @Cached InlinedBranchProfile sharedBranch) {
196+
sharedBranch.enter(node);
197+
return a;
198+
}
199+
200+
@Specialization
201+
@ExpectWarning(EXPECTED_WARNING)
202+
static Object mixWithDataClass(int a,
203+
@Bind("this") Node node,
204+
@Shared @Cached InlinedBranchProfile sharedBranch,
205+
@Exclusive @Cached InlinedBranchProfile exclusiveBranch,
206+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode1,
207+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode2,
208+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode3,
209+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode4) {
210+
sharedBranch.enter(node);
211+
exclusiveBranch.enter(node);
212+
return a;
213+
}
214+
}
215+
216+
@GenerateCached
217+
@GenerateInline(false)
218+
public abstract static class NonMixedProfilesWithDataClassNode extends Node {
219+
public abstract Object execute(Object arg);
220+
221+
@Specialization
222+
static Object dummy(double a,
223+
@Bind("this") Node node,
224+
@Exclusive @Cached InlinedBranchProfile sharedBranch) {
225+
sharedBranch.enter(node);
226+
return a;
227+
}
228+
229+
@Specialization
230+
static Object mixWithDataClass(int a,
231+
@Bind("this") Node node,
232+
@Exclusive @Cached InlinedBranchProfile sharedBranch,
233+
@Exclusive @Cached InlinedBranchProfile exclusiveBranch,
234+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode1,
235+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode2,
236+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode3,
237+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode4) {
238+
sharedBranch.enter(node);
239+
exclusiveBranch.enter(node);
240+
return a;
241+
}
242+
}
243+
244+
@GenerateCached
245+
@GenerateInline(false)
246+
public abstract static class MixProfileAndNodeWithDataClassNode extends Node {
247+
public abstract Object execute(Object arg);
248+
249+
@Specialization
250+
static Object dummy(double a,
251+
@Bind("this") Node node,
252+
@Shared @Cached InlinedBranchProfile sharedBranch) {
253+
sharedBranch.enter(node);
254+
return a;
255+
}
256+
257+
@Specialization
258+
@ExpectWarning(EXPECTED_WARNING)
259+
static Object mixWithDataClass(int a,
260+
@Bind("this") Node node,
261+
@Shared @Cached InlinedBranchProfile sharedBranch,
262+
@Exclusive @Cached InlineNode exclusiveNode,
263+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode1,
264+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode2,
265+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode3,
266+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode4) {
267+
sharedBranch.enter(node);
268+
exclusiveNode.execute(node, a);
269+
return a;
270+
}
271+
}
272+
273+
@GenerateCached
274+
@GenerateInline(false)
275+
public abstract static class MixNodesWithDataClassNode extends Node {
276+
public abstract Object execute(Object arg);
277+
278+
@Specialization
279+
static Object dummy(double a,
280+
@Bind("this") Node node,
281+
@Shared @Cached InlineNode sharedNode) {
282+
sharedNode.execute(node, a);
283+
return a;
284+
}
285+
286+
@Specialization
287+
@ExpectWarning(EXPECTED_WARNING)
288+
static Object mixWithDataClass(int a,
289+
@Bind("this") Node node,
290+
@Shared @Cached InlineNode sharedNode,
291+
@Exclusive @Cached InlineNode exclusiveNode,
292+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode1,
293+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode2,
294+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode3,
295+
@SuppressWarnings("unused") @Cached IndirectCallNode cachedNode4) {
296+
sharedNode.execute(node, a);
297+
exclusiveNode.execute(node, a);
298+
return a;
299+
}
300+
}
301+
}

0 commit comments

Comments
 (0)