Skip to content
Merged
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 @@ -30,17 +30,35 @@

import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.util.GraalAccess;
import com.oracle.svm.util.JVMCIReflectionUtil;
import com.oracle.svm.util.OriginalMethodProvider;

import jdk.vm.ci.meta.ResolvedJavaType;
import sun.util.calendar.JulianCalendar;

@AutomaticallyRegisteredFeature
public class CalendarFeature implements InternalFeature {

@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
initializeCalendarSystem(((InternalFeatureAccess) access));
// GregorianCalendar might use JulianCalendar via reflection
access.registerReachabilityHandler(_ -> {
RuntimeReflection.register(JulianCalendar.class);
RuntimeReflection.registerForReflectiveInstantiation(JulianCalendar.class);
}, GregorianCalendar.class);
}

/**
* Make sure {@code CalendarSystem} is initialized before analysis. Otherwise, the reachability
* of its {@code initName} method is non-deterministic, because there is a race condition
* between heap snapshotting and the first call to the {@code forName} method, which triggers
* the initialization.
*/
private static void initializeCalendarSystem(InternalFeatureAccess access) {
ResolvedJavaType calendarSystem = access.findTypeByName("sun.util.calendar.CalendarSystem");
var forName = JVMCIReflectionUtil.getUniqueDeclaredMethod(access.getMetaAccess(), calendarSystem, "forName", String.class);
GraalAccess.getVMAccess().invoke(OriginalMethodProvider.getOriginalMethod(forName), null, GraalAccess.getOriginalSnippetReflection().forObject("julian"));
}
}