From 8c3b1dc55acae76656836d623fa286f55051b2b8 Mon Sep 17 00:00:00 2001 From: "Aleksei.Cherepanov" Date: Mon, 29 Nov 2021 16:39:58 +0300 Subject: [PATCH] Improve performance of classloaders + small refactoring During the initialization of the classloader, we preload some jar files, that are necessary for the compiler to work correctly. In this process of preloading classes, we unpack each jar file and look at the value of the Class-Path in its META_INF. So we will determine, which files are depends on by original jars. We will load the resulting jars in the next iteration of class preloading. Thus, we get nested classloaders. However, in practice, it turned out that the jar files needed for the second iteration were already loaded in the first iteration, so there is no point in loading them again. Moreover, if we do not find the class in the first loader, then we will not find it in the second either. However, the case, when there are some jars from Class-Path of original jars and they were not loaded by first iteration, does not change. Aldo needed for KT-49786 --- .../preloading/ClassPreloadingUtils.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/preloader/src/org/jetbrains/kotlin/preloading/ClassPreloadingUtils.java b/compiler/preloader/src/org/jetbrains/kotlin/preloading/ClassPreloadingUtils.java index 3d15d170dbb..24a4d0cd6dc 100644 --- a/compiler/preloader/src/org/jetbrains/kotlin/preloading/ClassPreloadingUtils.java +++ b/compiler/preloader/src/org/jetbrains/kotlin/preloading/ClassPreloadingUtils.java @@ -31,10 +31,10 @@ public class ClassPreloadingUtils { /** * Creates a class loader that loads all classes from {@code jarFiles} into memory to make loading faster (avoid skipping through zip archives). * - * @param jarFiles jars to load all classes from - * @param classCountEstimation an estimated number of classes in a the jars - * @param parentClassLoader parent class loader - * @param handler handler to be notified on class definitions done by this class loader, or null + * @param jarFiles jars to load all classes from + * @param classCountEstimation an estimated number of classes in a the jars + * @param parentClassLoader parent class loader + * @param handler handler to be notified on class definitions done by this class loader, or null * @param classesToLoadByParent condition to load some classes via parent class loader * @return a class loader that reads classes from memory * @throws IOException on from reading the jar @@ -49,6 +49,7 @@ public class ClassPreloadingUtils { Map entries = loadAllClassesFromJars(jarFiles, classCountEstimation, handler); Collection classpath = mergeClasspathFromManifests(entries); + classpath.removeAll(jarFiles); if (!classpath.isEmpty()) { parentClassLoader = preloadClasses(classpath, classCountEstimation, parentClassLoader, null, handler); } @@ -57,7 +58,7 @@ public class ClassPreloadingUtils { } private static URLClassLoader createFallbackClassLoader(Collection files) throws IOException { - List urls = new ArrayList(files.size()); + List urls = new ArrayList<>(files.size()); for (File file : files) { urls.add(file.toURI().toURL()); } @@ -76,7 +77,7 @@ public class ClassPreloadingUtils { return extractManifestClasspath((ResourceData) manifest); } else if (manifest instanceof ArrayList) { - List result = new ArrayList(); + List result = new ArrayList<>(); for (ResourceData data : (ArrayList) manifest) { result.addAll(extractManifestClasspath(data)); } @@ -93,7 +94,7 @@ public class ClassPreloadingUtils { String classpathSpaceSeparated = (String) manifest.getMainAttributes().get(Attributes.Name.CLASS_PATH); if (classpathSpaceSeparated == null) return Collections.emptyList(); - Collection classpath = new ArrayList(1); + Collection classpath = new ArrayList<>(1); for (String jar : classpathSpaceSeparated.split(" ")) { if (".".equals(jar)) continue; @@ -117,7 +118,7 @@ public class ClassPreloadingUtils { ClassHandler handler ) throws IOException { // 0.75 is HashMap.DEFAULT_LOAD_FACTOR - Map resources = new HashMap((int) (classNumberEstimate / 0.75)); + Map resources = new HashMap<>((int) (classNumberEstimate / 0.75)); for (File jarFile : jarFiles) { if (handler != null) { @@ -154,7 +155,7 @@ public class ClassPreloadingUtils { resources.put(name, resourceData); } else if (previous instanceof ResourceData) { - List list = new ArrayList(); + List list = new ArrayList<>(); list.add((ResourceData) previous); list.add(resourceData); resources.put(name, list);