< prev index next >

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java

Print this page
imported patch URLClasspath-ArrayDeque

@@ -44,10 +44,11 @@
 import java.security.CodeSigner;
 import java.security.Permission;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.security.cert.Certificate;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;

@@ -55,11 +56,10 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Properties;
 import java.util.Set;
-import java.util.Stack;
 import java.util.StringTokenizer;
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
 import java.util.jar.JarEntry;
 import java.util.jar.Manifest;

@@ -99,14 +99,14 @@
         p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
         DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
     }
 
     /** The original search path of URLs. */
-    private final List<URL> path;
+    private final ArrayList<URL> path;
 
-    /** The stack of unopened URLs. */
-    private final Stack<URL> unopenedUrls = new Stack<>();
+    /** The deque of unopened URLs. */
+    private final ArrayDeque<URL> unopenedUrls;
 
     /** The resulting search path of Loaders. */
     private final ArrayList<Loader> loaders = new ArrayList<>();
 
     /** Map of each URL opened to its corresponding Loader. */

@@ -139,16 +139,17 @@
      *            be null
      */
     public URLClassPath(URL[] urls,
                         URLStreamHandlerFactory factory,
                         AccessControlContext acc) {
-        List<URL> path = new ArrayList<>(urls.length);
+        ArrayList<URL> path = new ArrayList<>(urls.length);
         for (URL url : urls) {
             path.add(url);
         }
         this.path = path;
-        push(urls);
+        this.unopenedUrls = copyToArrayDeque(path);
+
         if (factory != null) {
             jarHandler = factory.createURLStreamHandler("jar");
         } else {
             jarHandler = null;
         }

@@ -170,11 +171,11 @@
      *        treated as the current working directory
      *
      * @apiNote Used to create the application class path.
      */
     URLClassPath(String cp, boolean skipEmptyElements) {
-        List<URL> path = new ArrayList<>();
+        ArrayList<URL> path = new ArrayList<>();
         if (cp != null) {
             // map each element of class path to a file URL
             int off = 0;
             int next;
             while ((next = cp.indexOf(File.pathSeparator, off)) != -1) {

@@ -190,22 +191,28 @@
             String element = cp.substring(off);
             if (element.length() > 0 || !skipEmptyElements) {
                 URL url = toFileURL(element);
                 if (url != null) path.add(url);
             }
-
-            // push the URLs
-            for (int i = path.size() - 1; i >= 0; --i) {
-                unopenedUrls.push(path.get(i));
-            }
         }
 
+        this.unopenedUrls = copyToArrayDeque(path);
         this.path = path;
         this.jarHandler = null;
         this.acc = null;
     }
 
+    private <T> ArrayDeque<T> copyToArrayDeque(ArrayList<T> list) {
+        // can't simplify to deque.addAll(list) or new ArrayDeque(list);
+        // it's too early in the bootstrap to trigger use of lambdas
+        int size = list.size();
+        ArrayDeque<T> deque = new ArrayDeque<>(size);
+        for (int i = 0; i < size; i++)
+            deque.add(list.get(i));
+        return deque;
+    }
+
     public synchronized List<IOException> closeLoaders() {
         if (closed) {
             return Collections.emptyList();
         }
         List<IOException> result = new LinkedList<>();

@@ -226,20 +233,19 @@
      * <p>
      * If the URL specified is null or is already in the list of
      * URLs, then invoking this method has no effect.
      */
     public synchronized void addURL(URL url) {
-        if (closed)
+        if (closed || url == null)
             return;
         synchronized (unopenedUrls) {
-            if (url == null || path.contains(url))
-                return;
-
-            unopenedUrls.add(0, url);
+            if (! path.contains(url)) {
+                unopenedUrls.addLast(url);
             path.add(url);
         }
     }
+    }
 
     /**
      * Appends the specified file path as a file URL to the search path.
      */
     public void addFile(String s) {

@@ -415,20 +421,17 @@
     private synchronized Loader getLoader(int index) {
         if (closed) {
             return null;
         }
          // Expand URL search path until the request can be satisfied
-         // or the URL stack is empty.
+        // or unopenedUrls is exhausted.
         while (loaders.size() < index + 1) {
-            // Pop the next URL from the URL stack
-            URL url;
+            final URL url;
             synchronized (unopenedUrls) {
-                if (unopenedUrls.empty()) {
+                url = unopenedUrls.pollFirst();
+                if (url == null)
                     return null;
-                } else {
-                    url = unopenedUrls.pop();
-                }
             }
             // Skip this URL if it already has a Loader. (Loader
             // may be null in the case where URL has not been opened
             // but is referenced by a JAR index.)
             String urlNoFragString = URLUtil.urlNoFragString(url);

@@ -503,11 +506,11 @@
         URLStreamHandler h = JNUA.getHandler(u);
         return h instanceof sun.net.www.protocol.jar.Handler;
     }
 
     /**
-     * Pushes the specified URLs onto the list of unopened URLs.
+     * Pushes the specified URLs onto the head of unopened URLs.
      */
     private void push(URL[] urls) {
         synchronized (unopenedUrls) {
             for (int i = urls.length - 1; i >= 0; --i) {
                 unopenedUrls.push(urls[i]);
< prev index next >