1 /*
  2  * Copyright (c) 2023, 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/archiveHeapLoader.hpp"
 26 #include "cds/cdsConfig.hpp"

 27 #include "cds/classListWriter.hpp"
 28 #include "cds/filemap.hpp"
 29 #include "cds/heapShared.hpp"

 30 #include "classfile/classLoaderDataShared.hpp"
 31 #include "classfile/moduleEntry.hpp"


 32 #include "include/jvm_io.h"
 33 #include "logging/log.hpp"

 34 #include "memory/universe.hpp"
 35 #include "runtime/arguments.hpp"
 36 #include "runtime/globals_extension.hpp"
 37 #include "runtime/java.hpp"
 38 #include "runtime/vmThread.hpp"
 39 #include "utilities/defaultStream.hpp"
 40 #include "utilities/formatBuffer.hpp"
 41 
 42 bool CDSConfig::_is_dumping_static_archive = false;
 43 bool CDSConfig::_is_dumping_preimage_static_archive = false;
 44 bool CDSConfig::_is_dumping_final_static_archive = false;
 45 bool CDSConfig::_is_dumping_dynamic_archive = false;
 46 bool CDSConfig::_is_using_optimized_module_handling = true;
 47 bool CDSConfig::_is_dumping_full_module_graph = true;
 48 bool CDSConfig::_is_using_full_module_graph = true;
 49 bool CDSConfig::_has_aot_linked_classes = false;



 50 bool CDSConfig::_old_cds_flags_used = false;
 51 bool CDSConfig::_new_aot_flags_used = false;
 52 bool CDSConfig::_disable_heap_dumping = false;
 53 
 54 char* CDSConfig::_default_archive_path = nullptr;
 55 char* CDSConfig::_static_archive_path = nullptr;
 56 char* CDSConfig::_dynamic_archive_path = nullptr;
 57 
 58 JavaThread* CDSConfig::_dumper_thread = nullptr;
 59 
 60 int CDSConfig::get_status() {
 61   assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized");
 62   return (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
 63          (is_dumping_static_archive()       ? IS_DUMPING_STATIC_ARCHIVE : 0) |
 64          (is_logging_lambda_form_invokers() ? IS_LOGGING_LAMBDA_FORM_INVOKERS : 0) |
 65          (is_using_archive()                ? IS_USING_ARCHIVE : 0);




 66 }
 67 
 68 void CDSConfig::initialize() {
 69   if (is_dumping_static_archive() && !is_dumping_final_static_archive()) {
 70     // Note: -Xshare and -XX:AOTMode flags are mutually exclusive.
 71     // - Classic workflow: -Xshare:on and -Xshare:dump cannot take effect at the same time.
 72     // - JEP 483 workflow: -XX:AOTMode:record and -XX:AOTMode=on cannot take effect at the same time.
 73     // So we can never come to here with RequireSharedSpaces==true.
 74     assert(!RequireSharedSpaces, "sanity");
 75 
 76     // If dumping the classic archive, or making an AOT training run (dumping a preimage archive),
 77     // for sanity, parse all classes from classfiles.
 78     // TODO: in the future, if we want to support re-training on top of an existing AOT cache, this
 79     // needs to be changed.










 80     UseSharedSpaces = false;
 81   }
 82 
 83   // Initialize shared archive paths which could include both base and dynamic archive paths
 84   // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
 85   //
 86   // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
 87   if (is_dumping_static_archive() || is_using_archive()) {
 88     init_shared_archive_paths();
 89   }
 90 
 91   if (!is_dumping_heap()) {
 92     _is_dumping_full_module_graph = false;
 93   }
 94 }
 95 
 96 char* CDSConfig::default_archive_path() {
 97   if (_default_archive_path == nullptr) {
 98     stringStream tmp;
 99     const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib");
100     tmp.print("%s%s%s%s%s%sclasses", Arguments::get_java_home(), os::file_separator(), subdir,
101               os::file_separator(), Abstract_VM_Version::vm_variant(), os::file_separator());
102 #ifdef _LP64
103     if (!UseCompressedOops) {
104       tmp.print_raw("_nocoops");
105     }
106     if (UseCompactObjectHeaders) {
107       // Note that generation of xxx_coh.jsa variants require
108       // --enable-cds-archive-coh at build time
109       tmp.print_raw("_coh");
110     }
111 #endif
112     tmp.print_raw(".jsa");
113     _default_archive_path = os::strdup(tmp.base());
114   }
115   return _default_archive_path;
116 }
117 
118 int CDSConfig::num_archives(const char* archive_path) {
119   if (archive_path == nullptr) {
120     return 0;
121   }
122   int npaths = 1;
123   char* p = (char*)archive_path;
124   while (*p != '\0') {
125     if (*p == os::path_separator()[0]) {
126       npaths++;
127     }
128     p++;
129   }
130   return npaths;
131 }
132 
133 void CDSConfig::extract_shared_archive_paths(const char* archive_path,
134                                              char** base_archive_path,
135                                              char** top_archive_path) {
136   char* begin_ptr = (char*)archive_path;
137   char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
138   if (end_ptr == nullptr || end_ptr == begin_ptr) {
139     vm_exit_during_initialization("Base archive was not specified", archive_path);
140   }
141   size_t len = end_ptr - begin_ptr;
142   char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
143   strncpy(cur_path, begin_ptr, len);
144   cur_path[len] = '\0';
145   *base_archive_path = cur_path;
146 
147   begin_ptr = ++end_ptr;
148   if (*begin_ptr == '\0') {
149     vm_exit_during_initialization("Top archive was not specified", archive_path);
150   }
151   end_ptr = strchr(begin_ptr, '\0');
152   assert(end_ptr != nullptr, "sanity");
153   len = end_ptr - begin_ptr;
154   cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
155   strncpy(cur_path, begin_ptr, len + 1);
156   *top_archive_path = cur_path;
157 }
158 
159 void CDSConfig::init_shared_archive_paths() {
160   if (ArchiveClassesAtExit != nullptr) {
161     assert(!RecordDynamicDumpInfo, "already checked");
162     if (is_dumping_static_archive()) {
163       vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
164     }
165     check_unsupported_dumping_module_options();
166 
167     if (os::same_files(default_archive_path(), ArchiveClassesAtExit)) {
168       vm_exit_during_initialization(
169         "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", default_archive_path());
170     }
171   }
172 
173   if (SharedArchiveFile == nullptr) {
174     _static_archive_path = default_archive_path();
175   } else {
176     int archives = num_archives(SharedArchiveFile);
177     assert(archives > 0, "must be");
178 
179     if (is_dumping_archive() && archives > 1) {
180       vm_exit_during_initialization(
181         "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
182     }
183 




184     if (is_dumping_static_archive()) {
185       assert(archives == 1, "must be");
186       // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file
187       // will be overwritten no matter regardless of its contents
188       _static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
189     } else {
190       // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa
191       // is read from top.jsa
192       //    (a) 1 file:  -XX:SharedArchiveFile=base.jsa
193       //    (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa
194       //    (c) 2 files: -XX:SharedArchiveFile=top.jsa
195       //
196       // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not
197       // allow cases (b) and (c). Case (b) is already checked above.
198 
199       if (archives > 2) {
200         vm_exit_during_initialization(
201           "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
202       }
203       if (archives == 1) {
204         char* base_archive_path = nullptr;
205         bool success =
206           FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
207         if (!success) {




208           // If +AutoCreateSharedArchive and the specified shared archive does not exist,
209           // regenerate the dynamic archive base on default archive.
210           if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) {
211             enable_dumping_dynamic_archive();
212             ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile);
213             _static_archive_path = default_archive_path();
214             SharedArchiveFile = nullptr;
215           } else {
216             if (AutoCreateSharedArchive) {
217               warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.");
218               AutoCreateSharedArchive = false;
219             }
220             log_error(cds)("Not a valid %s (%s)", new_aot_flags_used() ? "AOT cache" : "archive", SharedArchiveFile);
221             Arguments::no_shared_spaces("invalid archive");
222           }
223         } else if (base_archive_path == nullptr) {
224           // User has specified a single archive, which is a static archive.
225           _static_archive_path = const_cast<char *>(SharedArchiveFile);
226         } else {
227           // User has specified a single archive, which is a dynamic archive.
228           _dynamic_archive_path = const_cast<char *>(SharedArchiveFile);
229           _static_archive_path = base_archive_path; // has been c-heap allocated.
230         }
231       } else {
232         extract_shared_archive_paths((const char*)SharedArchiveFile,
233                                       &_static_archive_path, &_dynamic_archive_path);
234         if (_static_archive_path == nullptr) {
235           assert(_dynamic_archive_path == nullptr, "must be");
236           Arguments::no_shared_spaces("invalid archive");
237         }
238       }
239 
240       if (_dynamic_archive_path != nullptr) {
241         // Check for case (c)
242         if (RecordDynamicDumpInfo) {
243           vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
244                                         SharedArchiveFile);
245         }
246         if (ArchiveClassesAtExit != nullptr) {
247           vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
248                                         SharedArchiveFile);
249         }
250       }
251 
252       if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
253           vm_exit_during_initialization(
254             "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
255             SharedArchiveFile);
256       }
257     }
258   }
259 }
260 



261 void CDSConfig::check_internal_module_property(const char* key, const char* value) {
262   if (Arguments::is_incompatible_cds_internal_module_property(key)) {
263     stop_using_optimized_module_handling();
264     log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);









265   }
266 }
267 
268 void CDSConfig::check_incompatible_property(const char* key, const char* value) {
269   static const char* incompatible_properties[] = {
270     "java.system.class.loader",
271     "jdk.module.showModuleResolution",
272     "jdk.module.validation"
273   };
274 
275   for (const char* property : incompatible_properties) {
276     if (strcmp(key, property) == 0) {
277       stop_dumping_full_module_graph();
278       stop_using_full_module_graph();
279       log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
280       break;
281     }
282   }
283 






284 }
285 
286 // Returns any JVM command-line option, such as "--patch-module", that's not supported by CDS.
287 static const char* find_any_unsupported_module_option() {
288   // Note that arguments.cpp has translated the command-line options into properties. If we find an
289   // unsupported property, translate it back to its command-line option for better error reporting.
290 
291   // The following properties are checked by Arguments::is_internal_module_property() and cannot be
292   // directly specified in the command-line.
293   static const char* unsupported_module_properties[] = {
294     "jdk.module.limitmods",
295     "jdk.module.upgrade.path",
296     "jdk.module.patch.0"
297   };
298   static const char* unsupported_module_options[] = {
299     "--limit-modules",
300     "--upgrade-module-path",
301     "--patch-module"
302   };
303 
304   assert(ARRAY_SIZE(unsupported_module_properties) == ARRAY_SIZE(unsupported_module_options), "must be");
305   SystemProperty* sp = Arguments::system_properties();
306   while (sp != nullptr) {
307     for (uint i = 0; i < ARRAY_SIZE(unsupported_module_properties); i++) {
308       if (strcmp(sp->key(), unsupported_module_properties[i]) == 0) {
309         return unsupported_module_options[i];
310       }
311     }
312     sp = sp->next();
313   }
314 
315   return nullptr; // not found
316 }
317 
318 void CDSConfig::check_unsupported_dumping_module_options() {
319   assert(is_dumping_archive(), "this function is only used with CDS dump time");
320   const char* option = find_any_unsupported_module_option();
321   if (option != nullptr) {
322     vm_exit_during_initialization("Cannot use the following option when dumping the shared archive", option);
323   }
324   // Check for an exploded module build in use with -Xshare:dump.
325   if (!Arguments::has_jimage()) {
326     vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
327   }
328 }
329 
330 bool CDSConfig::has_unsupported_runtime_module_options() {
331   assert(is_using_archive(), "this function is only used with -Xshare:{on,auto}");
332   if (ArchiveClassesAtExit != nullptr) {
333     // dynamic dumping, just return false for now.
334     // check_unsupported_dumping_properties() will be called later to check the same set of
335     // properties, and will exit the VM with the correct error message if the unsupported properties
336     // are used.
337     return false;
338   }
339   const char* option = find_any_unsupported_module_option();
340   if (option != nullptr) {
341     if (RequireSharedSpaces) {
342       warning("CDS is disabled when the %s option is specified.", option);
343     } else {
344       if (new_aot_flags_used()) {
345         log_warning(cds)("AOT cache is disabled when the %s option is specified.", option);
346       } else {
347         log_info(cds)("CDS is disabled when the %s option is specified.", option);
348       }
349     }
350     return true;
351   }
352   return false;
353 }
354 
355 #define CHECK_ALIAS(f) check_flag_alias(FLAG_IS_DEFAULT(f), #f)
356 
357 void CDSConfig::check_flag_alias(bool alias_is_default, const char* alias_name) {
358   if (old_cds_flags_used() && !alias_is_default) {
359     vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with "
360                                           "-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, "
361                                           "DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile",
362                                           alias_name));
363   }
364 }
365 
366 void CDSConfig::check_aot_flags() {
367   if (!FLAG_IS_DEFAULT(DumpLoadedClassList) ||
368       !FLAG_IS_DEFAULT(SharedClassListFile) ||
369       !FLAG_IS_DEFAULT(SharedArchiveFile)) {
370     _old_cds_flags_used = true;
371   }
372 
373   CHECK_ALIAS(AOTCache);
374   CHECK_ALIAS(AOTConfiguration);
375   CHECK_ALIAS(AOTMode);
376 
377   if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) {
378     // AOTCache/AOTConfiguration/AOTMode not used.
379     return;
380   } else {
381     _new_aot_flags_used = true;
382   }
383 
384   if (FLAG_IS_DEFAULT(AOTMode) || strcmp(AOTMode, "auto") == 0 || strcmp(AOTMode, "on") == 0) {
385     check_aotmode_auto_or_on();
386   } else if (strcmp(AOTMode, "off") == 0) {
387     check_aotmode_off();
388   } else {
389     // AOTMode is record or create
390     if (FLAG_IS_DEFAULT(AOTConfiguration)) {
391       vm_exit_during_initialization(err_msg("-XX:AOTMode=%s cannot be used without setting AOTConfiguration", AOTMode));
392     }
393 
394     if (strcmp(AOTMode, "record") == 0) {
395       check_aotmode_record();
396     } else {
397       assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc");
398       check_aotmode_create();
399     }
400   }
401 }
402 
403 void CDSConfig::check_aotmode_off() {
404   UseSharedSpaces = false;
405   RequireSharedSpaces = false;
406 }
407 
408 void CDSConfig::check_aotmode_auto_or_on() {
409   if (!FLAG_IS_DEFAULT(AOTConfiguration)) {
410     vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create");
411   }
412 
413   if (!FLAG_IS_DEFAULT(AOTCache)) {
414     assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
415     FLAG_SET_ERGO(SharedArchiveFile, AOTCache);
416   }
417 
418   UseSharedSpaces = true;
419   if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) {
420     RequireSharedSpaces = false;
421   } else {
422     assert(strcmp(AOTMode, "on") == 0, "already checked");
423     RequireSharedSpaces = true;
424   }
425 }
426 
427 void CDSConfig::check_aotmode_record() {
428   if (!FLAG_IS_DEFAULT(AOTCache)) {
429     vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record");
430   }
431 
432   assert(FLAG_IS_DEFAULT(DumpLoadedClassList), "already checked");
433   assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
434   FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
435   FLAG_SET_ERGO(DumpLoadedClassList, nullptr);
436   UseSharedSpaces = false;
437   RequireSharedSpaces = false;
438   _is_dumping_static_archive = true;
439   _is_dumping_preimage_static_archive = true;
440 
441   // At VM exit, the module graph may be contaminated with program states.
442   // We will rebuild the module graph when dumping the CDS final image.
443   disable_heap_dumping();
444 }
445 
446 void CDSConfig::check_aotmode_create() {
447   if (FLAG_IS_DEFAULT(AOTCache)) {
448     vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create");
449   }
450 
451   assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
452 
453   _is_dumping_final_static_archive = true;
454   FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
455   UseSharedSpaces = true;
456   RequireSharedSpaces = true;
457 
458   if (!FileMapInfo::is_preimage_static_archive(AOTConfiguration)) {
459     vm_exit_during_initialization("Must be a valid AOT configuration generated by the current JVM", AOTConfiguration);
460   }
461 
462   CDSConfig::enable_dumping_static_archive();
463 }
464 
465 bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) {
466   check_aot_flags();
467 
468   if (!FLAG_IS_DEFAULT(AOTMode)) {
469     // Using any form of the new AOTMode switch enables enhanced optimizations.
470     FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true);
471   }
472 












473   if (AOTClassLinking) {
474     // If AOTClassLinking is specified, enable all AOT optimizations by default.
475     FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true);





476   } else {
477     // AOTInvokeDynamicLinking depends on AOTClassLinking.
478     FLAG_SET_ERGO(AOTInvokeDynamicLinking, false);

















479   }
480 





481   if (is_dumping_static_archive()) {
482     if (is_dumping_preimage_static_archive()) {
483       // Don't tweak execution mode
484     } else if (!mode_flag_cmd_line) {
485       // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
486       //
487       // If your classlist is large and you don't care about deterministic dumping, you can use
488       // -Xshare:dump -Xmixed to improve dumping speed.
489       Arguments::set_mode_flags(Arguments::_int);
490     } else if (Arguments::mode() == Arguments::_comp) {
491       // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
492       // Java code, so there's not much benefit in running -Xcomp.
493       log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
494       Arguments::set_mode_flags(Arguments::_mixed);
495     }
496 
497     // String deduplication may cause CDS to iterate the strings in different order from one
498     // run to another which resulting in non-determinstic CDS archives.
499     // Disable UseStringDeduplication while dumping CDS archive.
500     UseStringDeduplication = false;
501 
502     // Don't use SoftReferences so that objects used by java.lang.invoke tables can be archived.
503     Arguments::PropertyList_add(new SystemProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "false", false));
504   }
505 
506   // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit
507   if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) {
508     jio_fprintf(defaultStream::output_stream(),
509                 "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n");
510     return false;
511   }
512 
513   if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
514     disable_dumping_dynamic_archive();
515   } else {
516     enable_dumping_dynamic_archive();
517   }
518 
519   if (AutoCreateSharedArchive) {
520     if (SharedArchiveFile == nullptr) {
521       log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
522       return false;
523     }
524     if (ArchiveClassesAtExit != nullptr) {
525       log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
526       return false;
527     }
528   }
529 
530   if (is_using_archive() && patch_mod_javabase) {
531     Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
532   }
533   if (is_using_archive() && has_unsupported_runtime_module_options()) {
534     UseSharedSpaces = false;
535   }
536 
537   if (is_dumping_archive()) {
538     // Always verify non-system classes during CDS dump
539     if (!BytecodeVerificationRemote) {
540       BytecodeVerificationRemote = true;
541       log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
542     }
543   }
544 











































































































































545   return true;
546 }
547 
548 bool CDSConfig::is_dumping_classic_static_archive() {
549   return _is_dumping_static_archive &&
550     !is_dumping_preimage_static_archive() &&
551     !is_dumping_final_static_archive();
552 }
553 
554 bool CDSConfig::is_dumping_preimage_static_archive() {
555   return _is_dumping_preimage_static_archive;
556 }
557 




558 bool CDSConfig::is_dumping_final_static_archive() {
559   return _is_dumping_final_static_archive;
560 }
561 
562 bool CDSConfig::allow_only_single_java_thread() {
563   // See comments in JVM_StartThread()
564   return is_dumping_classic_static_archive() || is_dumping_final_static_archive();
565 }
566 
































567 bool CDSConfig::is_using_archive() {
568   return UseSharedSpaces;
569 }
570 
571 bool CDSConfig::is_logging_lambda_form_invokers() {
572   return ClassListWriter::is_enabled() || is_dumping_dynamic_archive();
573 }
574 
575 void CDSConfig::stop_using_optimized_module_handling() {
576   _is_using_optimized_module_handling = false;
577   _is_dumping_full_module_graph = false; // This requires is_using_optimized_module_handling()
578   _is_using_full_module_graph = false; // This requires is_using_optimized_module_handling()
579 }
580 
581 
582 CDSConfig::DumperThreadMark::DumperThreadMark(JavaThread* current) {
583   assert(_dumper_thread == nullptr, "sanity");
584   _dumper_thread = current;
585 }
586 
587 CDSConfig::DumperThreadMark::~DumperThreadMark() {
588   assert(_dumper_thread != nullptr, "sanity");
589   _dumper_thread = nullptr;
590 }
591 
592 bool CDSConfig::current_thread_is_vm_or_dumper() {
593   Thread* t = Thread::current();
594   return t != nullptr && (t->is_VM_thread() || t == _dumper_thread);
595 }
596 
597 const char* CDSConfig::type_of_archive_being_loaded() {
598   if (is_dumping_final_static_archive()) {
599     return "AOT configuration file";
600   } else if (new_aot_flags_used()) {
601     return "AOT cache";
602   } else {
603     return "shared archive file";
604   }
605 }
606 
607 const char* CDSConfig::type_of_archive_being_written() {
608   if (is_dumping_preimage_static_archive()) {
609     return "AOT configuration file";
610   } else if (new_aot_flags_used()) {
611     return "AOT cache";
612   } else {
613     return "shared archive file";
614   }
615 }
616 
617 // If an incompatible VM options is found, return a text message that explains why
618 static const char* check_options_incompatible_with_dumping_heap() {
619 #if INCLUDE_CDS_JAVA_HEAP
620   if (!UseCompressedClassPointers) {
621     return "UseCompressedClassPointers must be true";
622   }
623 
624   // Almost all GCs support heap region dump, except ZGC (so far).
625   if (UseZGC) {
626     return "ZGC is not supported";
627   }
628 
629   return nullptr;
630 #else
631   return "JVM not configured for writing Java heap objects";
632 #endif
633 }
634 
635 void CDSConfig::log_reasons_for_not_dumping_heap() {
636   const char* reason;
637 
638   assert(!is_dumping_heap(), "sanity");
639 
640   if (_disable_heap_dumping) {
641     reason = "Programmatically disabled";
642   } else {
643     reason = check_options_incompatible_with_dumping_heap();
644   }
645 
646   assert(reason != nullptr, "sanity");
647   log_info(cds)("Archived java heap is not supported: %s", reason);
648 }
649 
650 #if INCLUDE_CDS_JAVA_HEAP
651 bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() {
652   return check_options_incompatible_with_dumping_heap() != nullptr;
653 }
654 
655 
656 bool CDSConfig::is_dumping_heap() {
657   if (!(is_dumping_classic_static_archive() || is_dumping_final_static_archive())
658       || are_vm_options_incompatible_with_dumping_heap()
659       || _disable_heap_dumping) {
660     return false;
661   }
662   return true;
663 }
664 
665 bool CDSConfig::is_loading_heap() {
666   return ArchiveHeapLoader::is_in_use();
667 }
668 
669 bool CDSConfig::is_using_full_module_graph() {
670   if (ClassLoaderDataShared::is_full_module_graph_loaded()) {
671     return true;
672   }
673 
674   if (!_is_using_full_module_graph) {
675     return false;
676   }
677 
678   if (is_using_archive() && ArchiveHeapLoader::can_use()) {
679     // Classes used by the archived full module graph are loaded in JVMTI early phase.
680     assert(!(JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()),
681            "CDS should be disabled if early class hooks are enabled");
682     return true;
683   } else {
684     _is_using_full_module_graph = false;
685     return false;
686   }
687 }
688 
689 void CDSConfig::stop_dumping_full_module_graph(const char* reason) {
690   if (_is_dumping_full_module_graph) {
691     _is_dumping_full_module_graph = false;
692     if (reason != nullptr) {
693       log_info(cds)("full module graph cannot be dumped: %s", reason);
694     }
695   }
696 }
697 
698 void CDSConfig::stop_using_full_module_graph(const char* reason) {
699   assert(!ClassLoaderDataShared::is_full_module_graph_loaded(), "you call this function too late!");
700   if (_is_using_full_module_graph) {
701     _is_using_full_module_graph = false;
702     if (reason != nullptr) {
703       log_info(cds)("full module graph cannot be loaded: %s", reason);
704     }
705   }
706 }
707 
708 bool CDSConfig::is_dumping_aot_linked_classes() {
709   if (is_dumping_preimage_static_archive()) {
710     return false;
711   } else if (is_dumping_dynamic_archive()) {
712     return is_using_full_module_graph() && AOTClassLinking;
713   } else if (is_dumping_static_archive()) {
714     return is_dumping_full_module_graph() && AOTClassLinking;
715   } else {
716     return false;
717   }
718 }
719 
720 bool CDSConfig::is_using_aot_linked_classes() {





721   // Make sure we have the exact same module graph as in the assembly phase, or else
722   // some aot-linked classes may not be visible so cannot be loaded.
723   return is_using_full_module_graph() && _has_aot_linked_classes;
724 }
725 




726 void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) {
727   _has_aot_linked_classes |= has_aot_linked_classes;
728 }
729 
730 bool CDSConfig::is_initing_classes_at_dump_time() {
731   return is_dumping_heap() && is_dumping_aot_linked_classes();
732 }
733 
734 bool CDSConfig::is_dumping_invokedynamic() {
735   // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap
736   // objects used by the archive indy callsites may be replaced at runtime.
737   return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap();
738 }
739 































740 // When we are dumping aot-linked classes and we are able to write archived heap objects, we automatically
741 // enable the archiving of MethodHandles. This will in turn enable the archiving of MethodTypes and hidden
742 // classes that are used in the implementation of MethodHandles.
743 // Archived MethodHandles are required for higher-level optimizations such as AOT resolution of invokedynamic
744 // and dynamic proxies.
745 bool CDSConfig::is_dumping_method_handles() {
746   return is_initing_classes_at_dump_time();
747 }
748 
749 #endif // INCLUDE_CDS_JAVA_HEAP
























--- EOF ---