1 /*
2 * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
44 import java.util.Enumeration;
45 import java.util.HashMap;
46 import java.util.Map;
47 import java.util.NoSuchElementException;
48 import java.util.Objects;
49 import java.util.Set;
50 import java.util.Spliterator;
51 import java.util.Spliterators;
52 import java.util.WeakHashMap;
53 import java.util.concurrent.ConcurrentHashMap;
54 import java.util.function.Supplier;
55 import java.util.stream.Stream;
56 import java.util.stream.StreamSupport;
57
58 import jdk.internal.loader.BootLoader;
59 import jdk.internal.loader.BuiltinClassLoader;
60 import jdk.internal.loader.ClassLoaders;
61 import jdk.internal.loader.NativeLibrary;
62 import jdk.internal.loader.NativeLibraries;
63 import jdk.internal.perf.PerfCounter;
64 import jdk.internal.misc.Unsafe;
65 import jdk.internal.misc.VM;
66 import jdk.internal.reflect.CallerSensitive;
67 import jdk.internal.reflect.CallerSensitiveAdapter;
68 import jdk.internal.reflect.Reflection;
69 import jdk.internal.util.StaticProperty;
70 import sun.reflect.misc.ReflectUtil;
71 import sun.security.util.SecurityConstants;
72
73 /**
74 * A class loader is an object that is responsible for loading classes. The
75 * class {@code ClassLoader} is an abstract class. Given the <a
76 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
77 * locate or generate data that constitutes a definition for the class. A
78 * typical strategy is to transform the name into a file name and then read a
79 * "class file" of that name from a file system.
80 *
81 * <p> Every {@link java.lang.Class Class} object contains a {@link
82 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
83 * it.
2693 }
2694 return map;
2695 }
2696
2697 // the storage for ClassLoaderValue(s) associated with this ClassLoader
2698 private volatile ConcurrentHashMap<?, ?> classLoaderValueMap;
2699
2700 /**
2701 * Attempts to atomically set a volatile field in this object. Returns
2702 * {@code true} if not beaten by another thread. Avoids the use of
2703 * AtomicReferenceFieldUpdater in this class.
2704 */
2705 private boolean trySetObjectField(String name, Object obj) {
2706 Unsafe unsafe = Unsafe.getUnsafe();
2707 Class<?> k = ClassLoader.class;
2708 long offset;
2709 offset = unsafe.objectFieldOffset(k, name);
2710 return unsafe.compareAndSetReference(this, offset, null, obj);
2711 }
2712
2713 /**
2714 * Called by the VM, during -Xshare:dump
2715 */
2716 private void resetArchivedStates() {
2717 if (parallelLockMap != null) {
2718 parallelLockMap.clear();
2719 }
2720 packages.clear();
2721 package2certs.clear();
2722 classes.clear();
2723 classLoaderValueMap = null;
2724 }
2725 }
2726
2727 /*
2728 * A utility class that will enumerate over an array of enumerations.
2729 */
2730 final class CompoundEnumeration<E> implements Enumeration<E> {
2731 private final Enumeration<E>[] enums;
2732 private int index;
2733
2734 public CompoundEnumeration(Enumeration<E>[] enums) {
2735 this.enums = enums;
2736 }
2737
2738 private boolean next() {
2739 while (index < enums.length) {
2740 if (enums[index] != null && enums[index].hasMoreElements()) {
2741 return true;
|
1 /*
2 * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
44 import java.util.Enumeration;
45 import java.util.HashMap;
46 import java.util.Map;
47 import java.util.NoSuchElementException;
48 import java.util.Objects;
49 import java.util.Set;
50 import java.util.Spliterator;
51 import java.util.Spliterators;
52 import java.util.WeakHashMap;
53 import java.util.concurrent.ConcurrentHashMap;
54 import java.util.function.Supplier;
55 import java.util.stream.Stream;
56 import java.util.stream.StreamSupport;
57
58 import jdk.internal.loader.BootLoader;
59 import jdk.internal.loader.BuiltinClassLoader;
60 import jdk.internal.loader.ClassLoaders;
61 import jdk.internal.loader.NativeLibrary;
62 import jdk.internal.loader.NativeLibraries;
63 import jdk.internal.perf.PerfCounter;
64 import jdk.internal.misc.CDS;
65 import jdk.internal.misc.Unsafe;
66 import jdk.internal.misc.VM;
67 import jdk.internal.reflect.CallerSensitive;
68 import jdk.internal.reflect.CallerSensitiveAdapter;
69 import jdk.internal.reflect.Reflection;
70 import jdk.internal.util.StaticProperty;
71 import sun.reflect.misc.ReflectUtil;
72 import sun.security.util.SecurityConstants;
73
74 /**
75 * A class loader is an object that is responsible for loading classes. The
76 * class {@code ClassLoader} is an abstract class. Given the <a
77 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
78 * locate or generate data that constitutes a definition for the class. A
79 * typical strategy is to transform the name into a file name and then read a
80 * "class file" of that name from a file system.
81 *
82 * <p> Every {@link java.lang.Class Class} object contains a {@link
83 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
84 * it.
2694 }
2695 return map;
2696 }
2697
2698 // the storage for ClassLoaderValue(s) associated with this ClassLoader
2699 private volatile ConcurrentHashMap<?, ?> classLoaderValueMap;
2700
2701 /**
2702 * Attempts to atomically set a volatile field in this object. Returns
2703 * {@code true} if not beaten by another thread. Avoids the use of
2704 * AtomicReferenceFieldUpdater in this class.
2705 */
2706 private boolean trySetObjectField(String name, Object obj) {
2707 Unsafe unsafe = Unsafe.getUnsafe();
2708 Class<?> k = ClassLoader.class;
2709 long offset;
2710 offset = unsafe.objectFieldOffset(k, name);
2711 return unsafe.compareAndSetReference(this, offset, null, obj);
2712 }
2713
2714 static final boolean DEBUG = System.getProperty("leyden.debug.archived.packages") != null;
2715
2716 /**
2717 * Called by the VM, during -Xshare:dump
2718 */
2719 private void resetArchivedStates() {
2720 if (parallelLockMap != null) {
2721 parallelLockMap.clear();
2722 }
2723
2724 if (DEBUG) {
2725 System.out.println(this + ": packages = " + packages.size());
2726 for (Map.Entry<String, NamedPackage> entry : packages.entrySet()) {
2727 String key = entry.getKey();
2728 NamedPackage value = entry.getValue();
2729 System.out.print("Package ");
2730 System.out.print(key);
2731 System.out.print(" = ");
2732 System.out.println(value instanceof Package ? "Package" : "NamedPackage");
2733 }
2734 }
2735 if (DEBUG) {
2736 System.out.println("package2certs = " + package2certs.size());
2737 for (Map.Entry<String, Certificate[]> entry : package2certs.entrySet()) {
2738 String key = entry.getKey();
2739 Certificate[] value = entry.getValue();
2740 System.out.print("Package ");
2741 System.out.print(key);
2742 System.out.print(" = ");
2743 System.out.println(value.length);
2744 }
2745 }
2746 if (!CDS.isDumpingPackages()) {
2747 if (DEBUG) {
2748 System.out.println("Reset packages/package2certs");
2749 }
2750 packages.clear();
2751 package2certs.clear();
2752 } else {
2753 if (DEBUG) {
2754 System.out.println("Retained packages/package2certs");
2755 }
2756 }
2757 classes.clear();
2758 classLoaderValueMap = null;
2759 }
2760 }
2761
2762 /*
2763 * A utility class that will enumerate over an array of enumerations.
2764 */
2765 final class CompoundEnumeration<E> implements Enumeration<E> {
2766 private final Enumeration<E>[] enums;
2767 private int index;
2768
2769 public CompoundEnumeration(Enumeration<E>[] enums) {
2770 this.enums = enums;
2771 }
2772
2773 private boolean next() {
2774 while (index < enums.length) {
2775 if (enums[index] != null && enums[index].hasMoreElements()) {
2776 return true;
|