Skip to content

Commit be0da80

Browse files
committedJan 13, 2025
8327994: Update code gen in CallGeneratorHelper
Backport-of: ac2f8e5af8c88cd13038b113f82bb7c17a38aa40
1 parent 6bc25f3 commit be0da80

File tree

6 files changed

+36038
-36016
lines changed

6 files changed

+36038
-36016
lines changed
 

‎test/jdk/java/foreign/CallGeneratorHelper.java

+95-75
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@
2222
*
2323
*/
2424

25+
import java.io.IOException;
26+
import java.io.PrintStream;
2527
import java.lang.foreign.*;
2628

2729
import java.lang.invoke.MethodHandle;
30+
import java.nio.file.Files;
31+
import java.nio.file.Path;
2832
import java.util.ArrayList;
2933
import java.util.List;
3034
import java.util.Stack;
@@ -188,136 +192,152 @@ static <Z extends Enum<Z>> String sigCode(List<Z> elems) {
188192
return elems.stream().map(p -> p.name().charAt(0) + "").collect(Collectors.joining());
189193
}
190194

191-
static void generateStructDecl(List<StructFieldType> fields) {
195+
private static void generateStructDecl(PrintStream out, List<StructFieldType> fields) {
192196
String structCode = sigCode(fields);
193197
List<String> fieldDecls = new ArrayList<>();
194198
for (int i = 0 ; i < fields.size() ; i++) {
195199
fieldDecls.add(String.format("%s p%d;", fields.get(i).typeStr, i));
196200
}
197201
String res = String.format("struct S_%s { %s };", structCode,
198202
fieldDecls.stream().collect(Collectors.joining(" ")));
199-
System.out.println(res);
203+
out.println(res);
200204
}
201205

202-
/* this can be used to generate the test header/implementation */
203-
public static void main(String[] args) {
204-
boolean header = args.length > 0 && args[0].equals("header");
205-
boolean upcall = args.length > 1 && args[1].equals("upcall");
206-
if (upcall) {
207-
generateUpcalls(header);
208-
} else {
209-
generateDowncalls(header);
210-
}
206+
private static PrintStream printStream(String first) throws IOException {
207+
return new PrintStream(Files.newOutputStream(Path.of(first)));
211208
}
212209

213-
static void generateDowncalls(boolean header) {
214-
if (header) {
215-
System.out.println(
216-
"#include \"export.h\"\n"
217-
);
210+
// This can be used to generate the test implementation.
211+
// From the test/jdk/java/foreign directory, run this class using:
212+
// java -cp <jtreg_home>\lib\testng-7.3.0.jar --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED ./CallGeneratorHelper.java
213+
// Copyright header has to be added manually, and on Windows line endings have to be changed from \r\n to just \n
214+
public static void main(String[] args) throws IOException {
215+
try (PrintStream shared = printStream("shared.h");
216+
PrintStream libTestDowncall = printStream("libTestDowncall.c");
217+
PrintStream libTestDowncallStack = printStream("libTestDowncallStack.c");
218+
PrintStream libTestUpcall = printStream("libTestUpcall.c");
219+
PrintStream libTestUpcallStack = printStream("libTestUpcallStack.c")) {
220+
generateShared(shared);
221+
generateDowncalls(libTestDowncall, false);
222+
generateDowncalls(libTestDowncallStack, true);
223+
generateUpcalls(libTestUpcall, false);
224+
generateUpcalls(libTestUpcallStack, true);
225+
}
226+
}
218227

219-
for (int j = 1; j <= MAX_FIELDS; j++) {
220-
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
221-
generateStructDecl(fields);
222-
}
228+
private static void generateShared(PrintStream out) {
229+
out.println("""
230+
#include "export.h"
231+
232+
#ifdef __clang__
233+
#pragma clang optimize off
234+
#elif defined __GNUC__
235+
#pragma GCC optimize ("O0")
236+
#elif defined _MSC_BUILD
237+
#pragma optimize( "", off )
238+
#endif
239+
240+
#ifdef _AIX
241+
#pragma align (natural)
242+
#endif
243+
""");
244+
245+
for (int j = 1; j <= MAX_FIELDS; j++) {
246+
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
247+
generateStructDecl(out, fields);
223248
}
224-
} else {
225-
System.out.println(
226-
"#include \"libh\"\n" +
227-
"#ifdef __clang__\n" +
228-
"#pragma clang optimize off\n" +
229-
"#elif defined __GNUC__\n" +
230-
"#pragma GCC optimize (\"O0\")\n" +
231-
"#elif defined _MSC_BUILD\n" +
232-
"#pragma optimize( \"\", off )\n" +
233-
"#endif\n"
234-
);
235249
}
236250

251+
out.print("""
252+
253+
#ifdef _AIX
254+
#pragma align (reset)
255+
#endif
256+
""");
257+
}
258+
259+
private static void generateDowncalls(PrintStream out, boolean stack) {
260+
out.println("#include \"shared.h\"\n");
261+
237262
for (Object[] downcall : functions()) {
238-
String fName = (String)downcall[0];
239-
Ret r = (Ret)downcall[1];
263+
String fName = (String)downcall[1];
264+
Ret r = (Ret)downcall[2];
240265
@SuppressWarnings("unchecked")
241-
List<ParamType> ptypes = (List<ParamType>)downcall[2];
266+
List<ParamType> ptypes = (List<ParamType>)downcall[3];
242267
@SuppressWarnings("unchecked")
243-
List<StructFieldType> fields = (List<StructFieldType>)downcall[3];
244-
generateDowncallFunction(fName, r, ptypes, fields, header);
268+
List<StructFieldType> fields = (List<StructFieldType>)downcall[4];
269+
generateDowncallFunction(out, fName, r, ptypes, fields, stack);
245270
}
246271
}
247272

248-
static void generateDowncallFunction(String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean declOnly) {
273+
private static final List<String> stackParamTypes = Stream.concat(Stream.generate(() -> "long long").limit(8),
274+
Stream.generate(() -> "double").limit(8)).toList();
275+
private static final List<String> stackParamNames = IntStream.range(0, 16).mapToObj(i -> "pf" + i).toList();
276+
private static final List<String> stackParamDecls = IntStream.range(0, 16)
277+
.mapToObj(i -> stackParamTypes.get(i) + " " + stackParamNames.get(i)).toList();
278+
279+
private static void generateDowncallFunction(PrintStream out, String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean stack) {
249280
String retType = ret == Ret.VOID ? "void" : params.get(0).type(fields);
250281
List<String> paramDecls = new ArrayList<>();
282+
if (stack) {
283+
paramDecls.addAll(stackParamDecls);
284+
}
251285
for (int i = 0 ; i < params.size() ; i++) {
252286
paramDecls.add(String.format("%s p%d", params.get(i).type(fields), i));
253287
}
254288
String sig = paramDecls.isEmpty() ?
255289
"void" :
256290
paramDecls.stream().collect(Collectors.joining(", "));
257291
String body = ret == Ret.VOID ? "{ }" : "{ return p0; }";
258-
String res = String.format("EXPORT %s f%s(%s) %s", retType, fName,
259-
sig, declOnly ? ";" : body);
260-
System.out.println(res);
292+
String res = String.format("EXPORT %s %s%s(%s) %s", retType, stack ? "s" : "", fName,
293+
sig, body);
294+
out.println(res);
261295
}
262296

263-
static void generateUpcalls(boolean header) {
264-
if (header) {
265-
System.out.println(
266-
"#include \"export.h\"\n"
267-
);
268-
269-
for (int j = 1; j <= MAX_FIELDS; j++) {
270-
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
271-
generateStructDecl(fields);
272-
}
273-
}
274-
} else {
275-
System.out.println(
276-
"#include \"libh\"\n" +
277-
"#ifdef __clang__\n" +
278-
"#pragma clang optimize off\n" +
279-
"#elif defined __GNUC__\n" +
280-
"#pragma GCC optimize (\"O0\")\n" +
281-
"#elif defined _MSC_BUILD\n" +
282-
"#pragma optimize( \"\", off )\n" +
283-
"#endif\n"
284-
);
285-
}
297+
private static void generateUpcalls(PrintStream out, boolean stack) {
298+
out.println("#include \"shared.h\"\n");
286299

287300
for (Object[] downcall : functions()) {
288-
String fName = (String)downcall[0];
289-
Ret r = (Ret)downcall[1];
301+
String fName = (String)downcall[1];
302+
Ret r = (Ret)downcall[2];
290303
@SuppressWarnings("unchecked")
291-
List<ParamType> ptypes = (List<ParamType>)downcall[2];
304+
List<ParamType> ptypes = (List<ParamType>)downcall[3];
292305
@SuppressWarnings("unchecked")
293-
List<StructFieldType> fields = (List<StructFieldType>)downcall[3];
294-
generateUpcallFunction(fName, r, ptypes, fields, header);
306+
List<StructFieldType> fields = (List<StructFieldType>)downcall[4];
307+
generateUpcallFunction(out, fName, r, ptypes, fields, stack);
295308
}
296309
}
297310

298-
static void generateUpcallFunction(String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean declOnly) {
311+
private static void generateUpcallFunction(PrintStream out, String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean stack) {
299312
String retType = ret == Ret.VOID ? "void" : params.get(0).type(fields);
300313
List<String> paramDecls = new ArrayList<>();
314+
if (stack) {
315+
paramDecls.addAll(stackParamDecls);
316+
}
301317
for (int i = 0 ; i < params.size() ; i++) {
302318
paramDecls.add(String.format("%s p%d", params.get(i).type(fields), i));
303319
}
304-
String paramNames = IntStream.range(0, params.size())
305-
.mapToObj(i -> "p" + i)
306-
.collect(Collectors.joining(","));
320+
Stream<String> prefixParamNames = stack ? stackParamNames.stream() : Stream.of();
321+
String paramNames = Stream.concat(prefixParamNames, IntStream.range(0, params.size())
322+
.mapToObj(i -> "p" + i))
323+
.collect(Collectors.joining(", "));
307324
String sig = paramDecls.isEmpty() ?
308325
"" :
309326
paramDecls.stream().collect(Collectors.joining(", ")) + ", ";
310327
String body = String.format(ret == Ret.VOID ? "{ cb(%s); }" : "{ return cb(%s); }", paramNames);
311328
List<String> paramTypes = params.stream().map(p -> p.type(fields)).collect(Collectors.toList());
329+
if (stack) {
330+
paramTypes.addAll(0, stackParamTypes);
331+
}
312332
String cbSig = paramTypes.isEmpty() ?
313333
"void" :
314334
paramTypes.stream().collect(Collectors.joining(", "));
315335
String cbParam = String.format("%s (*cb)(%s)",
316336
retType, cbSig);
317337

318-
String res = String.format("EXPORT %s %s(%s %s) %s", retType, fName,
319-
sig, cbParam, declOnly ? ";" : body);
320-
System.out.println(res);
338+
String res = String.format("EXPORT %s %s%s(%s %s) %s", retType, stack ? "s" : "", fName,
339+
sig, cbParam, body);
340+
out.println(res);
321341
}
322342

323343
//helper methods

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Jan 13, 2025

@openjdk-notifier[bot]
Please sign in to comment.