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::_has_archived_invokedynamic = false;
 51 bool CDSConfig::_old_cds_flags_used = false;
 52 bool CDSConfig::_new_aot_flags_used = false;
 53 bool CDSConfig::_disable_heap_dumping = false;
 54 
 55 char* CDSConfig::_default_archive_path = nullptr;
 56 char* CDSConfig::_static_archive_path = nullptr;
 57 char* CDSConfig::_dynamic_archive_path = nullptr;
 58 
 59 JavaThread* CDSConfig::_dumper_thread = nullptr;
 60 
 61 int CDSConfig::get_status() {
 62   assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized");
 63   return (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
 64          (is_dumping_static_archive()       ? IS_DUMPING_STATIC_ARCHIVE : 0) |
 65          (is_logging_lambda_form_invokers() ? IS_LOGGING_LAMBDA_FORM_INVOKERS : 0) |
 66          (is_using_archive()                ? IS_USING_ARCHIVE : 0);
 67 }
 68 
 69 void CDSConfig::initialize() {
 70   if (is_dumping_static_archive() && !is_dumping_final_static_archive()) {
 71     if (RequireSharedSpaces) {
 72       warning("Cannot dump shared archive while using shared archive");
 73     }
 74     UseSharedSpaces = false;
 75   }
 76 
 77   // Initialize shared archive paths which could include both base and dynamic archive paths
 78   // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
 79   //
 80   // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
 81   if (is_dumping_static_archive() || is_using_archive()) {
 82     init_shared_archive_paths();
 83   }
 84 
 85   if (!is_dumping_heap()) {
 86     _is_dumping_full_module_graph = false;
 87   }
 88 }
 89 
 90 char* CDSConfig::default_archive_path() {
 91   if (_default_archive_path == nullptr) {
 92     char jvm_path[JVM_MAXPATHLEN];
 93     os::jvm_path(jvm_path, sizeof(jvm_path));
 94     char *end = strrchr(jvm_path, *os::file_separator());
 95     if (end != nullptr) *end = '\0';
 96     stringStream tmp;
 97     tmp.print("%s%sclasses", jvm_path, os::file_separator());
 98 #ifdef _LP64
 99     if (!UseCompressedOops) {
100       tmp.print_raw("_nocoops");
101     }
102     if (UseCompactObjectHeaders) {
103       // Note that generation of xxx_coh.jsa variants require
104       // --enable-cds-archive-coh at build time
105       tmp.print_raw("_coh");
106     }
107 #endif
108     tmp.print_raw(".jsa");
109     _default_archive_path = os::strdup(tmp.base());
110   }
111   return _default_archive_path;
112 }
113 
114 int CDSConfig::num_archives(const char* archive_path) {
115   if (archive_path == nullptr) {
116     return 0;
117   }
118   int npaths = 1;
119   char* p = (char*)archive_path;
120   while (*p != '\0') {
121     if (*p == os::path_separator()[0]) {
122       npaths++;
123     }
124     p++;
125   }
126   return npaths;
127 }
128 
129 void CDSConfig::extract_shared_archive_paths(const char* archive_path,
130                                              char** base_archive_path,
131                                              char** top_archive_path) {
132   char* begin_ptr = (char*)archive_path;
133   char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
134   if (end_ptr == nullptr || end_ptr == begin_ptr) {
135     vm_exit_during_initialization("Base archive was not specified", archive_path);
136   }
137   size_t len = end_ptr - begin_ptr;
138   char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
139   strncpy(cur_path, begin_ptr, len);
140   cur_path[len] = '\0';
141   *base_archive_path = cur_path;
142 
143   begin_ptr = ++end_ptr;
144   if (*begin_ptr == '\0') {
145     vm_exit_during_initialization("Top archive was not specified", archive_path);
146   }
147   end_ptr = strchr(begin_ptr, '\0');
148   assert(end_ptr != nullptr, "sanity");
149   len = end_ptr - begin_ptr;
150   cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
151   strncpy(cur_path, begin_ptr, len + 1);
152   *top_archive_path = cur_path;
153 }
154 
155 void CDSConfig::init_shared_archive_paths() {
156   if (ArchiveClassesAtExit != nullptr) {
157     assert(!RecordDynamicDumpInfo, "already checked");
158     if (is_dumping_static_archive()) {
159       vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
160     }
161     check_unsupported_dumping_module_options();
162 
163     if (os::same_files(default_archive_path(), ArchiveClassesAtExit)) {
164       vm_exit_during_initialization(
165         "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", default_archive_path());
166     }
167   }
168 
169   if (SharedArchiveFile == nullptr) {
170     _static_archive_path = default_archive_path();
171   } else {
172     int archives = num_archives(SharedArchiveFile);
173     assert(archives > 0, "must be");
174 
175     if (is_dumping_archive() && archives > 1) {
176       vm_exit_during_initialization(
177         "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
178     }
179 
180     if (is_dumping_static_archive()) {
181       assert(archives == 1, "must be");
182       // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file
183       // will be overwritten no matter regardless of its contents
184       _static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
185     } else {
186       // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa
187       // is read from top.jsa
188       //    (a) 1 file:  -XX:SharedArchiveFile=base.jsa
189       //    (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa
190       //    (c) 2 files: -XX:SharedArchiveFile=top.jsa
191       //
192       // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not
193       // allow cases (b) and (c). Case (b) is already checked above.
194 
195       if (archives > 2) {
196         vm_exit_during_initialization(
197           "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
198       }
199       if (archives == 1) {
200         char* base_archive_path = nullptr;
201         bool success =
202           FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
203         if (!success) {
204           // If +AutoCreateSharedArchive and the specified shared archive does not exist,
205           // regenerate the dynamic archive base on default archive.
206           if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) {
207             enable_dumping_dynamic_archive();
208             ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile);
209             _static_archive_path = default_archive_path();
210             SharedArchiveFile = nullptr;
211           } else {
212             if (AutoCreateSharedArchive) {
213               warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.");
214               AutoCreateSharedArchive = false;
215             }
216             log_error(cds)("Not a valid %s (%s)", new_aot_flags_used() ? "AOT cache" : "archive", SharedArchiveFile);
217             Arguments::no_shared_spaces("invalid archive");
218           }
219         } else if (base_archive_path == nullptr) {
220           // User has specified a single archive, which is a static archive.
221           _static_archive_path = const_cast<char *>(SharedArchiveFile);
222         } else {
223           // User has specified a single archive, which is a dynamic archive.
224           _dynamic_archive_path = const_cast<char *>(SharedArchiveFile);
225           _static_archive_path = base_archive_path; // has been c-heap allocated.
226         }
227       } else {
228         extract_shared_archive_paths((const char*)SharedArchiveFile,
229                                       &_static_archive_path, &_dynamic_archive_path);
230         if (_static_archive_path == nullptr) {
231           assert(_dynamic_archive_path == nullptr, "must be");
232           Arguments::no_shared_spaces("invalid archive");
233         }
234       }
235 
236       if (_dynamic_archive_path != nullptr) {
237         // Check for case (c)
238         if (RecordDynamicDumpInfo) {
239           vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
240                                         SharedArchiveFile);
241         }
242         if (ArchiveClassesAtExit != nullptr) {
243           vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
244                                         SharedArchiveFile);
245         }
246       }
247 
248       if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
249           vm_exit_during_initialization(
250             "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
251             SharedArchiveFile);
252       }
253     }
254   }
255 }
256 
257 void CDSConfig::check_internal_module_property(const char* key, const char* value) {
258   if (Arguments::is_incompatible_cds_internal_module_property(key)) {
259     stop_using_optimized_module_handling();
260     log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
261   }
262 }
263 
264 void CDSConfig::check_incompatible_property(const char* key, const char* value) {
265   static const char* incompatible_properties[] = {
266     "java.system.class.loader",
267     "jdk.module.showModuleResolution",
268     "jdk.module.validation"
269   };
270 
271   for (const char* property : incompatible_properties) {
272     if (strcmp(key, property) == 0) {
273       stop_dumping_full_module_graph();
274       stop_using_full_module_graph();
275       log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
276       break;
277     }
278   }
279 
280 }
281 
282 // Returns any JVM command-line option, such as "--patch-module", that's not supported by CDS.
283 static const char* find_any_unsupported_module_option() {
284   // Note that arguments.cpp has translated the command-line options into properties. If we find an
285   // unsupported property, translate it back to its command-line option for better error reporting.
286 
287   // The following properties are checked by Arguments::is_internal_module_property() and cannot be
288   // directly specified in the command-line.
289   static const char* unsupported_module_properties[] = {
290     "jdk.module.limitmods",
291     "jdk.module.upgrade.path",
292     "jdk.module.patch.0"
293   };
294   static const char* unsupported_module_options[] = {
295     "--limit-modules",
296     "--upgrade-module-path",
297     "--patch-module"
298   };
299 
300   assert(ARRAY_SIZE(unsupported_module_properties) == ARRAY_SIZE(unsupported_module_options), "must be");
301   SystemProperty* sp = Arguments::system_properties();
302   while (sp != nullptr) {
303     for (uint i = 0; i < ARRAY_SIZE(unsupported_module_properties); i++) {
304       if (strcmp(sp->key(), unsupported_module_properties[i]) == 0) {
305         return unsupported_module_options[i];
306       }
307     }
308     sp = sp->next();
309   }
310 
311   return nullptr; // not found
312 }
313 
314 void CDSConfig::check_unsupported_dumping_module_options() {
315   assert(is_dumping_archive(), "this function is only used with CDS dump time");
316   const char* option = find_any_unsupported_module_option();
317   if (option != nullptr) {
318     vm_exit_during_initialization("Cannot use the following option when dumping the shared archive", option);
319   }
320   // Check for an exploded module build in use with -Xshare:dump.
321   if (!Arguments::has_jimage()) {
322     vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
323   }
324 }
325 
326 bool CDSConfig::has_unsupported_runtime_module_options() {
327   assert(is_using_archive(), "this function is only used with -Xshare:{on,auto}");
328   if (ArchiveClassesAtExit != nullptr) {
329     // dynamic dumping, just return false for now.
330     // check_unsupported_dumping_properties() will be called later to check the same set of
331     // properties, and will exit the VM with the correct error message if the unsupported properties
332     // are used.
333     return false;
334   }
335   const char* option = find_any_unsupported_module_option();
336   if (option != nullptr) {
337     if (RequireSharedSpaces) {
338       warning("CDS is disabled when the %s option is specified.", option);
339     } else {
340       if (new_aot_flags_used()) {
341         log_warning(cds)("AOT cache is disabled when the %s option is specified.", option);
342       } else {
343         log_info(cds)("CDS is disabled when the %s option is specified.", option);
344       }
345     }
346     return true;
347   }
348   return false;
349 }
350 
351 #define CHECK_ALIAS(f) check_flag_alias(FLAG_IS_DEFAULT(f), #f)
352 
353 void CDSConfig::check_flag_alias(bool alias_is_default, const char* alias_name) {
354   if (old_cds_flags_used() && !alias_is_default) {
355     vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with "
356                                           "-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, "
357                                           "DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile",
358                                           alias_name));
359   }
360 }
361 
362 void CDSConfig::check_aot_flags() {
363   if (!FLAG_IS_DEFAULT(DumpLoadedClassList) ||
364       !FLAG_IS_DEFAULT(SharedClassListFile) ||
365       !FLAG_IS_DEFAULT(SharedArchiveFile)) {
366     _old_cds_flags_used = true;
367   }
368 
369   CHECK_ALIAS(AOTCache);
370   CHECK_ALIAS(AOTConfiguration);
371   CHECK_ALIAS(AOTMode);
372 
373   if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) {
374     // AOTCache/AOTConfiguration/AOTMode not used.
375     return;
376   } else {
377     _new_aot_flags_used = true;
378   }
379 
380   if (FLAG_IS_DEFAULT(AOTMode) || strcmp(AOTMode, "auto") == 0 || strcmp(AOTMode, "on") == 0) {
381     check_aotmode_auto_or_on();
382   } else if (strcmp(AOTMode, "off") == 0) {
383     check_aotmode_off();
384   } else {
385     // AOTMode is record or create
386     if (FLAG_IS_DEFAULT(AOTConfiguration)) {
387       vm_exit_during_initialization(err_msg("-XX:AOTMode=%s cannot be used without setting AOTConfiguration", AOTMode));
388     }
389 
390     if (strcmp(AOTMode, "record") == 0) {
391       check_aotmode_record();
392     } else {
393       assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc");
394       check_aotmode_create();
395     }
396   }
397 }
398 
399 void CDSConfig::check_aotmode_off() {
400   UseSharedSpaces = false;
401   RequireSharedSpaces = false;
402 }
403 
404 void CDSConfig::check_aotmode_auto_or_on() {
405   if (!FLAG_IS_DEFAULT(AOTConfiguration)) {
406     vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create");
407   }
408 
409   if (!FLAG_IS_DEFAULT(AOTCache)) {
410     assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
411     FLAG_SET_ERGO(SharedArchiveFile, AOTCache);
412   }
413 
414   UseSharedSpaces = true;
415   if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) {
416     RequireSharedSpaces = false;
417   } else {
418     assert(strcmp(AOTMode, "on") == 0, "already checked");
419     RequireSharedSpaces = true;
420   }
421 }
422 
423 void CDSConfig::check_aotmode_record() {
424   if (!FLAG_IS_DEFAULT(AOTCache)) {
425     vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record");
426   }
427 
428   assert(FLAG_IS_DEFAULT(DumpLoadedClassList), "already checked");
429   assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
430   FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
431   FLAG_SET_ERGO(DumpLoadedClassList, nullptr);
432   UseSharedSpaces = false;
433   RequireSharedSpaces = false;
434   _is_dumping_static_archive = true;
435   _is_dumping_preimage_static_archive = true;
436 
437   // At VM exit, the module graph may be contaminated with program states.
438   // We will rebuild the module graph when dumping the CDS final image.
439   disable_heap_dumping();
440 }
441 
442 void CDSConfig::check_aotmode_create() {
443   if (FLAG_IS_DEFAULT(AOTCache)) {
444     vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create");
445   }
446 
447   assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
448 
449   _is_dumping_final_static_archive = true;
450   FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
451   UseSharedSpaces = true;
452   RequireSharedSpaces = true;
453 
454   if (!FileMapInfo::is_preimage_static_archive(AOTConfiguration)) {
455     vm_exit_during_initialization("Must be a valid AOT configuration generated by the current JVM", AOTConfiguration);
456   }
457 
458   CDSConfig::enable_dumping_static_archive();
459 }
460 
461 bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) {
462   check_aot_flags();
463 
464   if (!FLAG_IS_DEFAULT(AOTMode)) {
465     // Using any form of the new AOTMode switch enables enhanced optimizations.
466     FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true);
467   }
468 
469   if (AOTClassLinking) {
470     // If AOTClassLinking is specified, enable all AOT optimizations by default.
471     FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true);
472   } else {
473     // AOTInvokeDynamicLinking depends on AOTClassLinking.
474     FLAG_SET_ERGO(AOTInvokeDynamicLinking, false);
475   }
476 
477   if (is_dumping_static_archive()) {
478     if (is_dumping_preimage_static_archive()) {
479       // Don't tweak execution mode
480     } else if (!mode_flag_cmd_line) {
481       // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
482       //
483       // If your classlist is large and you don't care about deterministic dumping, you can use
484       // -Xshare:dump -Xmixed to improve dumping speed.
485       Arguments::set_mode_flags(Arguments::_int);
486     } else if (Arguments::mode() == Arguments::_comp) {
487       // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
488       // Java code, so there's not much benefit in running -Xcomp.
489       log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
490       Arguments::set_mode_flags(Arguments::_mixed);
491     }
492 
493     // String deduplication may cause CDS to iterate the strings in different order from one
494     // run to another which resulting in non-determinstic CDS archives.
495     // Disable UseStringDeduplication while dumping CDS archive.
496     UseStringDeduplication = false;
497 
498     // Don't use SoftReferences so that objects used by java.lang.invoke tables can be archived.
499     Arguments::PropertyList_add(new SystemProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "false", false));
500   }
501 
502   // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit
503   if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) {
504     jio_fprintf(defaultStream::output_stream(),
505                 "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n");
506     return false;
507   }
508 
509   if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
510     disable_dumping_dynamic_archive();
511   } else {
512     enable_dumping_dynamic_archive();
513   }
514 
515   if (AutoCreateSharedArchive) {
516     if (SharedArchiveFile == nullptr) {
517       log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
518       return false;
519     }
520     if (ArchiveClassesAtExit != nullptr) {
521       log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
522       return false;
523     }
524   }
525 
526   if (is_using_archive() && patch_mod_javabase) {
527     Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
528   }
529   if (is_using_archive() && has_unsupported_runtime_module_options()) {
530     UseSharedSpaces = false;
531   }
532 
533   if (is_dumping_archive()) {
534     // Always verify non-system classes during CDS dump
535     if (!BytecodeVerificationRemote) {
536       BytecodeVerificationRemote = true;
537       log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
538     }
539   }
540 
541   return true;
542 }
543 
544 bool CDSConfig::is_dumping_classic_static_archive() {
545   return _is_dumping_static_archive &&
546     !is_dumping_preimage_static_archive() &&
547     !is_dumping_final_static_archive();
548 }
549 
550 bool CDSConfig::is_dumping_preimage_static_archive() {
551   return _is_dumping_preimage_static_archive;
552 }
553 
554 bool CDSConfig::is_dumping_final_static_archive() {
555   return _is_dumping_final_static_archive;
556 }
557 
558 bool CDSConfig::allow_only_single_java_thread() {
559   // See comments in JVM_StartThread()
560   return is_dumping_static_archive();
561 }
562 
563 bool CDSConfig::is_using_archive() {
564   return UseSharedSpaces;
565 }
566 
567 bool CDSConfig::is_logging_lambda_form_invokers() {
568   return ClassListWriter::is_enabled() || is_dumping_dynamic_archive();
569 }
570 
571 void CDSConfig::stop_using_optimized_module_handling() {
572   _is_using_optimized_module_handling = false;
573   _is_dumping_full_module_graph = false; // This requires is_using_optimized_module_handling()
574   _is_using_full_module_graph = false; // This requires is_using_optimized_module_handling()
575 }
576 
577 
578 CDSConfig::DumperThreadMark::DumperThreadMark(JavaThread* current) {
579   assert(_dumper_thread == nullptr, "sanity");
580   _dumper_thread = current;
581 }
582 
583 CDSConfig::DumperThreadMark::~DumperThreadMark() {
584   assert(_dumper_thread != nullptr, "sanity");
585   _dumper_thread = nullptr;
586 }
587 
588 bool CDSConfig::current_thread_is_vm_or_dumper() {
589   Thread* t = Thread::current();
590   return t != nullptr && (t->is_VM_thread() || t == _dumper_thread);
591 }
592 
593 const char* CDSConfig::type_of_archive_being_loaded() {
594   if (is_dumping_final_static_archive()) {
595     return "AOT configuration file";
596   } else if (new_aot_flags_used()) {
597     return "AOT cache";
598   } else {
599     return "shared archive file";
600   }
601 }
602 
603 const char* CDSConfig::type_of_archive_being_written() {
604   if (is_dumping_preimage_static_archive()) {
605     return "AOT configuration file";
606   } else if (new_aot_flags_used()) {
607     return "AOT cache";
608   } else {
609     return "shared archive file";
610   }
611 }
612 
613 // If an incompatible VM options is found, return a text message that explains why
614 static const char* check_options_incompatible_with_dumping_heap() {
615 #if INCLUDE_CDS_JAVA_HEAP
616   if (!UseCompressedClassPointers) {
617     return "UseCompressedClassPointers must be true";
618   }
619 
620   // Almost all GCs support heap region dump, except ZGC (so far).
621   if (UseZGC) {
622     return "ZGC is not supported";
623   }
624 
625   return nullptr;
626 #else
627   return "JVM not configured for writing Java heap objects";
628 #endif
629 }
630 
631 void CDSConfig::log_reasons_for_not_dumping_heap() {
632   const char* reason;
633 
634   assert(!is_dumping_heap(), "sanity");
635 
636   if (_disable_heap_dumping) {
637     reason = "Programmatically disabled";
638   } else {
639     reason = check_options_incompatible_with_dumping_heap();
640   }
641 
642   assert(reason != nullptr, "sanity");
643   log_info(cds)("Archived java heap is not supported: %s", reason);
644 }
645 
646 #if INCLUDE_CDS_JAVA_HEAP
647 bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() {
648   return check_options_incompatible_with_dumping_heap() != nullptr;
649 }
650 
651 
652 bool CDSConfig::is_dumping_heap() {
653   if (!(is_dumping_classic_static_archive() || is_dumping_final_static_archive())
654       || are_vm_options_incompatible_with_dumping_heap()
655       || _disable_heap_dumping) {
656     return false;
657   }
658   return true;
659 }
660 
661 bool CDSConfig::is_loading_heap() {
662   return ArchiveHeapLoader::is_in_use();
663 }
664 
665 bool CDSConfig::is_using_full_module_graph() {
666   if (ClassLoaderDataShared::is_full_module_graph_loaded()) {
667     return true;
668   }
669 
670   if (!_is_using_full_module_graph) {
671     return false;
672   }
673 
674   if (is_using_archive() && ArchiveHeapLoader::can_use()) {
675     // Classes used by the archived full module graph are loaded in JVMTI early phase.
676     assert(!(JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()),
677            "CDS should be disabled if early class hooks are enabled");
678     return true;
679   } else {
680     _is_using_full_module_graph = false;
681     return false;
682   }
683 }
684 
685 void CDSConfig::stop_dumping_full_module_graph(const char* reason) {
686   if (_is_dumping_full_module_graph) {
687     _is_dumping_full_module_graph = false;
688     if (reason != nullptr) {
689       log_info(cds)("full module graph cannot be dumped: %s", reason);
690     }
691   }
692 }
693 
694 void CDSConfig::stop_using_full_module_graph(const char* reason) {
695   assert(!ClassLoaderDataShared::is_full_module_graph_loaded(), "you call this function too late!");
696   if (_is_using_full_module_graph) {
697     _is_using_full_module_graph = false;
698     if (reason != nullptr) {
699       log_info(cds)("full module graph cannot be loaded: %s", reason);
700     }
701   }
702 }
703 
704 bool CDSConfig::is_dumping_aot_linked_classes() {
705   if (is_dumping_preimage_static_archive()) {
706     return false;
707   } else if (is_dumping_dynamic_archive()) {
708     return is_using_full_module_graph() && AOTClassLinking;
709   } else if (is_dumping_static_archive()) {
710     return is_dumping_full_module_graph() && AOTClassLinking;
711   } else {
712     return false;
713   }
714 }
715 
716 bool CDSConfig::is_using_aot_linked_classes() {
717   // Make sure we have the exact same module graph as in the assembly phase, or else
718   // some aot-linked classes may not be visible so cannot be loaded.
719   return is_using_full_module_graph() && _has_aot_linked_classes;
720 }
721 
722 void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) {
723   _has_aot_linked_classes |= has_aot_linked_classes;
724 }
725 
726 bool CDSConfig::is_initing_classes_at_dump_time() {
727   return is_dumping_heap() && is_dumping_aot_linked_classes();
728 }
729 
730 bool CDSConfig::is_dumping_invokedynamic() {
731   // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap
732   // objects used by the archive indy callsites may be replaced at runtime.
733   return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap();
734 }
735 
736 bool CDSConfig::is_loading_invokedynamic() {
737   return UseSharedSpaces && is_using_full_module_graph() && _has_archived_invokedynamic;
738 }
739 
740 #endif // INCLUDE_CDS_JAVA_HEAP