Skip to content
Permalink
Browse files
8266814: Improve library loading with SymbolLookup abstraction
Reviewed-by: jvernee, sundar
  • Loading branch information
mcimadamore committed May 11, 2021
1 parent 91e4ad8 commit 30ff6cd5c3b799a353af9aaa3b6839cf48f1d1e2
@@ -48,14 +48,12 @@ public class LibClang {
//this is an hack - needed because clang_toggleCrashRecovery only takes effect _after_ the
//first call to createIndex.
try {
Index_h.init();
if (!IS_WINDOWS) {
CLinker linker = CLinker.getInstance();
MethodHandle PUT_ENV = linker.downcallHandle(CLinker.findNative("putenv").get(),
CLinker linker = CLinker.getInstance();
String putenv = IS_WINDOWS ? "_putenv" : "putenv";
MethodHandle PUT_ENV = linker.downcallHandle(CLinker.systemLookup().lookup(putenv).get(),
MethodType.methodType(int.class, MemoryAddress.class),
FunctionDescriptor.of(CLinker.C_INT, CLinker.C_POINTER));
int res = (int) PUT_ENV.invokeExact(disableCrashRecovery.address());
}
int res = (int) PUT_ENV.invokeExact(disableCrashRecovery.address());
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}

Large diffs are not rendered by default.

@@ -170,47 +170,47 @@ public static class constants$0 {
C_INT
);
static final MethodHandle clang_index_isEntityObjCContainerKind$MH = RuntimeHelper.downcallHandle(
"clang_index_isEntityObjCContainerKind",
LIBRARIES, "clang_index_isEntityObjCContainerKind",
"(I)I",
constants$0.clang_index_isEntityObjCContainerKind$FUNC, false
);
static final FunctionDescriptor clang_index_getObjCContainerDeclInfo$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getObjCContainerDeclInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getObjCContainerDeclInfo",
LIBRARIES, "clang_index_getObjCContainerDeclInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$0.clang_index_getObjCContainerDeclInfo$FUNC, false
);
static final FunctionDescriptor clang_index_getObjCInterfaceDeclInfo$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getObjCInterfaceDeclInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getObjCInterfaceDeclInfo",
LIBRARIES, "clang_index_getObjCInterfaceDeclInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$0.clang_index_getObjCInterfaceDeclInfo$FUNC, false
);
static final FunctionDescriptor clang_index_getObjCCategoryDeclInfo$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getObjCCategoryDeclInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getObjCCategoryDeclInfo",
LIBRARIES, "clang_index_getObjCCategoryDeclInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$0.clang_index_getObjCCategoryDeclInfo$FUNC, false
);
static final FunctionDescriptor clang_index_getObjCProtocolRefListInfo$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getObjCProtocolRefListInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getObjCProtocolRefListInfo",
LIBRARIES, "clang_index_getObjCProtocolRefListInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$0.clang_index_getObjCProtocolRefListInfo$FUNC, false
);
static final FunctionDescriptor clang_index_getObjCPropertyDeclInfo$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getObjCPropertyDeclInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getObjCPropertyDeclInfo",
LIBRARIES, "clang_index_getObjCPropertyDeclInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$0.clang_index_getObjCPropertyDeclInfo$FUNC, false
);
@@ -288,23 +288,23 @@ public static class constants$1 {
C_POINTER
);
static final MethodHandle clang_index_getIBOutletCollectionAttrInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getIBOutletCollectionAttrInfo",
LIBRARIES, "clang_index_getIBOutletCollectionAttrInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$1.clang_index_getIBOutletCollectionAttrInfo$FUNC, false
);
static final FunctionDescriptor clang_index_getCXXClassDeclInfo$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getCXXClassDeclInfo$MH = RuntimeHelper.downcallHandle(
"clang_index_getCXXClassDeclInfo",
LIBRARIES, "clang_index_getCXXClassDeclInfo",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$1.clang_index_getCXXClassDeclInfo$FUNC, false
);
static final FunctionDescriptor clang_index_getClientContainer$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getClientContainer$MH = RuntimeHelper.downcallHandle(
"clang_index_getClientContainer",
LIBRARIES, "clang_index_getClientContainer",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$1.clang_index_getClientContainer$FUNC, false
);
@@ -313,15 +313,15 @@ public static class constants$1 {
C_POINTER
);
static final MethodHandle clang_index_setClientContainer$MH = RuntimeHelper.downcallHandle(
"clang_index_setClientContainer",
LIBRARIES, "clang_index_setClientContainer",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)V",
constants$1.clang_index_setClientContainer$FUNC, false
);
static final FunctionDescriptor clang_index_getClientEntity$FUNC = FunctionDescriptor.of(C_POINTER,
C_POINTER
);
static final MethodHandle clang_index_getClientEntity$MH = RuntimeHelper.downcallHandle(
"clang_index_getClientEntity",
LIBRARIES, "clang_index_getClientEntity",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$1.clang_index_getClientEntity$FUNC, false
);
@@ -330,7 +330,7 @@ public static class constants$1 {
C_POINTER
);
static final MethodHandle clang_index_setClientEntity$MH = RuntimeHelper.downcallHandle(
"clang_index_setClientEntity",
LIBRARIES, "clang_index_setClientEntity",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)V",
constants$1.clang_index_setClientEntity$FUNC, false
);
@@ -426,15 +426,15 @@ public static class constants$2 {
C_POINTER
);
static final MethodHandle clang_IndexAction_create$MH = RuntimeHelper.downcallHandle(
"clang_IndexAction_create",
LIBRARIES, "clang_IndexAction_create",
"(Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
constants$2.clang_IndexAction_create$FUNC, false
);
static final FunctionDescriptor clang_IndexAction_dispose$FUNC = FunctionDescriptor.ofVoid(
C_POINTER
);
static final MethodHandle clang_IndexAction_dispose$MH = RuntimeHelper.downcallHandle(
"clang_IndexAction_dispose",
LIBRARIES, "clang_IndexAction_dispose",
"(Ljdk/incubator/foreign/MemoryAddress;)V",
constants$2.clang_IndexAction_dispose$FUNC, false
);
@@ -453,7 +453,7 @@ public static class constants$2 {
C_INT
);
static final MethodHandle clang_indexSourceFile$MH = RuntimeHelper.downcallHandle(
"clang_indexSourceFile",
LIBRARIES, "clang_indexSourceFile",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;IILjdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;ILjdk/incubator/foreign/MemoryAddress;ILjdk/incubator/foreign/MemoryAddress;I)I",
constants$2.clang_indexSourceFile$FUNC, false
);
@@ -472,7 +472,7 @@ public static class constants$2 {
C_INT
);
static final MethodHandle clang_indexSourceFileFullArgv$MH = RuntimeHelper.downcallHandle(
"clang_indexSourceFileFullArgv",
LIBRARIES, "clang_indexSourceFileFullArgv",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;IILjdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;ILjdk/incubator/foreign/MemoryAddress;ILjdk/incubator/foreign/MemoryAddress;I)I",
constants$2.clang_indexSourceFileFullArgv$FUNC, false
);
@@ -485,7 +485,7 @@ public static class constants$2 {
C_POINTER
);
static final MethodHandle clang_indexTranslationUnit$MH = RuntimeHelper.downcallHandle(
"clang_indexTranslationUnit",
LIBRARIES, "clang_indexTranslationUnit",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;IILjdk/incubator/foreign/MemoryAddress;)I",
constants$2.clang_indexTranslationUnit$FUNC, false
);
@@ -502,7 +502,7 @@ public static class constants$2 {
C_POINTER
);
static final MethodHandle clang_indexLoc_getFileLocation$MH = RuntimeHelper.downcallHandle(
"clang_indexLoc_getFileLocation",
LIBRARIES, "clang_indexLoc_getFileLocation",
"(Ljdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)V",
constants$2.clang_indexLoc_getFileLocation$FUNC, false
);
@@ -549,10 +549,10 @@ private static String libName() {
}

