26
26
#include " cds/archiveBuilder.hpp"
27
27
#include " cds/cdsConfig.hpp"
28
28
#include " cds/heapShared.hpp"
29
+ #include " classfile/symbolTable.hpp"
30
+ #include " classfile/systemDictionaryShared.hpp"
29
31
#include " classfile/vmSymbols.hpp"
30
32
#include " oops/instanceKlass.inline.hpp"
31
33
#include " oops/symbol.hpp"
34
+ #include " runtime/java.hpp"
32
35
#include " runtime/javaCalls.hpp"
33
36
37
+ DEBUG_ONLY (InstanceKlass* _aot_init_class = nullptr ;)
38
+
34
39
// Detector for class names we wish to handle specially.
35
40
// It is either an exact string match or a string prefix match.
36
41
class AOTClassInitializer::AllowedSpec {
@@ -93,12 +98,12 @@ bool AOTClassInitializer::is_allowed(AllowedSpec* specs, InstanceKlass* ik) {
93
98
94
99
95
100
bool AOTClassInitializer::can_archive_initialized_mirror (InstanceKlass* ik) {
96
- assert (!ArchiveBuilder::current ()->is_in_buffer_space (ik), " must be source klass" );
101
+ assert (!ArchiveBuilder::is_active () || ! ArchiveBuilder:: current ()->is_in_buffer_space (ik), " must be source klass" );
97
102
if (!CDSConfig::is_initing_classes_at_dump_time ()) {
98
103
return false ;
99
104
}
100
105
101
- if (!ik->is_initialized ()) {
106
+ if (!ik->is_initialized () && !ik-> is_being_initialized () ) {
102
107
return false ;
103
108
}
104
109
@@ -293,9 +298,11 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
293
298
{" java/lang/invoke/LambdaForm" },
294
299
{" java/lang/invoke/LambdaForm$Holder" }, // UNSAFE.ensureClassInitialized()
295
300
{" java/lang/invoke/LambdaForm$NamedFunction" },
301
+ {" java/lang/invoke/LambdaMetafactory" },
296
302
{" java/lang/invoke/MethodHandle" },
297
303
{" java/lang/invoke/MethodHandles" },
298
304
{" java/lang/invoke/SimpleMethodHandle" },
305
+ {" java/lang/invoke/StringConcatFactory" },
299
306
{" java/util/Collections" },
300
307
{" java/util/stream/Collectors" },
301
308
{" jdk/internal/constant/ConstantUtils" },
@@ -315,6 +322,12 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
315
322
}
316
323
}
317
324
325
+ #ifdef ASSERT
326
+ if (ik == _aot_init_class) {
327
+ return true ;
328
+ }
329
+ #endif
330
+
318
331
return false ;
319
332
}
320
333
@@ -345,3 +358,33 @@ void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass*
345
358
}
346
359
}
347
360
}
361
+
362
+ #ifdef ASSERT
363
+ void AOTClassInitializer::init_test_class (TRAPS) {
364
+ // -XX:AOTInitTestClass is used in regression tests for adding additional AOT-initialized classes
365
+ // and heap objects into the AOT cache. The tests must be carefully written to avoid including
366
+ // any classes that cannot be AOT-initialized.
367
+ //
368
+ // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into
369
+ // the AOT cache. Therefore, this option is NOT available in product JVM.
370
+ if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time ()) {
371
+ log_info (cds)(" Debug build only: force initialization of AOTInitTestClass %s" , AOTInitTestClass);
372
+ TempNewSymbol class_name = SymbolTable::new_symbol (AOTInitTestClass);
373
+ Handle app_loader (THREAD, SystemDictionary::java_system_loader ());
374
+ Klass* k = SystemDictionary::resolve_or_null (class_name, app_loader, CHECK);
375
+ if (k == nullptr ) {
376
+ vm_exit_during_initialization (" AOTInitTestClass not found" , AOTInitTestClass);
377
+ }
378
+ if (!k->is_instance_klass ()) {
379
+ vm_exit_during_initialization (" Invalid name for AOTInitTestClass" , AOTInitTestClass);
380
+ }
381
+
382
+ _aot_init_class = InstanceKlass::cast (k);
383
+ _aot_init_class->initialize (CHECK);
384
+ }
385
+ }
386
+
387
+ bool AOTClassInitializer::has_test_class () {
388
+ return _aot_init_class != nullptr ;
389
+ }
390
+ #endif
0 commit comments