1 /* 2 * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "cds/cdsConfig.hpp" 27 #include "cds/serializeClosure.hpp" 28 #include "classfile/classLoaderData.inline.hpp" 29 #include "classfile/classLoaderDataShared.hpp" 30 #include "classfile/moduleEntry.hpp" 31 #include "classfile/packageEntry.hpp" 32 #include "classfile/systemDictionary.hpp" 33 #include "logging/log.hpp" 34 #include "runtime/handles.inline.hpp" 35 36 #if INCLUDE_CDS_JAVA_HEAP 37 38 bool ClassLoaderDataShared::_full_module_graph_loaded = false; 39 40 class ArchivedClassLoaderData { 41 Array<PackageEntry*>* _packages; 42 Array<ModuleEntry*>* _modules; 43 44 void assert_valid(ClassLoaderData* loader_data) { 45 // loader_data may be null if the boot layer has loaded no modules for the platform or 46 // system loaders (e.g., if you create a custom JDK image with only java.base). 47 if (loader_data != nullptr) { 48 assert(!loader_data->has_class_mirror_holder(), 49 "loaders for non-strong hidden classes not supported"); 50 } 51 } 52 public: 53 ArchivedClassLoaderData() : _packages(nullptr), _modules(nullptr) {} 54 55 void iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure); 56 void allocate(ClassLoaderData* loader_data); 57 void init_archived_entries(ClassLoaderData* loader_data); 58 59 void serialize(SerializeClosure* f) { 60 f->do_ptr(&_packages); 61 f->do_ptr(&_modules); 62 } 63 64 void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops); 65 void clear_archived_oops(); 66 }; 67 68 static ArchivedClassLoaderData _archived_boot_loader_data; 69 static ArchivedClassLoaderData _archived_platform_loader_data; 70 static ArchivedClassLoaderData _archived_system_loader_data; 71 static ModuleEntry* _archived_javabase_moduleEntry = nullptr; 72 73 void ArchivedClassLoaderData::iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure) { 74 assert(CDSConfig::is_dumping_full_module_graph(), "must be"); 75 assert_valid(loader_data); 76 if (loader_data != nullptr) { 77 loader_data->packages()->iterate_symbols(closure); 78 loader_data->modules() ->iterate_symbols(closure); 79 } 80 } 81 82 void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) { 83 assert(CDSConfig::is_dumping_full_module_graph(), "must be"); 84 assert_valid(loader_data); 85 if (loader_data != nullptr) { 86 // We can't create hashtables at dump time because the hashcode depends on the 87 // address of the Symbols, which may be relocated at runtime due to ASLR. 88 // So we store the packages/modules in Arrays. At runtime, we create 89 // the hashtables using these arrays. 90 _packages = loader_data->packages()->allocate_archived_entries(); 91 _modules = loader_data->modules() ->allocate_archived_entries(); 92 } 93 } 94 95 void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data) { 96 assert(CDSConfig::is_dumping_full_module_graph(), "must be"); 97 assert_valid(loader_data); 98 if (loader_data != nullptr) { 99 loader_data->packages()->init_archived_entries(_packages); 100 loader_data->modules() ->init_archived_entries(_modules); 101 } 102 } 103 104 void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops) { 105 assert(CDSConfig::is_using_archive(), "must be"); 106 assert_valid(loader_data); 107 if (_modules != nullptr) { // Could be null if we have archived no modules for platform/system loaders 108 ModuleEntryTable* modules = loader_data->modules(); 109 PackageEntryTable* packages = loader_data->packages(); 110 111 MutexLocker m1(Module_lock); 112 if (do_entries) { 113 modules->load_archived_entries(loader_data, _modules); 114 packages->load_archived_entries(_packages); 115 } 116 if (do_oops) { 117 modules->restore_archived_oops(loader_data, _modules); 118 } 119 } 120 } 121 122 void ArchivedClassLoaderData::clear_archived_oops() { 123 assert(CDSConfig::is_using_archive(), "must be"); 124 if (_modules != nullptr) { 125 for (int i = 0; i < _modules->length(); i++) { 126 _modules->at(i)->clear_archived_oops(); 127 } 128 } 129 } 130 131 // ------------------------------ 132 133 static ClassLoaderData* null_class_loader_data() { 134 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); 135 assert(loader_data != nullptr, "must be"); 136 return loader_data; 137 } 138 139 static ClassLoaderData* java_platform_loader_data_or_null() { 140 return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader()); 141 } 142 143 static ClassLoaderData* java_system_loader_data_or_null() { 144 return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader()); 145 } 146 147 void ClassLoaderDataShared::iterate_symbols(MetaspaceClosure* closure) { 148 assert(CDSConfig::is_dumping_full_module_graph(), "must be"); 149 _archived_boot_loader_data.iterate_symbols (null_class_loader_data(), closure); 150 _archived_platform_loader_data.iterate_symbols(java_platform_loader_data_or_null(), closure); 151 _archived_system_loader_data.iterate_symbols (java_system_loader_data_or_null(), closure); 152 } 153 154 void ClassLoaderDataShared::allocate_archived_tables() { 155 assert(CDSConfig::is_dumping_full_module_graph(), "must be"); 156 _archived_boot_loader_data.allocate (null_class_loader_data()); 157 _archived_platform_loader_data.allocate(java_platform_loader_data_or_null()); 158 _archived_system_loader_data.allocate (java_system_loader_data_or_null()); 159 } 160 161 void ClassLoaderDataShared::init_archived_tables() { 162 assert(CDSConfig::is_dumping_full_module_graph(), "must be"); 163 _archived_boot_loader_data.init_archived_entries (null_class_loader_data()); 164 _archived_platform_loader_data.init_archived_entries(java_platform_loader_data_or_null()); 165 _archived_system_loader_data.init_archived_entries (java_system_loader_data_or_null()); 166 _archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry()); 167 } 168 169 void ClassLoaderDataShared::serialize(SerializeClosure* f) { 170 _archived_boot_loader_data.serialize(f); 171 _archived_platform_loader_data.serialize(f); 172 _archived_system_loader_data.serialize(f); 173 f->do_ptr(&_archived_javabase_moduleEntry); 174 175 if (f->reading() && CDSConfig::is_using_full_module_graph()) { 176 // Must be done before ClassLoader::create_javabase() 177 _archived_boot_loader_data.restore(null_class_loader_data(), true, false); 178 ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry); 179 log_info(cds)("use_full_module_graph = true; java.base = " INTPTR_FORMAT, 180 p2i(_archived_javabase_moduleEntry)); 181 } 182 } 183 184 void ClassLoaderDataShared::clear_archived_oops() { 185 assert(!CDSConfig::is_using_full_module_graph(), "must be"); 186 _archived_boot_loader_data.clear_archived_oops(); 187 _archived_platform_loader_data.clear_archived_oops(); 188 _archived_system_loader_data.clear_archived_oops(); 189 } 190 191 oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() { 192 assert(CDSConfig::is_using_full_module_graph(), "must be"); 193 _archived_boot_loader_data.restore(null_class_loader_data(), false, true); 194 return _archived_javabase_moduleEntry->module(); 195 } 196 197 void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoaderData* loader_data) { 198 assert(CDSConfig::is_using_full_module_graph(), "must be"); 199 _archived_platform_loader_data.restore(loader_data, true, true); 200 } 201 202 void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) { 203 assert(CDSConfig::is_using_full_module_graph(), "must be"); 204 _archived_system_loader_data.restore(loader_data, true, true); 205 _full_module_graph_loaded = true; 206 } 207 208 #endif // INCLUDE_CDS_JAVA_HEAP