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/aotClassInitializer.hpp"
 26 #include "cds/aotLinkedClassBulkLoader.hpp"
 27 #include "cds/archiveBuilder.hpp"
 28 #include "cds/cdsConfig.hpp"
 29 #include "cds/heapShared.hpp"
 30 #include "cds/regeneratedClasses.hpp"
 31 #include "classfile/symbolTable.hpp"
 32 #include "classfile/systemDictionaryShared.hpp"
 33 #include "classfile/vmSymbols.hpp"
 34 #include "dumpTimeClassInfo.inline.hpp"
 35 #include "memory/resourceArea.hpp"
 36 #include "oops/fieldStreams.inline.hpp"
 37 #include "oops/instanceKlass.inline.hpp"
 38 #include "oops/symbol.hpp"
 39 #include "runtime/fieldDescriptor.inline.hpp"
 40 #include "runtime/java.hpp"
 41 #include "runtime/javaCalls.hpp"
 42 #include "runtime/mutexLocker.hpp"
 43 
 44 DEBUG_ONLY(InstanceKlass* _aot_init_class = nullptr;)
 45 
 46 bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
 47   assert(!ArchiveBuilder::is_active() || !ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass");
 48   if (!CDSConfig::is_initing_classes_at_dump_time()) {
 49     return false;
 50   }
 51 
 52   if (RegeneratedClasses::is_regenerated_object(ik)) {
 53     ik = RegeneratedClasses::get_original_object(ik);
 54   }
 55 
 56   check_aot_annotations(ik);
 57 
 58   if (!ik->is_initialized() && !ik->is_being_initialized()) {
 59     if (ik->has_aot_safe_initializer()) {
 60       ResourceMark rm;
 61       log_info(aot, init)("Class %s is annotated with @AOTSafeClassInitializer but has not been initialized",
 62                           ik->external_name());
 63     }
 64     return false;
 65   }
 66 
 67   // About "static field that may hold a different value" errors:
 68   //
 69   // Automatic selection for aot-inited classes
 70   // ==========================================
 71   //
 72   // When CDSConfig::is_initing_classes_at_dump_time is enabled,
 73   // AOTArtifactFinder::find_artifacts() finds the classes of all
 74   // heap objects that are reachable from HeapShared::_run_time_special_subgraph,
 75   // and mark these classes as aot-inited. This preserves the initialized
 76   // mirrors of these classes, and their <clinit> methods are NOT executed
 77   // at runtime. See aotArtifactFinder.hpp for more info.
 78   //
 79   // For example, with -XX:+AOTInvokeDynamicLinking, _run_time_special_subgraph
 80   // will contain some DirectMethodHandle objects. As a result, the DirectMethodHandle
 81   // class is automatically marked as aot-inited.
 82   //
 83   // When a class is aot-inited, its static fields are already set up
 84   // by executing the <clinit> method at AOT assembly time.  Later on
 85   // in the production run, when the class would normally be
 86   // initialized, the VM performs guarding and synchronization as if
 87   // it were going to run the <clinit> again, but instead it simply
 88   // observes that that class was aot-inited.  The VM assumes that, if
 89   // it were to run <clinit> again, it would get a semantically
 90   // equivalent set of final field values, so it just adopts the
 91   // existing field values (from AOT assembly) and skips the call to
 92   // <clinit>.  There may at that point be fixups performed by ad hoc
 93   // code, if the VM recognizes a request in the library.
 94   //
 95   // It is true that this is not generally correct for all possible
 96   // Java code.  A <clinit> method might have a side effect beyond
 97   // initializing the static fields.  It might send an email somewhere
 98   // noting the current time of day.  In that case, such an email
 99   // would have been sent during the AOT assembly phase, and the email
100   // would NOT be sent again during production.  This is clearly NOT
101   // what a user would want, if this were a general purpose facility.
102   // But in fact it is only for certain well-behaved classes, which
103   // are known NOT to have such side effects.  We know this because
104   // the optimization (of skipping <clinit> for aot-init classes) is
105   // only applied to classes fully defined by the JDK.
106   //
107   // (A day may come when we figure out how to gracefully extend this
108   // optimization to untrusted third parties, but it is not this day.)
109   //
110   // Manual selection
111   // ================
112   //
113   // There are important cases where one aot-init class has a side
114   // effect on another aot-class, a side effect which is not captured
115   // in any static field value in either class.  The simplest example
116   // is class A forces the initialization of class B.  In that case,
117   // we need to aot-init either both classes or neither.  From looking
118   // at the JDK state after AOT assembly is done, it is hard to tell
119   // that A "touched" B and B might escape our notice.  Another common
120   // example is A copying a field value from B.  We don't know where A
121   // got the value, but it would be wrong to re-initialize B at
122   // startup, while keeping the snapshot of the old B value in A.  In
123   // general, if we aot-init A, we need to aot-init every class B that
124   // somehow contributed to A's initial state, and every class C that
125   // was somehow side-effected by A's initialization.  We say that the
126   // aot-init of A is "init-coupled" to those of B and C.
127   //
128   // So there are init-coupled classes that cannot be automatically discovered. For
129   // example, DirectMethodHandle::IMPL_NAMES points to MethodHandles::IMPL_NAMES,
130   // but the MethodHandles class is not automatically marked because there are
131   // no archived instances of the MethodHandles type.
132   //
133   // If we aot-initialize DirectMethodHandle, but allow MethodHandles to be
134   // initialized at runtime, MethodHandles::IMPL_NAMES will get a different
135   // value than DirectMethodHandle::IMPL_NAMES. This *may or may not* be a problem,
136   // but to ensure compatibility, we should try to preserve the identity equality
137   // of these two fields.
138   //
139   // To do that, we add MethodHandles to the indy_specs[] table below.
140   //
141   // Luckily we do not need to be all-knowing in order to choose which
142   // items to add to that table.  We have tools to help detect couplings.
143   //
144   // Automatic validation
145   // ====================
146   //
147   // CDSHeapVerifier is used to detect potential problems with identity equality.
148   //
149   // A class B is assumed to be init-coupled to some aot-init class if
150   // B has a field which points to a live object X in the AOT heap.
151   // The live object X was created by some other class A which somehow
152   // used B's reference to X, perhaps with the help of an intermediate
153   // class Z.  Or, B pulled the reference to X from some other class
154   // Y, and B obtained that reference from Y (or an intermediate Z).
155   // It is not certain how X got into the heap, nor whether B
156   // contributed it, but it is a good heuristic that B is init-coupled
157   // to X's class or some other aot-init class.  In any case, B should
158   // be made an aot-init class as well, unless a manual inspection
159   // shows that would be a problem.  If there is a problem, then the
160   // JDK code for B and/or X probably needs refactoring.  If there is
161   // no problem, we add B to the list.  Typically the same scan will
162   // find any other accomplices Y, Z, etc.  One failure would be a
163   // class Q whose only initialization action is to scribble a special
164   // value into B, from which the value X is derived and then makes
165   // its way into the heap.  In that case, the heuristic does not
166   // identify Q.  It is (currently) a human responsibility, of JDK
167   // engineers, not to write such dirty JDK code, or to repair it if
168   // it crops up.  Eventually we may have tools, or even a user mode
169   // with design rules and checks, that will vet our code base more
170   // automatically.
171   //
172   // To see how the tool detects the problem with MethodHandles::IMPL_NAMES:
173   //
174   // - Comment out all the lines in indy_specs[] except the {nullptr} line.
175   // - Rebuild the JDK
176   //
177   // Then run the following:
178   //    java -XX:AOTMode=record -XX:AOTConfiguration=jc.aotconfig com.sun.tools.javac.Main
179   //    java -XX:AOTMode=create -Xlog:aot -XX:AOTCache=jc.aot -XX:AOTConfiguration=jc.aotconfig
180   //
181   // You will see an error like this:
182   //
183   // Archive heap points to a static field that may hold a different value at runtime:
184   // Field: java/lang/invoke/MethodHandles::IMPL_NAMES
185   // Value: java.lang.invoke.MemberName$Factory
186   // {0x000000060e906ae8} - klass: 'java/lang/invoke/MemberName$Factory' - flags:
187   //
188   //  - ---- fields (total size 2 words):
189   // --- trace begin ---
190   // [ 0] {0x000000060e8deeb0} java.lang.Class (java.lang.invoke.DirectMethodHandle::IMPL_NAMES)
191   // [ 1] {0x000000060e906ae8} java.lang.invoke.MemberName$Factory
192   // --- trace end ---
193   //
194   // Trouble-shooting
195   // ================
196   //
197   // If you see a "static field that may hold a different value" error, it's probably
198   // because you've made some changes in the JDK core libraries (most likely
199   // java.lang.invoke).
200   //
201   //  - Did you add a new static field to a class that could be referenced by
202   //    cached object instances of MethodType, MethodHandle, etc? You may need
203   //    to add that class to indy_specs[].
204   //  - Did you modify the <clinit> of the classes in java.lang.invoke such that
205   //    a static field now points to an object that should not be cached (e.g.,
206   //    a native resource such as a file descriptior, or a Thread)?
207   //
208   // Note that these potential problems only occur when one class gets
209   // the aot-init treatment, AND another class is init-coupled to it,
210   // AND the coupling is not detected.  Currently there are a number
211   // classes that get the aot-init treatment, in java.lang.invoke
212   // because of invokedynamic.  They are few enough for now to be
213   // manually tracked.  There may be more in the future.
214 
215   {
216     if (ik == vmClasses::Object_klass()) {
217       // everybody's favorite super
218       return true;
219     }
220   }
221 
222   if (CDSConfig::is_dumping_method_handles()) {
223     // The minimal list of @AOTSafeClassInitializer was created with the help of CDSHeapVerifier.
224     // Also, some $Holder classes are needed. E.g., Invokers.<clinit> explicitly
225     // initializes Invokers$Holder. Since Invokers.<clinit> won't be executed
226     // at runtime, we need to make sure Invokers$Holder is also aot-inited.
227     if (ik->has_aot_safe_initializer()) {
228       return true;
229     }
230   }
231 
232 #ifdef ASSERT
233   if (ik == _aot_init_class) {
234     return true;
235   }
236 #endif
237 
238   return false;
239 }
240 
241 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
242   assert(ik->has_aot_initialized_mirror(), "sanity");
243   if (ik->is_runtime_setup_required()) {
244     if (log_is_enabled(Info, aot, init)) {
245       ResourceMark rm;
246       log_info(aot, init)("Calling %s::runtimeSetup()", ik->external_name());
247     }
248     JavaValue result(T_VOID);
249     JavaCalls::call_static(&result, ik,
250                            vmSymbols::runtimeSetup(),
251                            vmSymbols::void_method_signature(), current);
252     if (current->has_pending_exception()) {
253       // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
254       // exception would cause ik to be in an error state.
255       AOTLinkedClassBulkLoader::exit_on_exception(current);
256     }
257   }
258 }
259 
260 // check_can_be_preinited() is quite costly, so we cache the results inside
261 // DumpTimeClassInfo::_can_be_preinited. See also AOTClassInitializer::reset_preinit_check().
262 bool AOTClassInitializer::check_can_be_preinited(InstanceKlass* ik) {
263   ResourceMark rm;
264 
265   if (!SystemDictionaryShared::is_builtin(ik)) {
266     log_info(cds, init)("cannot initialize %s (not built-in loader)", ik->external_name());
267     return false;
268   }
269 
270   InstanceKlass* super = ik->java_super();
271   if (super != nullptr && !can_be_preinited_locked(super)) {
272     log_info(cds, init)("cannot initialize %s (super %s not initable)", ik->external_name(), super->external_name());
273     return false;
274   }
275 
276   Array<InstanceKlass*>* interfaces = ik->local_interfaces();
277   for (int i = 0; i < interfaces->length(); i++) {
278     if (!can_be_preinited_locked(interfaces->at(i))) {
279       log_info(cds, init)("cannot initialize %s (interface %s not initable)",
280                           ik->external_name(), interfaces->at(i)->external_name());
281       return false;
282     }
283   }
284 
285   if (HeapShared::is_lambda_form_klass(ik)) {
286     // We allow only these to have <clinit> or non-default static fields
287     return true;
288   }
289 
290   if (ik->class_initializer() != nullptr) {
291     log_info(cds, init)("cannot initialize %s (has <clinit>)", ik->external_name());
292     return false;
293   }
294   if (ik->is_initialized() && !has_default_static_fields(ik)) {
295     return false;
296   }
297 
298   return true;
299 }
300 
301 bool AOTClassInitializer::has_default_static_fields(InstanceKlass* ik) {
302   oop mirror = ik->java_mirror();
303 
304   for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
305     if (fs.access_flags().is_static()) {
306       fieldDescriptor& fd = fs.field_descriptor();
307       int offset = fd.offset();
308       bool is_default = true;
309       bool has_initval = fd.has_initial_value();
310       switch (fd.field_type()) {
311       case T_OBJECT:
312       case T_ARRAY:
313         is_default = mirror->obj_field(offset) == nullptr;
314         break;
315       case T_BOOLEAN:
316         is_default = mirror->bool_field(offset) == (has_initval ? fd.int_initial_value() : 0);
317         break;
318       case T_BYTE:
319         is_default = mirror->byte_field(offset) == (has_initval ? fd.int_initial_value() : 0);
320         break;
321       case T_SHORT:
322         is_default = mirror->short_field(offset) == (has_initval ? fd.int_initial_value() : 0);
323         break;
324       case T_CHAR:
325         is_default = mirror->char_field(offset) == (has_initval ? fd.int_initial_value() : 0);
326         break;
327       case T_INT:
328         is_default = mirror->int_field(offset) == (has_initval ? fd.int_initial_value() : 0);
329         break;
330       case T_LONG:
331         is_default = mirror->long_field(offset) == (has_initval ? fd.long_initial_value() : 0);
332         break;
333       case T_FLOAT:
334         is_default = mirror->float_field(offset) == (has_initval ? fd.float_initial_value() : 0);
335         break;
336       case T_DOUBLE:
337         is_default = mirror->double_field(offset) == (has_initval ? fd.double_initial_value() : 0);
338         break;
339       default:
340         ShouldNotReachHere();
341       }
342 
343       if (!is_default) {
344         log_info(cds, init)("cannot initialize %s (static field %s has non-default value)",
345                             ik->external_name(), fd.name()->as_C_string());
346         return false;
347       }
348     }
349   }
350 
351   return true;
352 }
353 
354 bool AOTClassInitializer::can_be_preinited(InstanceKlass* ik) {
355   MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
356   return can_be_preinited_locked(ik);
357 }
358 
359 bool AOTClassInitializer::can_be_preinited_locked(InstanceKlass* ik) {
360   if (!CDSConfig::is_initing_classes_at_dump_time()) {
361     return false;
362   }
363 
364   assert_lock_strong(DumpTimeTable_lock);
365   DumpTimeClassInfo* info = SystemDictionaryShared::get_info_locked(ik);
366   if (!info->has_done_preinit_check()) {
367     info->set_can_be_preinited(AOTClassInitializer::check_can_be_preinited(ik));
368   }
369   return info->can_be_preinited();
370 }
371 
372 // Initialize a class at dump time, if possible.
373 void AOTClassInitializer::maybe_preinit_class(InstanceKlass* ik, TRAPS) {
374 #if 0 // FIXME -- leyden+JEP483 merge
375   if (!ik->is_initialized() && AOTClassInitializer::can_be_preinited(ik)) {
376     if (log_is_enabled(Info, cds, init)) {
377       ResourceMark rm;
378       log_info(cds, init)("preinitializing %s", ik->external_name());
379     }
380     ik->initialize(CHECK);
381   }
382 #endif
383 }
384 
385 template <typename FUNCTION>
386 void require_annotation_for_super_types(InstanceKlass* ik, const char* annotation, FUNCTION func) {
387   if (log_is_enabled(Info, aot, init)) {
388     ResourceMark rm;
389     log_info(aot, init)("Found %s class %s", annotation, ik->external_name());
390   }
391 
392   // Since ik has this annotation, we require that
393   //   - all super classes must have this annotation
394   //   - all super interfaces that are interface_needs_clinit_execution_as_super()
395   //     must have this annotation
396   // This avoid the situation where in the production run, we run the <clinit>
397   // of a supertype but not the <clinit> of ik
398 
399   InstanceKlass* super = ik->java_super();
400   if (super != nullptr && !func(super)) {
401     ResourceMark rm;
402     log_error(aot, init)("Missing %s in superclass %s for class %s",
403                          annotation, super->external_name(), ik->external_name());
404     AOTMetaspace::unrecoverable_writing_error();
405   }
406 
407   int len = ik->local_interfaces()->length();
408   for (int i = 0; i < len; i++) {
409     InstanceKlass* intf = ik->local_interfaces()->at(i);
410     if (intf->interface_needs_clinit_execution_as_super() && !func(intf)) {
411       ResourceMark rm;
412       log_error(aot, init)("Missing %s in superinterface %s for class %s",
413                            annotation, intf->external_name(), ik->external_name());
414       AOTMetaspace::unrecoverable_writing_error();
415     }
416   }
417 }
418 
419 void AOTClassInitializer::check_aot_annotations(InstanceKlass* ik) {
420   if (ik->has_aot_safe_initializer()) {
421     require_annotation_for_super_types(ik, "@AOTSafeClassInitializer", [&] (const InstanceKlass* supertype) {
422       return supertype->has_aot_safe_initializer();
423     });
424   } else {
425     // @AOTRuntimeSetup only meaningful in @AOTSafeClassInitializer
426     if (ik->is_runtime_setup_required()) {
427       ResourceMark rm;
428       log_error(aot, init)("@AOTRuntimeSetup meaningless in non-@AOTSafeClassInitializer class %s",
429                            ik->external_name());
430     }
431   }
432 }
433 
434 #ifdef ASSERT
435 void AOTClassInitializer::init_test_class(TRAPS) {
436   // -XX:AOTInitTestClass is used in regression tests for adding additional AOT-initialized classes
437   // and heap objects into the AOT cache. The tests must be carefully written to avoid including
438   // any classes that cannot be AOT-initialized.
439   //
440   // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into
441   // the AOT cache. Therefore, this option is NOT available in product JVM.
442   if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time()) {
443     log_info(aot)("Debug build only: force initialization of AOTInitTestClass %s", AOTInitTestClass);
444     TempNewSymbol class_name = SymbolTable::new_symbol(AOTInitTestClass);
445     Handle app_loader(THREAD, SystemDictionary::java_system_loader());
446     Klass* k = SystemDictionary::resolve_or_null(class_name, app_loader, CHECK);
447     if (k == nullptr) {
448       vm_exit_during_initialization("AOTInitTestClass not found", AOTInitTestClass);
449     }
450     if (!k->is_instance_klass()) {
451       vm_exit_during_initialization("Invalid name for AOTInitTestClass", AOTInitTestClass);
452     }
453 
454     _aot_init_class = InstanceKlass::cast(k);
455     _aot_init_class->initialize(CHECK);
456   }
457 }
458 
459 bool AOTClassInitializer::has_test_class() {
460   return _aot_init_class != nullptr;
461 }
462 #endif