1 /*
  2  * Copyright (c) 2024, 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/aotConstantPoolResolver.hpp"
 27 #include "cds/aotLinkedClassTable.hpp"
 28 #include "cds/archiveBuilder.hpp"
 29 #include "cds/archiveUtils.inline.hpp"
 30 #include "cds/cdsConfig.hpp"
 31 #include "cds/heapShared.hpp"
 32 #include "cds/lambdaFormInvokers.inline.hpp"
 33 #include "classfile/classLoader.hpp"
 34 #include "classfile/dictionary.hpp"
 35 #include "classfile/systemDictionary.hpp"
 36 #include "classfile/systemDictionaryShared.hpp"
 37 #include "classfile/vmClasses.hpp"
 38 #include "memory/resourceArea.hpp"
 39 #include "oops/constantPool.inline.hpp"
 40 #include "oops/instanceKlass.hpp"
 41 #include "oops/klass.inline.hpp"
 42 #include "runtime/handles.inline.hpp"
 43 
 44 AOTClassLinker::ClassesTable* AOTClassLinker::_vm_classes = nullptr;
 45 AOTClassLinker::ClassesTable* AOTClassLinker::_candidates = nullptr;
 46 GrowableArrayCHeap<InstanceKlass*, mtClassShared>* AOTClassLinker::_sorted_candidates = nullptr;
 47 
 48 #ifdef ASSERT
 49 bool AOTClassLinker::is_initialized() {
 50   assert(CDSConfig::is_dumping_archive(), "AOTClassLinker is for CDS dumping only");
 51   return _vm_classes != nullptr;
 52 }
 53 #endif
 54 
 55 void AOTClassLinker::initialize() {
 56   assert(!is_initialized(), "sanity");
 57 
 58   _vm_classes = new (mtClass)ClassesTable();
 59   _candidates = new (mtClass)ClassesTable();
 60   _sorted_candidates = new GrowableArrayCHeap<InstanceKlass*, mtClassShared>(1000);
 61 
 62   for (auto id : EnumRange<vmClassID>{}) {
 63     add_vm_class(vmClasses::klass_at(id));
 64   }
 65 
 66   assert(is_initialized(), "sanity");
 67 }
 68 
 69 void AOTClassLinker::dispose() {
 70   assert(is_initialized(), "sanity");
 71 
 72   delete _vm_classes;
 73   delete _candidates;
 74   delete _sorted_candidates;
 75   _vm_classes = nullptr;
 76   _candidates = nullptr;
 77   _sorted_candidates = nullptr;
 78 
 79   assert(!is_initialized(), "sanity");
 80 }
 81 
 82 bool AOTClassLinker::is_vm_class(InstanceKlass* ik) {
 83   assert(is_initialized(), "sanity");
 84   return (_vm_classes->get(ik) != nullptr);
 85 }
 86 
 87 void AOTClassLinker::add_vm_class(InstanceKlass* ik) {
 88   assert(is_initialized(), "sanity");
 89   bool created;
 90   _vm_classes->put_if_absent(ik, &created);
 91   if (created) {
 92     if (CDSConfig::is_dumping_aot_linked_classes()) {
 93       bool v = try_add_candidate(ik);
 94       assert(v, "must succeed for VM class");
 95     }
 96     InstanceKlass* super = ik->super();
 97     if (super != nullptr) {
 98       add_vm_class(super);
 99     }
100     Array<InstanceKlass*>* ifs = ik->local_interfaces();
101     for (int i = 0; i < ifs->length(); i++) {
102       add_vm_class(ifs->at(i));
103     }
104   }
105 }
106 
107 bool AOTClassLinker::is_candidate(InstanceKlass* ik) {
108   return (_candidates->get(ik) != nullptr);
109 }
110 
111 void AOTClassLinker::add_new_candidate(InstanceKlass* ik) {
112   assert(!is_candidate(ik), "caller need to check");
113   _candidates->put_when_absent(ik, true);
114   _sorted_candidates->append(ik);
115 
116   if (log_is_enabled(Info, aot, link)) {
117     ResourceMark rm;
118     log_info(aot, link)("%s %s %p", class_category_name(ik), ik->external_name(), ik);
119   }
120 }
121 
122 // ik is a candidate for aot-linking; see if it can really work
123 // that way, and return success or failure. Not only must ik itself
124 // look like a class that can be aot-linked but its supers must also be
125 // aot-linkable.
126 bool AOTClassLinker::try_add_candidate(InstanceKlass* ik) {
127   assert(is_initialized(), "sanity");
128   assert(CDSConfig::is_dumping_aot_linked_classes(), "sanity");
129 
130   if (!SystemDictionaryShared::is_builtin(ik)) {
131     // not loaded by a class loader which we know about
132     return false;
133   }
134 
135   if (is_candidate(ik)) { // already checked.
136     return true;
137   }
138 
139   if (!ik->is_linked() && SystemDictionaryShared::has_class_failed_verification(ik)) {
140     return false;
141   }
142 
143   if (ik->is_hidden()) {
144     assert(!ik->defined_by_other_loaders(), "hidden classes are archived only for builtin loaders");
145     if (!CDSConfig::is_dumping_method_handles()) {
146       return false;
147     }
148     if (HeapShared::is_lambda_proxy_klass(ik)) {
149       InstanceKlass* nest_host = ik->nest_host_not_null();
150       if (!try_add_candidate(nest_host)) {
151         ResourceMark rm;
152         log_warning(aot, link)("%s cannot be aot-linked because it nest host is not aot-linked", ik->external_name());
153         return false;
154       }
155     }
156   }
157 
158   InstanceKlass* s = ik->super();
159   if (s != nullptr && !try_add_candidate(s)) {
160     return false;
161   }
162 
163   Array<InstanceKlass*>* interfaces = ik->local_interfaces();
164   int num_interfaces = interfaces->length();
165   for (int index = 0; index < num_interfaces; index++) {
166     InstanceKlass* intf = interfaces->at(index);
167     if (!try_add_candidate(intf)) {
168       return false;
169     }
170   }
171 
172   // There are no loops in the class hierarchy, and this function is always called single-threaded, so
173   // we know ik has not been added yet.
174   assert(CDSConfig::current_thread_is_vm_or_dumper(), "that's why we don't need locks");
175   add_new_candidate(ik);
176 
177   return true;
178 }
179 
180 void AOTClassLinker::add_candidates() {
181   assert_at_safepoint();
182   if (CDSConfig::is_dumping_aot_linked_classes()) {
183     GrowableArray<Klass*>* klasses = ArchiveBuilder::current()->klasses();
184     for (GrowableArrayIterator<Klass*> it = klasses->begin(); it != klasses->end(); ++it) {
185       Klass* k = *it;
186       if (k->is_instance_klass()) {
187         try_add_candidate(InstanceKlass::cast(k));
188       }
189     }
190   }
191 }
192 
193 void AOTClassLinker::write_to_archive() {
194   assert(is_initialized(), "sanity");
195   assert_at_safepoint();
196 
197   if (CDSConfig::is_dumping_aot_linked_classes()) {
198     AOTLinkedClassTable* table = AOTLinkedClassTable::get();
199     table->set_boot1(write_classes(nullptr, true));
200     table->set_boot2(write_classes(nullptr, false));
201     table->set_platform(write_classes(SystemDictionary::java_platform_loader(), false));
202     table->set_app(write_classes(SystemDictionary::java_system_loader(), false));
203   }
204 }
205 
206 Array<InstanceKlass*>* AOTClassLinker::write_classes(oop class_loader, bool is_javabase) {
207   ResourceMark rm;
208   GrowableArray<InstanceKlass*> list;
209 
210   for (int i = 0; i < _sorted_candidates->length(); i++) {
211     InstanceKlass* ik = _sorted_candidates->at(i);
212     if (ik->class_loader() != class_loader) {
213       continue;
214     }
215     if ((ik->module() == ModuleEntryTable::javabase_moduleEntry()) != is_javabase) {
216       continue;
217     }
218 
219     list.append(ArchiveBuilder::current()->get_buffered_addr(ik));
220   }
221 
222   if (list.length() == 0) {
223     return nullptr;
224   } else {
225     const char* category = class_category_name(list.at(0));
226     log_info(aot, link)("wrote %d class(es) for category %s", list.length(), category);
227     return ArchiveUtils::archive_array(&list);
228   }
229 }
230 
231 int AOTClassLinker::num_platform_initiated_classes() {
232   if (CDSConfig::is_dumping_aot_linked_classes()) {
233     // AOTLinkedClassBulkLoader will initiate loading of all public boot classes in the platform loader.
234     return count_public_classes(nullptr);
235   } else {
236     return 0;
237   }
238 }
239 
240 int AOTClassLinker::num_app_initiated_classes() {
241   if (CDSConfig::is_dumping_aot_linked_classes()) {
242     // AOTLinkedClassBulkLoader will initiate loading of all public boot/platform classes in the app loader.
243     return count_public_classes(nullptr) + count_public_classes(SystemDictionary::java_platform_loader());
244   } else {
245     return 0;
246   }
247 }
248 
249 int AOTClassLinker::count_public_classes(oop loader) {
250   int n = 0;
251   for (int i = 0; i < _sorted_candidates->length(); i++) {
252     InstanceKlass* ik = _sorted_candidates->at(i);
253     if (ik->is_public() && !ik->is_hidden() && ik->class_loader() == loader) {
254       n++;
255     }
256   }
257 
258   return n;
259 }
260 
261 // Used in logging: "boot1", "boot2", "plat", "app" and "unreg", or "array"
262 const char* AOTClassLinker::class_category_name(Klass* k) {
263   if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
264     k = ArchiveBuilder::current()->get_source_addr(k);
265   }
266 
267   if (k->is_array_klass()) {
268     return "array";
269   } else {
270     oop loader = k->class_loader();
271     if (loader == nullptr) {
272       if (k->module() != nullptr &&
273           k->module()->name() != nullptr &&
274           k->module()->name()->equals("java.base")) {
275         return "boot1"; // boot classes in java.base are loaded in the 1st phase
276       } else {
277         return "boot2"; // boot classes outside of java.base are loaded in the 2nd phase phase
278       }
279     } else {
280       if (loader == SystemDictionary::java_platform_loader()) {
281         return "plat";
282       } else if (loader == SystemDictionary::java_system_loader()) {
283         return "app";
284       } else {
285         return "unreg";
286       }
287     }
288   }
289 }
290 
291 const char* AOTClassLinker::class_category_name(AOTLinkedClassCategory category) {
292   switch (category) {
293   case AOTLinkedClassCategory::BOOT1:
294     return "boot1";
295   case AOTLinkedClassCategory::BOOT2:
296     return "boot2";
297   case AOTLinkedClassCategory::PLATFORM:
298     return "plat";
299   case AOTLinkedClassCategory::APP:
300     return "app";
301   case AOTLinkedClassCategory::UNREGISTERED:
302   default:
303       return "unreg";
304   }
305 }