1 /* 2 * Copyright (c) 2020, 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 "classfile/classLoaderData.inline.hpp" 27 #include "classfile/classLoaderDataShared.hpp" 28 #include "classfile/moduleEntry.hpp" 29 #include "classfile/packageEntry.hpp" 30 #include "logging/log.hpp" 31 #include "memory/metaspaceShared.hpp" 32 #include "runtime/handles.inline.hpp" 33 34 #if INCLUDE_CDS_JAVA_HEAP 35 36 class ArchivedClassLoaderData { 37 Array<PackageEntry*>* _packages; 38 Array<ModuleEntry*>* _modules; 39 40 void assert_valid(ClassLoaderData* loader_data) { 41 // loader_data may be NULL if the boot layer has loaded no modules for the platform or 42 // system loaders (e.g., if you create a custom JDK image with only java.base). 43 if (loader_data != NULL) { 44 assert(!loader_data->has_class_mirror_holder(), 45 "loaders for non-strong hidden classes or unsafe anonymous classes not supported"); 46 } 47 } 48 public: 49 ArchivedClassLoaderData() : _packages(NULL), _modules(NULL) {} 50 51 void allocate(ClassLoaderData* loader_data); 52 void init_archived_entries(ClassLoaderData* loader_data); 53 void init_archived_oops(ClassLoaderData* loader_data); 54 55 void serialize(SerializeClosure* f) { 56 f->do_ptr((void**)&_packages); 57 f->do_ptr((void**)&_modules); 58 } 59 60 void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops); 61 }; 62 63 static ArchivedClassLoaderData _archived_boot_loader_data; 64 static ArchivedClassLoaderData _archived_platform_loader_data; 65 static ArchivedClassLoaderData _archived_system_loader_data; 66 static ModuleEntry* _archived_javabase_moduleEntry = NULL; 67 68 void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) { 69 assert(DumpSharedSpaces, "must be"); 70 assert_valid(loader_data); 71 if (loader_data != NULL) { 72 // We can't create a hashtable at dump time because the hashcode dependes on the 73 // address of the Symbols, which may be relocated at run time due to ASLR. 74 _packages = loader_data->packages()->allocate_archived_entries(); 75 _modules = loader_data->modules() ->allocate_archived_entries(); 76 } 77 } 78 79 void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data) { 80 assert(DumpSharedSpaces, "must be"); 81 assert_valid(loader_data); 82 if (loader_data != NULL) { 83 loader_data->packages()->init_archived_entries(_packages); 84 loader_data->modules() ->init_archived_entries(_modules); 85 } 86 } 87 88 void ArchivedClassLoaderData::init_archived_oops(ClassLoaderData* loader_data) { 89 assert(DumpSharedSpaces, "must be"); 90 assert_valid(loader_data); 91 if (loader_data != NULL) { 92 loader_data->modules()->init_archived_oops(_modules); 93 } 94 } 95 96 void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops) { 97 assert(UseSharedSpaces, "must be"); 98 assert_valid(loader_data); 99 if (_modules != NULL) { // Could be NULL if we have archived no modules for platform/system loaders 100 ModuleEntryTable* modules = loader_data->modules(); 101 PackageEntryTable* packages = loader_data->packages(); 102 103 MutexLocker m1(Module_lock); 104 if (do_entries) { 105 modules->load_archived_entries(loader_data, _modules); 106 packages->load_archived_entries(_packages); 107 } 108 if (do_oops) { 109 modules->restore_archived_oops(loader_data, _modules); 110 } 111 } 112 } 113 114 // ------------------------------ 115 116 ClassLoaderData* ClassLoaderDataShared::null_class_loader_data() { 117 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); 118 assert(loader_data != NULL, "must be"); 119 return loader_data; 120 } 121 122 ClassLoaderData* ClassLoaderDataShared::java_platform_loader_data_or_null() { 123 return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader()); 124 } 125 126 ClassLoaderData* ClassLoaderDataShared::java_system_loader_data_or_null() { 127 return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader()); 128 } 129 130 void ClassLoaderDataShared::allocate_archived_tables() { 131 assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); 132 _archived_boot_loader_data.allocate (null_class_loader_data()); 133 _archived_platform_loader_data.allocate(java_platform_loader_data_or_null()); 134 _archived_system_loader_data.allocate (java_system_loader_data_or_null()); 135 } 136 137 void ClassLoaderDataShared::init_archived_tables() { 138 assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); 139 _archived_boot_loader_data.init_archived_entries (null_class_loader_data()); 140 _archived_platform_loader_data.init_archived_entries(java_platform_loader_data_or_null()); 141 _archived_system_loader_data.init_archived_entries (java_system_loader_data_or_null()); 142 _archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry()); 143 } 144 145 void ClassLoaderDataShared::init_archived_oops() { 146 assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); 147 _archived_boot_loader_data.init_archived_oops (null_class_loader_data()); 148 _archived_platform_loader_data.init_archived_oops(java_platform_loader_data_or_null()); 149 _archived_system_loader_data.init_archived_oops (java_system_loader_data_or_null()); 150 } 151 152 void ClassLoaderDataShared::serialize(class SerializeClosure* f) { 153 _archived_boot_loader_data.serialize(f); 154 _archived_platform_loader_data.serialize(f); 155 _archived_system_loader_data.serialize(f); 156 f->do_ptr((void**)&_archived_javabase_moduleEntry); 157 158 if (f->reading() && MetaspaceShared::use_full_module_graph()) { 159 // Must be done before ClassLoader::create_javabase() 160 _archived_boot_loader_data.restore(null_class_loader_data(), true, false); 161 ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry); 162 log_info(cds)("use_full_module_graph = true; java.base = " INTPTR_FORMAT, 163 p2i(_archived_javabase_moduleEntry)); 164 } 165 } 166 167 oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() { 168 assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); 169 _archived_boot_loader_data.restore(null_class_loader_data(), false, true); 170 return _archived_javabase_moduleEntry->module(); 171 } 172 173 void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoaderData* loader_data) { 174 assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); 175 _archived_platform_loader_data.restore(loader_data, true, true); 176 } 177 178 void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) { 179 assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); 180 _archived_system_loader_data.restore(loader_data, true, true); 181 } 182 183 #endif // INCLUDE_CDS_JAVA_HEAP