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