Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ public boolean getAsBoolean() {
private AnalysisMetaAccess metaAccess;
private GraalGraphObjectReplacer graalGraphObjectReplacer;
private final EconomicSet<Class<?>> registeredClasses = EconomicSet.create();
private final EconomicSet<Class<?>> registeredExportLibraryClasses = EconomicSet.create();
private final Set<Class<?>> pendingExportLibraryReceiverClasses = ConcurrentHashMap.newKeySet();
private final Map<Class<?>, PossibleReplaceCandidatesSubtypeHandler> subtypeChecks = new HashMap<>();
private boolean profilingEnabled;
private Field uncachedDispatchField;
Expand Down Expand Up @@ -818,6 +820,13 @@ public void duringAnalysis(DuringAnalysisAccess a) {
initializeTruffleLibrariesAtBuildTime(access, type);
initializeDynamicObjectLayouts(type);
}
/* Resolve reachable export subclasses once they are known to be instantiated. */
for (Class<?> receiverClass : pendingExportLibraryReceiverClasses) {
AnalysisType type = access.getMetaAccess().lookupJavaType(receiverClass);
if (type.isInstantiated() && pendingExportLibraryReceiverClasses.remove(receiverClass)) {
initializeTruffleLibraryReceiverAtBuildTime(receiverClass);
}
}
access.rescanRoot(layoutInfoMapField, scanReason);
access.rescanRoot(layoutMapField, scanReason);
access.rescanRoot(libraryFactoryCacheField, scanReason);
Expand Down Expand Up @@ -983,12 +992,40 @@ private void initializeTruffleLibrariesAtBuildTime(DuringAnalysisAccessImpl acce
access.rescanField(factory, uncachedDispatchField, scanReason);
}
if (AnnotationUtil.isAnnotationPresent(type, ExportLibrary.class) || AnnotationUtil.isAnnotationPresent(type, ExportLibrary.Repeat.class)) {
/* Eagerly resolve receiver type. */
invokeStaticMethod("com.oracle.truffle.api.library.LibraryFactory$ResolvedDispatch", "lookup",
Collections.singleton(Class.class), type.getJavaClass());
Class<?> receiverClass = type.getJavaClass();
if (registeredExportLibraryClasses.add(receiverClass)) {
access.registerSubtypeReachabilityHandler(this::registerConcreteTruffleLibraryReceiver, receiverClass);
if (hasExplicitReceiverExport(type)) {
/*
* Exports with an explicit receiver can be used as dynamic dispatch targets
* without the export class being instantiated.
*/
initializeTruffleLibraryReceiverAtBuildTime(receiverClass);
}
}
}
}

private static boolean hasExplicitReceiverExport(AnalysisType type) {
for (ExportLibrary export : AnnotationUtil.getAnnotationsByType(type, ExportLibrary.class, ExportLibrary.Repeat.class, ExportLibrary.Repeat::value)) {
if (export.receiverType() != Void.class) {
return true;
}
}
return false;
}

private void registerConcreteTruffleLibraryReceiver(@SuppressWarnings("unused") DuringAnalysisAccess access, Class<?> receiverClass) {
if (!Modifier.isAbstract(receiverClass.getModifiers())) {
pendingExportLibraryReceiverClasses.add(receiverClass);
}
}

private static void initializeTruffleLibraryReceiverAtBuildTime(Class<?> receiverClass) {
invokeStaticMethod("com.oracle.truffle.api.library.LibraryFactory$ResolvedDispatch", "lookup",
Collections.singleton(Class.class), receiverClass);
}

private final EconomicSet<Class<?>> dynamicObjectClasses = EconomicSet.create();

private void initializeDynamicObjectLayouts(AnalysisType type) {
Expand Down