Skip to content

Commit 6ea6a47

Browse files
committed
Add bytecode builder benchmark.
1 parent d388a43 commit 6ea6a47

File tree

4 files changed

+246
-6
lines changed

4 files changed

+246
-6
lines changed

truffle/src/org.graalvm.truffle.benchmark/src/org/graalvm/truffle/benchmark/bytecode/BenchmarkLanguage.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@
5050
import com.oracle.truffle.api.bytecode.BytecodeConfig;
5151
import com.oracle.truffle.api.bytecode.BytecodeParser;
5252
import com.oracle.truffle.api.bytecode.BytecodeRootNodes;
53+
import com.oracle.truffle.api.instrumentation.ProvidedTags;
54+
import com.oracle.truffle.api.instrumentation.StandardTags.RootBodyTag;
55+
import com.oracle.truffle.api.instrumentation.StandardTags.RootTag;
5356

5457
@Registration(id = "bm", name = "bm")
58+
@ProvidedTags({RootTag.class, RootBodyTag.class})
5559
public class BenchmarkLanguage extends TruffleLanguage<Object> {
5660

5761
private static final Map<String, Function<BenchmarkLanguage, CallTarget>> NAMES = new HashMap<>();

truffle/src/org.graalvm.truffle.benchmark/src/org/graalvm/truffle/benchmark/bytecode/BytecodeBenchmarkRootNode.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@
5050
import com.oracle.truffle.api.nodes.RootNode;
5151

5252
@GenerateBytecodeTestVariants({
53-
@Variant(suffix = "Base", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class)),
54-
@Variant(suffix = "Checked", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, allowUnsafe = false)),
55-
@Variant(suffix = "WithUncached", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableUncachedInterpreter = true)),
56-
@Variant(suffix = "BoxingEliminated", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, boxingEliminationTypes = {int.class, boolean.class})),
57-
@Variant(suffix = "All", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableUncachedInterpreter = true, boxingEliminationTypes = {
53+
@Variant(suffix = "Base", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableTagInstrumentation = true, enableYield = true)),
54+
@Variant(suffix = "Checked", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableTagInstrumentation = true, enableYield = true, allowUnsafe = false)),
55+
@Variant(suffix = "WithUncached", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableTagInstrumentation = true, enableYield = true, enableUncachedInterpreter = true)),
56+
@Variant(suffix = "BoxingEliminated", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableTagInstrumentation = true, enableYield = true, boxingEliminationTypes = {
57+
int.class,
58+
boolean.class})),
59+
@Variant(suffix = "All", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, enableTagInstrumentation = true, enableYield = true, enableUncachedInterpreter = true, boxingEliminationTypes = {
5860
int.class, boolean.class}))
5961
})
6062
public abstract class BytecodeBenchmarkRootNode extends RootNode implements BytecodeRootNode {
@@ -86,4 +88,5 @@ static boolean doInts(int left, int right) {
8688
return left < right;
8789
}
8890
}
91+
8992
}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
/*
2+
* Copyright (c) 2024, 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 org.graalvm.truffle.benchmark.bytecode;
42+
43+
import java.util.function.Consumer;
44+
45+
import org.graalvm.truffle.benchmark.TruffleBenchmark;
46+
import org.graalvm.truffle.benchmark.bytecode.BytecodeBenchmarkRootNodeAll.Builder;
47+
import org.openjdk.jmh.annotations.Benchmark;
48+
import org.openjdk.jmh.annotations.Measurement;
49+
import org.openjdk.jmh.annotations.OperationsPerInvocation;
50+
import org.openjdk.jmh.annotations.Scope;
51+
import org.openjdk.jmh.annotations.State;
52+
import org.openjdk.jmh.annotations.Warmup;
53+
54+
import com.oracle.truffle.api.bytecode.BytecodeConfig;
55+
import com.oracle.truffle.api.bytecode.BytecodeLocal;
56+
57+
@State(Scope.Benchmark)
58+
@Warmup(iterations = 10, time = 1)
59+
@Measurement(iterations = 5, time = 1)
60+
public class BytecodeBuilderBenchmark extends TruffleBenchmark {
61+
62+
private static void parse(Builder b, Consumer<Builder> inner) {
63+
b.beginRoot();
64+
65+
BytecodeLocal iLoc = b.createLocal();
66+
BytecodeLocal sumLoc = b.createLocal();
67+
BytecodeLocal jLoc = b.createLocal();
68+
BytecodeLocal tempLoc = b.createLocal();
69+
70+
b.beginTryFinally(() -> {
71+
b.beginStoreLocal(sumLoc);
72+
b.beginAdd();
73+
b.emitLoadLocal(sumLoc);
74+
b.emitLoadConstant(1);
75+
b.endAdd();
76+
b.endStoreLocal();
77+
});
78+
79+
b.beginBlock();
80+
81+
// int i = 0;
82+
b.beginStoreLocal(iLoc);
83+
b.emitLoadConstant(0);
84+
b.endStoreLocal();
85+
86+
// int sum = 0;
87+
b.beginStoreLocal(sumLoc);
88+
b.emitLoadConstant(0);
89+
b.endStoreLocal();
90+
91+
// while (i < TOTAL_ITERATIONS) {
92+
b.beginWhile();
93+
b.beginLess();
94+
b.emitLoadLocal(iLoc);
95+
b.emitLoadConstant(5000);
96+
b.endLess();
97+
b.beginBlock();
98+
99+
// int j = 0;
100+
b.beginStoreLocal(jLoc);
101+
b.emitLoadConstant(0);
102+
b.endStoreLocal();
103+
104+
// while (j < i) {
105+
b.beginWhile();
106+
b.beginLess();
107+
b.emitLoadLocal(jLoc);
108+
b.emitLoadLocal(iLoc);
109+
b.endLess();
110+
b.beginBlock();
111+
112+
if (inner != null) {
113+
inner.accept(b);
114+
}
115+
116+
// int temp;
117+
// if (i % 3 < 1) {
118+
b.beginIfThenElse();
119+
120+
b.beginLess();
121+
b.beginMod();
122+
b.emitLoadLocal(iLoc);
123+
b.emitLoadConstant(3);
124+
b.endMod();
125+
b.emitLoadConstant(1);
126+
b.endLess();
127+
128+
// temp = 1;
129+
b.beginStoreLocal(tempLoc);
130+
b.emitLoadConstant(1);
131+
b.endStoreLocal();
132+
133+
// } else {
134+
// temp = i % 3;
135+
b.beginStoreLocal(tempLoc);
136+
b.beginMod();
137+
b.emitLoadLocal(iLoc);
138+
b.emitLoadConstant(3);
139+
b.endMod();
140+
b.endStoreLocal();
141+
142+
// }
143+
b.endIfThenElse();
144+
145+
// j = j + temp;
146+
b.beginStoreLocal(jLoc);
147+
b.beginAdd();
148+
b.emitLoadLocal(jLoc);
149+
b.emitLoadLocal(tempLoc);
150+
b.endAdd();
151+
b.endStoreLocal();
152+
153+
// }
154+
b.endBlock();
155+
b.endWhile();
156+
157+
// sum = sum + j;
158+
b.beginStoreLocal(sumLoc);
159+
b.beginAdd();
160+
b.emitLoadLocal(sumLoc);
161+
b.emitLoadLocal(jLoc);
162+
b.endAdd();
163+
b.endStoreLocal();
164+
165+
// i = i + 1;
166+
b.beginStoreLocal(iLoc);
167+
b.beginAdd();
168+
b.emitLoadLocal(iLoc);
169+
b.emitLoadConstant(1);
170+
b.endAdd();
171+
b.endStoreLocal();
172+
173+
// }
174+
b.endBlock();
175+
b.endWhile();
176+
177+
// exercise some label
178+
var label = b.createLabel();
179+
b.emitBranch(label);
180+
b.beginStoreLocal(sumLoc);
181+
b.beginAdd();
182+
b.emitLoadLocal(sumLoc);
183+
b.emitLoadConstant(1);
184+
b.endAdd();
185+
b.endStoreLocal();
186+
b.emitLabel(label);
187+
188+
// return sum;
189+
b.beginReturn();
190+
b.emitLoadLocal(sumLoc);
191+
b.endReturn();
192+
193+
b.endBlock();
194+
b.endTryFinally();
195+
196+
b.endRoot();
197+
}
198+
199+
@Benchmark
200+
@OperationsPerInvocation(100)
201+
public Object buildManyRoots() {
202+
return BytecodeBenchmarkRootNodeAll.create(null, BytecodeConfig.DEFAULT, (b) -> {
203+
for (int i = 0; i < 100; i++) {
204+
parse(b, null);
205+
}
206+
});
207+
}
208+
209+
@Benchmark
210+
public BytecodeBenchmarkRootNode buildSingleRoot() {
211+
return BytecodeBenchmarkRootNodeAll.create(null, BytecodeConfig.DEFAULT, (b) -> {
212+
parse(b, null);
213+
}).getNode(0);
214+
}
215+
216+
@Benchmark
217+
@OperationsPerInvocation(100)
218+
public BytecodeBenchmarkRootNode buildRecursive() {
219+
return BytecodeBenchmarkRootNodeAll.create(null, BytecodeConfig.DEFAULT, (b) -> {
220+
decrementAndParse(b, 100);
221+
}).getNode(0);
222+
}
223+
224+
private void decrementAndParse(Builder b, int count) {
225+
if (count == 0) {
226+
return;
227+
}
228+
parse(b, (b2) -> {
229+
decrementAndParse(b, count - 1);
230+
});
231+
}
232+
233+
}

truffle/src/org.graalvm.truffle.benchmark/src/org/graalvm/truffle/benchmark/bytecode/SimpleBytecodeBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ private static void createSimpleLoopManualBytecode(ManualBytecodeInterpreters.Bu
217217
b.emitReturn();
218218
}
219219

220-
private static BytecodeParser<BytecodeBenchmarkRootNodeBuilder> createBytecodeDSLParser(boolean forceUncached) {
220+
public static BytecodeParser<BytecodeBenchmarkRootNodeBuilder> createBytecodeDSLParser(boolean forceUncached) {
221221
return b -> {
222222
b.beginRoot();
223223

0 commit comments

Comments
 (0)