8327994: Update code gen in CallGeneratorHelper

Reviewed-by: mcimadamore
This commit is contained in:
Jorn Vernee 2024-03-21 12:34:38 +00:00
parent c434b79cff
commit ac2f8e5af8
6 changed files with 36037 additions and 36015 deletions

View File

@ -22,9 +22,13 @@
*
*/
import java.io.IOException;
import java.io.PrintStream;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
@ -188,7 +192,7 @@ public class CallGeneratorHelper extends NativeTestHelper {
return elems.stream().map(p -> p.name().charAt(0) + "").collect(Collectors.joining());
}
static void generateStructDecl(List<StructFieldType> fields) {
private static void generateStructDecl(PrintStream out, List<StructFieldType> fields) {
String structCode = sigCode(fields);
List<String> fieldDecls = new ArrayList<>();
for (int i = 0 ; i < fields.size() ; i++) {
@ -196,58 +200,88 @@ public class CallGeneratorHelper extends NativeTestHelper {
}
String res = String.format("struct S_%s { %s };", structCode,
fieldDecls.stream().collect(Collectors.joining(" ")));
System.out.println(res);
out.println(res);
}
/* this can be used to generate the test header/implementation */
public static void main(String[] args) {
boolean header = args.length > 0 && args[0].equals("header");
boolean upcall = args.length > 1 && args[1].equals("upcall");
if (upcall) {
generateUpcalls(header);
} else {
generateDowncalls(header);
private static PrintStream printStream(String first) throws IOException {
return new PrintStream(Files.newOutputStream(Path.of(first)));
}
// This can be used to generate the test implementation.
// From the test/jdk/java/foreign directory, run this class using:
// java -cp <jtreg_home>\lib\testng-7.3.0.jar --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED ./CallGeneratorHelper.java
// Copyright header has to be added manually, and on Windows line endings have to be changed from \r\n to just \n
public static void main(String[] args) throws IOException {
try (PrintStream shared = printStream("shared.h");
PrintStream libTestDowncall = printStream("libTestDowncall.c");
PrintStream libTestDowncallStack = printStream("libTestDowncallStack.c");
PrintStream libTestUpcall = printStream("libTestUpcall.c");
PrintStream libTestUpcallStack = printStream("libTestUpcallStack.c")) {
generateShared(shared);
generateDowncalls(libTestDowncall, false);
generateDowncalls(libTestDowncallStack, true);
generateUpcalls(libTestUpcall, false);
generateUpcalls(libTestUpcallStack, true);
}
}
static void generateDowncalls(boolean header) {
if (header) {
System.out.println(
"#include \"export.h\"\n"
);
private static void generateShared(PrintStream out) {
out.println("""
#include "export.h"
for (int j = 1; j <= MAX_FIELDS; j++) {
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
generateStructDecl(fields);
}
#ifdef __clang__
#pragma clang optimize off
#elif defined __GNUC__
#pragma GCC optimize ("O0")
#elif defined _MSC_BUILD
#pragma optimize( "", off )
#endif
#ifdef _AIX
#pragma align (natural)
#endif
""");
for (int j = 1; j <= MAX_FIELDS; j++) {
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
generateStructDecl(out, fields);
}
} else {
System.out.println(
"#include \"libh\"\n" +
"#ifdef __clang__\n" +
"#pragma clang optimize off\n" +
"#elif defined __GNUC__\n" +
"#pragma GCC optimize (\"O0\")\n" +
"#elif defined _MSC_BUILD\n" +
"#pragma optimize( \"\", off )\n" +
"#endif\n"
);
}
out.print("""
#ifdef _AIX
#pragma align (reset)
#endif
""");
}
private static void generateDowncalls(PrintStream out, boolean stack) {
out.println("#include \"shared.h\"\n");
for (Object[] downcall : functions()) {
String fName = (String)downcall[0];
Ret r = (Ret)downcall[1];
String fName = (String)downcall[1];
Ret r = (Ret)downcall[2];
@SuppressWarnings("unchecked")
List<ParamType> ptypes = (List<ParamType>)downcall[2];
List<ParamType> ptypes = (List<ParamType>)downcall[3];
@SuppressWarnings("unchecked")
List<StructFieldType> fields = (List<StructFieldType>)downcall[3];
generateDowncallFunction(fName, r, ptypes, fields, header);
List<StructFieldType> fields = (List<StructFieldType>)downcall[4];
generateDowncallFunction(out, fName, r, ptypes, fields, stack);
}
}
static void generateDowncallFunction(String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean declOnly) {
private static final List<String> stackParamTypes = Stream.concat(Stream.generate(() -> "long long").limit(8),
Stream.generate(() -> "double").limit(8)).toList();
private static final List<String> stackParamNames = IntStream.range(0, 16).mapToObj(i -> "pf" + i).toList();
private static final List<String> stackParamDecls = IntStream.range(0, 16)
.mapToObj(i -> stackParamTypes.get(i) + " " + stackParamNames.get(i)).toList();
private static void generateDowncallFunction(PrintStream out, String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean stack) {
String retType = ret == Ret.VOID ? "void" : params.get(0).type(fields);
List<String> paramDecls = new ArrayList<>();
if (stack) {
paramDecls.addAll(stackParamDecls);
}
for (int i = 0 ; i < params.size() ; i++) {
paramDecls.add(String.format("%s p%d", params.get(i).type(fields), i));
}
@ -255,69 +289,55 @@ public class CallGeneratorHelper extends NativeTestHelper {
"void" :
paramDecls.stream().collect(Collectors.joining(", "));
String body = ret == Ret.VOID ? "{ }" : "{ return p0; }";
String res = String.format("EXPORT %s f%s(%s) %s", retType, fName,
sig, declOnly ? ";" : body);
System.out.println(res);
String res = String.format("EXPORT %s %s%s(%s) %s", retType, stack ? "s" : "", fName,
sig, body);
out.println(res);
}
static void generateUpcalls(boolean header) {
if (header) {
System.out.println(
"#include \"export.h\"\n"
);
for (int j = 1; j <= MAX_FIELDS; j++) {
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
generateStructDecl(fields);
}
}
} else {
System.out.println(
"#include \"libh\"\n" +
"#ifdef __clang__\n" +
"#pragma clang optimize off\n" +
"#elif defined __GNUC__\n" +
"#pragma GCC optimize (\"O0\")\n" +
"#elif defined _MSC_BUILD\n" +
"#pragma optimize( \"\", off )\n" +
"#endif\n"
);
}
private static void generateUpcalls(PrintStream out, boolean stack) {
out.println("#include \"shared.h\"\n");
for (Object[] downcall : functions()) {
String fName = (String)downcall[0];
Ret r = (Ret)downcall[1];
String fName = (String)downcall[1];
Ret r = (Ret)downcall[2];
@SuppressWarnings("unchecked")
List<ParamType> ptypes = (List<ParamType>)downcall[2];
List<ParamType> ptypes = (List<ParamType>)downcall[3];
@SuppressWarnings("unchecked")
List<StructFieldType> fields = (List<StructFieldType>)downcall[3];
generateUpcallFunction(fName, r, ptypes, fields, header);
List<StructFieldType> fields = (List<StructFieldType>)downcall[4];
generateUpcallFunction(out, fName, r, ptypes, fields, stack);
}
}
static void generateUpcallFunction(String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean declOnly) {
private static void generateUpcallFunction(PrintStream out, String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean stack) {
String retType = ret == Ret.VOID ? "void" : params.get(0).type(fields);
List<String> paramDecls = new ArrayList<>();
if (stack) {
paramDecls.addAll(stackParamDecls);
}
for (int i = 0 ; i < params.size() ; i++) {
paramDecls.add(String.format("%s p%d", params.get(i).type(fields), i));
}
String paramNames = IntStream.range(0, params.size())
.mapToObj(i -> "p" + i)
.collect(Collectors.joining(","));
Stream<String> prefixParamNames = stack ? stackParamNames.stream() : Stream.of();
String paramNames = Stream.concat(prefixParamNames, IntStream.range(0, params.size())
.mapToObj(i -> "p" + i))
.collect(Collectors.joining(", "));
String sig = paramDecls.isEmpty() ?
"" :
paramDecls.stream().collect(Collectors.joining(", ")) + ", ";
String body = String.format(ret == Ret.VOID ? "{ cb(%s); }" : "{ return cb(%s); }", paramNames);
List<String> paramTypes = params.stream().map(p -> p.type(fields)).collect(Collectors.toList());
if (stack) {
paramTypes.addAll(0, stackParamTypes);
}
String cbSig = paramTypes.isEmpty() ?
"void" :
paramTypes.stream().collect(Collectors.joining(", "));
String cbParam = String.format("%s (*cb)(%s)",
retType, cbSig);
String res = String.format("EXPORT %s %s(%s %s) %s", retType, fName,
sig, cbParam, declOnly ? ";" : body);
System.out.println(res);
String res = String.format("EXPORT %s %s%s(%s %s) %s", retType, stack ? "s" : "", fName,
sig, cbParam, body);
out.println(res);
}
//helper methods

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, 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
@ -27,6 +27,8 @@
#include "shared.h"
struct S_FFFF { float p0; float p1; float p2; float p3; };
typedef void (*writeback_t)(int,void*);
typedef struct {

View File

@ -119,7 +119,6 @@ struct S_PPI { void* p0; void* p1; int p2; };
struct S_PPF { void* p0; void* p1; float p2; };
struct S_PPD { void* p0; void* p1; double p2; };
struct S_PPP { void* p0; void* p1; void* p2; };
struct S_FFFF { float p0; float p1; float p2; float p3; };
#ifdef _AIX
#pragma align (reset)