static {
RuntimeHelper.loadLibraries(new String[] { libName() });
System.loadLibrary(libName());
}

public static void init() {}
static final SymbolLookup LIBRARIES = SymbolLookup.loaderLookup();

public static class constants$3 {

@@ -568,7 +568,7 @@ public static class constants$3 {
)
);
static final MethodHandle clang_indexLoc_getCXSourceLocation$MH = RuntimeHelper.downcallHandle(
"clang_indexLoc_getCXSourceLocation",
LIBRARIES, "clang_indexLoc_getCXSourceLocation",
"(Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/MemorySegment;",
constants$3.clang_indexLoc_getCXSourceLocation$FUNC, false
);
@@ -582,7 +582,7 @@ public static class constants$3 {
C_POINTER
);
static final MethodHandle clang_Type_visitFields$MH = RuntimeHelper.downcallHandle(
"clang_Type_visitFields",
LIBRARIES, "clang_Type_visitFields",
"(Ljdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)I",
constants$3.clang_Type_visitFields$FUNC, false
);
@@ -35,6 +35,8 @@
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;
import jdk.incubator.foreign.SegmentAllocator;
import jdk.incubator.foreign.SymbolLookup;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
@@ -62,22 +64,12 @@ static <T> T requireNonNull(T obj, String symbolName) {

private final static SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); };

static final void loadLibraries(String... libNames) {
for (String libName : libNames) {
if (libName.indexOf(File.separatorChar) != -1) {
System.load(libName);
} else {
System.loadLibrary(libName);
}
}
static final MemorySegment lookupGlobalVariable(SymbolLookup LOOKUP, String name, MemoryLayout layout) {
return LOOKUP.lookup(name).map(s -> s.address().asSegment(layout.byteSize(), ResourceScope.newImplicitScope())).orElse(null);
}

static final MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) {
return lookup(name).map(s -> s.address().asSegment(layout.byteSize(), ResourceScope.newImplicitScope())).orElse(null);
}

