1 /* 2 * Copyright (c) 2025, 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 "cds/aotClassLinker.hpp" 26 #include "cds/aotArtifactFinder.hpp" 27 #include "cds/aotClassInitializer.hpp" 28 #include "cds/aotReferenceObjSupport.hpp" 29 #include "cds/dumpTimeClassInfo.inline.hpp" 30 #include "cds/heapShared.hpp" 31 #include "cds/lambdaProxyClassDictionary.hpp" 32 #include "classfile/systemDictionaryShared.hpp" 33 #include "logging/log.hpp" 34 #include "memory/metaspaceClosure.hpp" 35 #include "oops/instanceKlass.hpp" 36 #include "oops/objArrayKlass.hpp" 37 #include "utilities/resourceHash.hpp" 38 39 // All the classes that should be included in the AOT cache (in at least the "allocated" state) 40 static GrowableArrayCHeap<Klass*, mtClassShared>* _all_cached_classes = nullptr; 41 42 // This is a stack that tracks all the AOT-inited classes that are waiting to be passed 43 // to HeapShared::copy_and_rescan_aot_inited_mirror(). 44 static GrowableArrayCHeap<InstanceKlass*, mtClassShared>* _pending_aot_inited_classes = nullptr; 45 46 static const int TABLE_SIZE = 15889; // prime number 47 using ClassesTable = ResourceHashtable<Klass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared>; 48 static ClassesTable* _seen_classes; // all classes that have been seen by AOTArtifactFinder 49 static ClassesTable* _aot_inited_classes; // all classes that need to be AOT-initialized. 50 51 void AOTArtifactFinder::initialize() { 52 _all_cached_classes = new GrowableArrayCHeap<Klass*, mtClassShared>(); 53 _pending_aot_inited_classes = new GrowableArrayCHeap<InstanceKlass*, mtClassShared>(); 54 _seen_classes = new (mtClass)ClassesTable(); 55 _aot_inited_classes = new (mtClass)ClassesTable(); 56 } 57 58 void AOTArtifactFinder::dispose() { 59 delete _all_cached_classes; 60 delete _seen_classes; 61 delete _aot_inited_classes; 62 delete _pending_aot_inited_classes; 63 _all_cached_classes = nullptr; 64 _seen_classes = nullptr; 65 _aot_inited_classes = nullptr; 66 _pending_aot_inited_classes = nullptr; 67 } 68 69 // Find all Klasses and oops that should be included in the AOT cache. See aotArtifactFinder.hpp 70 void AOTArtifactFinder::find_artifacts() { 71 // Some classes might have been marked as excluded as a side effect of running 72 // AOTConstantPoolResolver. Make sure we check all the remaining ones. 73 // 74 // Note, if a class is not excluded, it does NOT mean it will be automatically included 75 // into the AOT cache -- that will be decided by the code below. 76 SystemDictionaryShared::finish_exclusion_checks(); 77 AOTReferenceObjSupport::init_keep_alive_objs_table(); 78 79 start_scanning_for_oops(); 80 81 // Add the primitive array classes 82 for (int i = T_BOOLEAN; i < T_VOID+1; i++) { 83 BasicType bt = (BasicType)i; 84 if (is_java_primitive(bt)) { 85 add_cached_type_array_class(Universe::typeArrayKlass(bt)); 86 } 87 } 88 89 #if INCLUDE_CDS_JAVA_HEAP 90 // Add the mirrors that aren't associated with a Klass 91 // - primitive mirrors (E.g., "int.class" in Java code) 92 // - mirror of fillerArrayKlass 93 if (CDSConfig::is_dumping_heap()) { 94 for (int i = T_BOOLEAN; i < T_VOID+1; i++) { 95 BasicType bt = (BasicType)i; 96 if (!is_reference_type(bt)) { 97 oop orig_mirror = Universe::java_mirror(bt); 98 oop scratch_mirror = HeapShared::scratch_java_mirror(bt); 99 HeapShared::scan_java_mirror(orig_mirror); 100 log_trace(cds, heap, mirror)( 101 "Archived %s mirror object from " PTR_FORMAT, 102 type2name(bt), p2i(scratch_mirror)); 103 Universe::set_archived_basic_type_mirror_index(bt, HeapShared::append_root(scratch_mirror)); 104 } 105 } 106 107 // Universe::fillerArrayKlass() isn't in the class hierarchy, so handle it specially. 108 HeapShared::scan_java_mirror(Universe::fillerArrayKlass()->java_mirror()); 109 } 110 #endif 111 112 // Add all the InstanceKlasses (and their array classes) that are always included. 113 SystemDictionaryShared::dumptime_table()->iterate_all_live_classes([&] (InstanceKlass* ik, DumpTimeClassInfo& info) { 114 // Skip "AOT tooling classes" in this block. They will be included in the AOT cache only if 115 // - One of their subtypes is included 116 // - One of their instances is found by HeapShared. 117 if (!info.is_excluded() && !info.is_aot_tooling_class()) { 118 bool add = false; 119 if (!ik->is_hidden()) { 120 // All non-hidden classes are always included into the AOT cache 121 add = true; 122 } else { 123 if (CDSConfig::is_dumping_lambdas_in_legacy_mode()) { 124 // Legacy support of lambda proxies -- these are always included into the AOT cache 125 if (LambdaProxyClassDictionary::is_registered_lambda_proxy_class(ik)) { 126 add = true; 127 } 128 } else { 129 assert(!LambdaProxyClassDictionary::is_registered_lambda_proxy_class(ik), 130 "registered lambda proxies are only for legacy lambda proxy support"); 131 } 132 } 133 134 if (add) { 135 add_cached_instance_class(ik); 136 if (AOTClassInitializer::can_archive_initialized_mirror(ik)) { 137 add_aot_inited_class(ik); 138 } 139 } 140 } 141 }); 142 143 #if INCLUDE_CDS_JAVA_HEAP 144 // Keep scanning until we discover no more class that need to be AOT-initialized. 145 if (CDSConfig::is_initing_classes_at_dump_time()) { 146 while (_pending_aot_inited_classes->length() > 0) { 147 InstanceKlass* ik = _pending_aot_inited_classes->pop(); 148 HeapShared::copy_and_rescan_aot_inited_mirror(ik); 149 } 150 } 151 #endif 152 153 // Exclude all the (hidden) classes that have not been discovered by the code above. 154 SystemDictionaryShared::dumptime_table()->iterate_all_live_classes([&] (InstanceKlass* k, DumpTimeClassInfo& info) { 155 if (!info.is_excluded() && _seen_classes->get(k) == nullptr) { 156 info.set_excluded(); 157 info.set_has_checked_exclusion(); 158 if (log_is_enabled(Debug, cds)) { 159 ResourceMark rm; 160 log_debug(cds)("Skipping %s: %s class", k->name()->as_C_string(), 161 k->is_hidden() ? "Unreferenced hidden" : "AOT tooling"); 162 } 163 } 164 }); 165 166 end_scanning_for_oops(); 167 } 168 169 void AOTArtifactFinder::start_scanning_for_oops() { 170 #if INCLUDE_CDS_JAVA_HEAP 171 if (CDSConfig::is_dumping_heap()) { 172 HeapShared::start_scanning_for_oops(); 173 } 174 #endif 175 } 176 177 void AOTArtifactFinder::end_scanning_for_oops() { 178 #if INCLUDE_CDS_JAVA_HEAP 179 if (CDSConfig::is_dumping_heap()) { 180 HeapShared::end_scanning_for_oops(); 181 } 182 #endif 183 } 184 185 void AOTArtifactFinder::add_aot_inited_class(InstanceKlass* ik) { 186 if (CDSConfig::is_initing_classes_at_dump_time()) { 187 assert(ik->is_initialized(), "must be"); 188 add_cached_instance_class(ik); 189 190 bool created; 191 _aot_inited_classes->put_if_absent(ik, &created); 192 if (created) { 193 _pending_aot_inited_classes->push(ik); 194 195 InstanceKlass* s = ik->java_super(); 196 if (s != nullptr) { 197 add_aot_inited_class(s); 198 } 199 200 Array<InstanceKlass*>* interfaces = ik->local_interfaces(); 201 int len = interfaces->length(); 202 for (int i = 0; i < len; i++) { 203 InstanceKlass* intf = interfaces->at(i); 204 if (intf->is_initialized()) { 205 add_aot_inited_class(intf); 206 } 207 } 208 } 209 } 210 } 211 212 void AOTArtifactFinder::append_to_all_cached_classes(Klass* k) { 213 precond(!SystemDictionaryShared::should_be_excluded(k)); 214 _all_cached_classes->append(k); 215 } 216 217 void AOTArtifactFinder::add_cached_instance_class(InstanceKlass* ik) { 218 if (CDSConfig::is_dumping_dynamic_archive() && ik->is_shared()) { 219 // This class is already included in the base archive. No need to cache 220 // it again in the dynamic archive. 221 return; 222 } 223 224 bool created; 225 _seen_classes->put_if_absent(ik, &created); 226 if (created) { 227 append_to_all_cached_classes(ik); 228 229 // All super types must be added. 230 InstanceKlass* s = ik->java_super(); 231 if (s != nullptr) { 232 add_cached_instance_class(s); 233 } 234 235 Array<InstanceKlass*>* interfaces = ik->local_interfaces(); 236 int len = interfaces->length(); 237 for (int i = 0; i < len; i++) { 238 InstanceKlass* intf = interfaces->at(i); 239 add_cached_instance_class(intf); 240 } 241 242 if (CDSConfig::is_dumping_final_static_archive() && ik->is_shared_unregistered_class()) { 243 // The following are not appliable to unregistered classes 244 return; 245 } 246 scan_oops_in_instance_class(ik); 247 if (ik->is_hidden() && CDSConfig::is_initing_classes_at_dump_time()) { 248 bool succeed = AOTClassLinker::try_add_candidate(ik); 249 guarantee(succeed, "All cached hidden classes must be aot-linkable"); 250 add_aot_inited_class(ik); 251 } 252 } 253 } 254 255 void AOTArtifactFinder::add_cached_type_array_class(TypeArrayKlass* tak) { 256 bool created; 257 _seen_classes->put_if_absent(tak, &created); 258 if (created) { 259 append_to_all_cached_classes(tak); 260 scan_oops_in_array_class(tak); 261 } 262 } 263 264 void AOTArtifactFinder::add_cached_class(Klass* k) { 265 if (k->is_typeArray_klass()) { 266 add_cached_type_array_class(TypeArrayKlass::cast(k)); 267 } else if (k->is_objArray_klass()) { 268 add_cached_class(ObjArrayKlass::cast(k)->element_klass()); 269 } else { 270 add_cached_instance_class(InstanceKlass::cast(k)); 271 } 272 } 273 274 void AOTArtifactFinder::scan_oops_in_instance_class(InstanceKlass* ik) { 275 #if INCLUDE_CDS_JAVA_HEAP 276 if (CDSConfig::is_dumping_heap()) { 277 HeapShared::scan_java_class(ik); 278 scan_oops_in_array_class(ik->array_klasses()); 279 } 280 #endif 281 } 282 283 void AOTArtifactFinder::scan_oops_in_array_class(ArrayKlass* ak) { 284 #if INCLUDE_CDS_JAVA_HEAP 285 if (CDSConfig::is_dumping_heap()) { 286 while (ak != nullptr) { 287 HeapShared::scan_java_class(ak); 288 ak = ak->array_klass_or_null(); 289 } 290 } 291 #endif 292 } 293 294 void AOTArtifactFinder::all_cached_classes_do(MetaspaceClosure* it) { 295 for (int i = 0; i < _all_cached_classes->length(); i++) { 296 it->push(_all_cached_classes->adr_at(i)); 297 } 298 }