diff a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
--- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
+++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
@@ -49,17 +49,19 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 import java.util.stream.Stream;
 
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.misc.CDS;
 import jdk.internal.misc.VM;
 import jdk.internal.module.ModulePatcher.PatchedModuleReader;
 import jdk.internal.module.Resources;
 import jdk.internal.vm.annotation.Stable;
 import sun.security.util.LazyCodeSourcePermissionCollection;
@@ -104,10 +106,16 @@
     private final BuiltinClassLoader parent;
 
     // the URL class path, or null if there is no class path
     private @Stable URLClassPath ucp;
 
+    private Set<String> negativeLookupCache;
+    private Map<String, Class<? extends Object>> positiveLookupCache;
+
+    public boolean useNegativeCache = false;
+    public boolean usePositiveCache = false;
+
     /**
      * A module defined/loaded by a built-in class loader.
      *
      * A LoadedModule encapsulates a ModuleReference along with its CodeSource
      * URL to avoid needing to create this URL when defining classes.
@@ -196,10 +204,12 @@
         this.parent = parent;
         this.ucp = ucp;
 
         this.nameToModule = new ConcurrentHashMap<>(32);
         this.moduleToReader = new ConcurrentHashMap<>();
+        this.negativeLookupCache = ConcurrentHashMap.newKeySet();
+        this.positiveLookupCache = new ConcurrentHashMap<>();
     }
 
     /**
      * Appends to the given file path to the class path.
      */
@@ -634,13 +644,19 @@
      */
     @Override
     protected Class<?> loadClass(String cn, boolean resolve)
         throws ClassNotFoundException
     {
+        if (useNegativeCache && checkNegativeLookupCache(cn)) {
+            throw new ClassNotFoundException(cn);
+        }
         Class<?> c = loadClassOrNull(cn, resolve);
-        if (c == null)
+        if (c == null) {
+            addToNegativeLookupCache(cn);
             throw new ClassNotFoundException(cn);
+        }
+
         return c;
     }
 
     /**
      * A variation of {@code loadClass} to load a class with the specified
@@ -1083,6 +1099,53 @@
     // Called from VM only, during -Xshare:dump
     private void resetArchivedStates() {
         ucp = null;
         resourceCache = null;
     }
+
+    public boolean checkNegativeLookupCache(String className) {
+        return negativeLookupCache.contains(className);
+    }
+
+    public void addToNegativeLookupCache(String className) {
+        negativeLookupCache.add(className);
+    }
+
+    public String negativeLookupCacheContents() {
+        String[] contents = negativeLookupCache.toArray(new String[]{});
+        StringBuilder builder = new StringBuilder();
+        if (contents.length != 0) {
+            for (String name: contents) {
+                if (builder.length() != 0) {
+                    builder.append(" ");
+                }
+                builder.append(name);
+            }
+            return builder.toString();
+        } else {
+            return null;
+        }
+    }
+
+    public void generateNegativeLookupCache(String contents) {
+        String[] tokens = contents.split(" ");
+        if (tokens.length > 0) {
+            for (String token : tokens) {
+                negativeLookupCache.add(token);
+            }
+            useNegativeCache = true;
+        }
+    }
+
+    public Class<?> checkPositiveLookupCache(String className) {
+        return positiveLookupCache.get(className);
+    }
+
+    public void generatePositiveLookupCache(Class<?>[] cls) {
+        if (cls.length > 0) {
+            for (Class<?> c : cls) {
+                positiveLookupCache.put(c.getName(), c);
+            }
+            usePositiveCache = true;
+        }
+    }
 }