static final MethodHandle downcallHandle(String name, String desc, FunctionDescriptor fdesc, boolean variadic) {
return lookup(name).map(
static final MethodHandle downcallHandle(SymbolLookup LOOKUP, String name, String desc, FunctionDescriptor fdesc, boolean variadic) {
return LOOKUP.lookup(name).map(
addr -> {
MethodType mt = MethodType.fromMethodDescriptorString(desc, LOADER);
return variadic ?
@@ -118,9 +110,6 @@ static MemorySegment asArray(MemoryAddress addr, MemoryLayout layout, int numEle
}

// Internals only below this point
private static final Optional<MemoryAddress> lookup(String sym) {
return CLinker.findNative(sym);
}

private static class VarargsInvoker {
private static final MethodHandle INVOKE_MH;
@@ -195,7 +195,7 @@ private Constant emitMethodHandleField(String javaName, String nativeName, Funct
incrAlign();
indent();
if (!virtual) {
append("\"" + nativeName + "\"");
append(toplevel().headerClassName() + ".LIBRARIES, \"" + nativeName + "\"");
append(",\n");
indent();
}
@@ -391,7 +391,8 @@ private Constant emitSegmentField(String javaName, String nativeName, MemoryLayo
append("MemorySegment ");
append(fieldName);
append(" = ");
append("RuntimeHelper.lookupGlobalVariable(\"");
append("RuntimeHelper.lookupGlobalVariable(");
append(toplevel().headerClassName() + ".LIBRARIES, \"");
append(nativeName);
append("\", ");
append(layoutConstant.accessExpression());
@@ -33,7 +33,6 @@
import jdk.internal.jextract.impl.JavaSourceBuilder.FunctionInfo;

import javax.tools.JavaFileObject;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.constant.ClassDesc;
@@ -74,7 +73,6 @@ public class OutputFactory implements Declaration.Visitor<Void, Declaration> {
private final Set<Declaration.Typedef> unresolvedStructTypedefs = new HashSet<>();
private final Map<Type, String> functionTypeDefNames = new HashMap<>();
private final IncludeHelper includeHelper;
private final String[] libraryNames;

private void addStructDefinition(Declaration decl, String name) {
structClassNames.put(decl, name);
@@ -113,17 +111,15 @@ protected boolean functionSeen(Declaration.Function tree) {
public static JavaFileObject[] generateWrapped(Declaration.Scoped decl, String headerName,
String pkgName, IncludeHelper includeHelper, List<String> libraryNames) {
String clsName = Utils.javaSafeIdentifier(headerName.replace(".h", "_h"), true);
ToplevelBuilder toplevelBuilder = new ToplevelBuilder(pkgName, clsName);
return new OutputFactory(pkgName, toplevelBuilder, includeHelper, libraryNames.toArray(new String[0])).generate(decl);
ToplevelBuilder toplevelBuilder = new ToplevelBuilder(pkgName, clsName, libraryNames.toArray(new String[0]));
return new OutputFactory(pkgName, toplevelBuilder, includeHelper).generate(decl);
}

private OutputFactory(String pkgName, ToplevelBuilder toplevelBuilder, IncludeHelper includeHelper,
String[] libraryNames) {
private OutputFactory(String pkgName, ToplevelBuilder toplevelBuilder, IncludeHelper includeHelper) {
this.pkgName = pkgName;
this.toplevelBuilder = toplevelBuilder;
this.currentBuilder = toplevelBuilder;
this.includeHelper = includeHelper;
this.libraryNames = libraryNames;
}

JavaFileObject[] generate(Declaration.Scoped decl) {
@@ -149,29 +145,7 @@ JavaFileObject[] generate(Declaration.Scoped decl) {
private String getRuntimeHelperSource() throws URISyntaxException, IOException {
URL runtimeHelper = OutputFactory.class.getResource("resources/RuntimeHelper.java.template");
return (pkgName.isEmpty()? "" : "package " + pkgName + ";\n") +
String.join("\n", Files.readAllLines(Paths.get(runtimeHelper.toURI())))
.replace("${LOADLIBRARIES}", generateLoadLibraries());
}

private String generateLoadLibraries() {
StringBuilder buf = new StringBuilder();
for (String lib : libraryNames) {
String quotedName = quoteLibraryName(lib);
if (lib.indexOf(File.separatorChar) != -1) {
buf.append("System.load(\"");
buf.append(quotedName);
buf.append("\");\n");
} else {
buf.append("System.loadLibrary(\"");
buf.append(quotedName);
buf.append("\");\n");
}
}
return buf.toString();
}

private String quoteLibraryName(String lib) {
return lib.replace("\\", "\\\\"); // double up slashes
String.join("\n", Files.readAllLines(Paths.get(runtimeHelper.toURI())));
}

private void generateDecl(Declaration tree) {

0 comments on commit 30ff6cd

Please sign in to comment.