< prev index next >

src/hotspot/share/cds/cdsConfig.cpp

Print this page

  1 /*
  2  * Copyright (c) 2023, 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 "precompiled.hpp"
 26 #include "cds/archiveHeapLoader.hpp"
 27 #include "cds/cdsConfig.hpp"
 28 #include "cds/heapShared.hpp"
 29 #include "classfile/classLoaderDataShared.hpp"
 30 #include "classfile/moduleEntry.hpp"
 31 #include "include/jvm_io.h"
 32 #include "logging/log.hpp"
 33 #include "runtime/arguments.hpp"

 34 #include "runtime/java.hpp"
 35 #include "utilities/defaultStream.hpp"
 36 
 37 bool CDSConfig::_is_dumping_static_archive = false;
 38 bool CDSConfig::_is_dumping_dynamic_archive = false;
 39 
 40 // The ability to dump the FMG depends on many factors checked by
 41 // is_dumping_full_module_graph(), but can be unconditionally disabled by
 42 // _dumping_full_module_graph_disabled. (Ditto for loading the FMG).
 43 bool CDSConfig::_dumping_full_module_graph_disabled = false;
 44 bool CDSConfig::_loading_full_module_graph_disabled = false;
 45 








 46 char* CDSConfig::_default_archive_path = nullptr;
 47 char* CDSConfig::_static_archive_path = nullptr;
 48 char* CDSConfig::_dynamic_archive_path = nullptr;
 49 
 50 void CDSConfig::initialize() {
 51   if (is_dumping_static_archive()) {
 52     if (RequireSharedSpaces) {
 53       warning("Cannot dump shared archive while using shared archive");
 54     }
 55     UseSharedSpaces = false;
 56   }
 57 
 58   // Initialize shared archive paths which could include both base and dynamic archive paths
 59   // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
 60   //
 61   // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
 62   if (is_dumping_static_archive() || UseSharedSpaces) {
 63     init_shared_archive_paths();
 64   }
 65 }
 66 
 67 char* CDSConfig::default_archive_path() {
 68   if (_default_archive_path == nullptr) {
 69     char jvm_path[JVM_MAXPATHLEN];
 70     os::jvm_path(jvm_path, sizeof(jvm_path));
 71     char *end = strrchr(jvm_path, *os::file_separator());
 72     if (end != nullptr) *end = '\0';
 73     size_t jvm_path_len = strlen(jvm_path);
 74     size_t file_sep_len = strlen(os::file_separator());
 75     const size_t len = jvm_path_len + file_sep_len + 20;
 76     _default_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments);
 77     jio_snprintf(_default_archive_path, len,
 78                 LP64_ONLY(!UseCompressedOops ? "%s%sclasses_nocoops.jsa":) "%s%sclasses.jsa",
 79                 jvm_path, os::file_separator());




 80   }
 81   return _default_archive_path;
 82 }
 83 
 84 int CDSConfig::num_archives(const char* archive_path) {
 85   if (archive_path == nullptr) {
 86     return 0;
 87   }
 88   int npaths = 1;
 89   char* p = (char*)archive_path;
 90   while (*p != '\0') {
 91     if (*p == os::path_separator()[0]) {
 92       npaths++;
 93     }
 94     p++;
 95   }
 96   return npaths;
 97 }
 98 
 99 void CDSConfig::extract_shared_archive_paths(const char* archive_path,

223   }
224 }
225 
226 void CDSConfig::check_system_property(const char* key, const char* value) {
227   if (Arguments::is_internal_module_property(key)) {
228     MetaspaceShared::disable_optimized_module_handling();
229     log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
230   }
231   if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
232       strcmp(key, "jdk.module.validation") == 0 ||
233       strcmp(key, "java.system.class.loader") == 0) {
234     disable_loading_full_module_graph();
235     disable_dumping_full_module_graph();
236     log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
237   }
238 }
239 
240 static const char* unsupported_properties[] = {
241   "jdk.module.limitmods",
242   "jdk.module.upgrade.path",
243   "jdk.module.patch.0"
244 };
245 static const char* unsupported_options[] = {
246   "--limit-modules",
247   "--upgrade-module-path",
248   "--patch-module"
249 };
250 
251 void CDSConfig::check_unsupported_dumping_properties() {
252   assert(is_dumping_archive(), "this function is only used with CDS dump time");
253   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
254   // If a vm option is found in the unsupported_options array, vm will exit with an error message.
255   SystemProperty* sp = Arguments::system_properties();
256   while (sp != nullptr) {
257     for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
258       if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
259         vm_exit_during_initialization(
260           "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
261       }
262     }
263     sp = sp->next();
264   }
265 






266   // Check for an exploded module build in use with -Xshare:dump.
267   if (!Arguments::has_jimage()) {
268     vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
269   }
270 }
271 
272 bool CDSConfig::check_unsupported_cds_runtime_properties() {
273   assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}");
274   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
275   if (ArchiveClassesAtExit != nullptr) {
276     // dynamic dumping, just return false for now.
277     // check_unsupported_dumping_properties() will be called later to check the same set of
278     // properties, and will exit the VM with the correct error message if the unsupported properties
279     // are used.
280     return false;
281   }
282   for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
283     if (Arguments::get_property(unsupported_properties[i]) != nullptr) {
284       if (RequireSharedSpaces) {
285         warning("CDS is disabled when the %s option is specified.", unsupported_options[i]);
286       } else {
287         log_info(cds)("CDS is disabled when the %s option is specified.", unsupported_options[i]);
288       }
289       return true;
290     }
291   }










292   return false;
293 }
294 
295 bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase,  bool mode_flag_cmd_line) {
296   if (is_dumping_static_archive()) {
297     if (!mode_flag_cmd_line) {
298       // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
299       //
300       // If your classlist is large and you don't care about deterministic dumping, you can use
301       // -Xshare:dump -Xmixed to improve dumping speed.
302       Arguments::set_mode_flags(Arguments::_int);
303     } else if (Arguments::mode() == Arguments::_comp) {
304       // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
305       // Java code, so there's not much benefit in running -Xcomp.
306       log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
307       Arguments::set_mode_flags(Arguments::_mixed);
308     }
309 
310     // String deduplication may cause CDS to iterate the strings in different order from one
311     // run to another which resulting in non-determinstic CDS archives.
312     // Disable UseStringDeduplication while dumping CDS archive.
313     UseStringDeduplication = false;
314   }
315 

320     return false;
321   }
322 
323   if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
324     disable_dumping_dynamic_archive();
325   } else {
326     enable_dumping_dynamic_archive();
327   }
328 
329   if (AutoCreateSharedArchive) {
330     if (SharedArchiveFile == nullptr) {
331       log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
332       return false;
333     }
334     if (ArchiveClassesAtExit != nullptr) {
335       log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
336       return false;
337     }
338   }
339 
340   if (UseSharedSpaces && patch_mod_javabase) {
341     Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
342   }
343   if (UseSharedSpaces && check_unsupported_cds_runtime_properties()) {
344     UseSharedSpaces = false;
345   }
346 
347   if (is_dumping_archive()) {
348     // Always verify non-system classes during CDS dump
349     if (!BytecodeVerificationRemote) {
350       BytecodeVerificationRemote = true;
351       log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
352     }
353   }
354 
355   return true;
356 }
357 
358 #if INCLUDE_CDS_JAVA_HEAP
359 bool CDSConfig::is_dumping_heap() {




360   // heap dump is not supported in dynamic dump
361   return is_dumping_static_archive() && HeapShared::can_write();
362 }
363 
364 bool CDSConfig::is_dumping_full_module_graph() {
365   if (!_dumping_full_module_graph_disabled &&
366       is_dumping_heap() &&
367       MetaspaceShared::use_optimized_module_handling()) {
368     return true;
369   } else {
370     return false;
371   }
372 }
373 
374 bool CDSConfig::is_loading_full_module_graph() {
375   if (ClassLoaderDataShared::is_full_module_graph_loaded()) {
376     return true;
377   }
378 
379   if (!_loading_full_module_graph_disabled &&

  1 /*
  2  * Copyright (c) 2023, 2024, 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 "precompiled.hpp"
 26 #include "cds/archiveHeapLoader.hpp"
 27 #include "cds/cdsConfig.hpp"
 28 #include "cds/heapShared.hpp"
 29 #include "classfile/classLoaderDataShared.hpp"
 30 #include "classfile/moduleEntry.hpp"
 31 #include "include/jvm_io.h"
 32 #include "logging/log.hpp"
 33 #include "runtime/arguments.hpp"
 34 #include "runtime/globals.hpp"
 35 #include "runtime/java.hpp"
 36 #include "utilities/defaultStream.hpp"
 37 
 38 bool CDSConfig::_is_dumping_static_archive = false;
 39 bool CDSConfig::_is_dumping_dynamic_archive = false;
 40 
 41 // The ability to dump the FMG depends on many factors checked by
 42 // is_dumping_full_module_graph(), but can be unconditionally disabled by
 43 // _dumping_full_module_graph_disabled. (Ditto for loading the FMG).
 44 bool CDSConfig::_dumping_full_module_graph_disabled = false;
 45 bool CDSConfig::_loading_full_module_graph_disabled = false;
 46 
 47 bool CDSConfig::_module_patching_disables_cds = false;
 48 bool CDSConfig::_java_base_module_patching_disables_cds = false;
 49 
 50 bool CDSConfig::is_valhalla_preview() {
 51   return Arguments::enable_preview() && EnableValhalla;
 52 }
 53 
 54 
 55 char* CDSConfig::_default_archive_path = nullptr;
 56 char* CDSConfig::_static_archive_path = nullptr;
 57 char* CDSConfig::_dynamic_archive_path = nullptr;
 58 
 59 void CDSConfig::initialize() {
 60   if (is_dumping_static_archive()) {
 61     if (RequireSharedSpaces) {
 62       warning("Cannot dump shared archive while using shared archive");
 63     }
 64     UseSharedSpaces = false;
 65   }
 66 
 67   // Initialize shared archive paths which could include both base and dynamic archive paths
 68   // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
 69   //
 70   // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
 71   if (is_dumping_static_archive() || UseSharedSpaces) {
 72     init_shared_archive_paths();
 73   }
 74 }
 75 
 76 char* CDSConfig::default_archive_path() {
 77   if (_default_archive_path == nullptr) {
 78     char jvm_path[JVM_MAXPATHLEN];
 79     os::jvm_path(jvm_path, sizeof(jvm_path));
 80     char *end = strrchr(jvm_path, *os::file_separator());
 81     if (end != nullptr) *end = '\0';
 82     size_t jvm_path_len = strlen(jvm_path);
 83     size_t file_sep_len = strlen(os::file_separator());
 84     const size_t len = jvm_path_len + file_sep_len + strlen("classes_nocoops_valhalla.jsa") + 1;
 85     _default_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments);
 86     LP64_ONLY(bool nocoops = !UseCompressedOops);
 87     NOT_LP64(bool nocoops = false);
 88     bool valhalla = is_valhalla_preview();
 89     jio_snprintf(_default_archive_path, len, "%s%sclasses%s%s.jsa",
 90                 jvm_path, os::file_separator(),
 91                  nocoops ? "_nocoops" : "",
 92                  valhalla ? "_valhalla" : "");
 93   }
 94   return _default_archive_path;
 95 }
 96 
 97 int CDSConfig::num_archives(const char* archive_path) {
 98   if (archive_path == nullptr) {
 99     return 0;
100   }
101   int npaths = 1;
102   char* p = (char*)archive_path;
103   while (*p != '\0') {
104     if (*p == os::path_separator()[0]) {
105       npaths++;
106     }
107     p++;
108   }
109   return npaths;
110 }
111 
112 void CDSConfig::extract_shared_archive_paths(const char* archive_path,

236   }
237 }
238 
239 void CDSConfig::check_system_property(const char* key, const char* value) {
240   if (Arguments::is_internal_module_property(key)) {
241     MetaspaceShared::disable_optimized_module_handling();
242     log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
243   }
244   if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
245       strcmp(key, "jdk.module.validation") == 0 ||
246       strcmp(key, "java.system.class.loader") == 0) {
247     disable_loading_full_module_graph();
248     disable_dumping_full_module_graph();
249     log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
250   }
251 }
252 
253 static const char* unsupported_properties[] = {
254   "jdk.module.limitmods",
255   "jdk.module.upgrade.path",

256 };
257 static const char* unsupported_options[] = {
258   "--limit-modules",
259   "--upgrade-module-path",

260 };
261 
262 void CDSConfig::check_unsupported_dumping_properties() {
263   assert(is_dumping_archive(), "this function is only used with CDS dump time");
264   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
265   // If a vm option is found in the unsupported_options array, vm will exit with an error message.
266   SystemProperty* sp = Arguments::system_properties();
267   while (sp != nullptr) {
268     for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
269       if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
270         vm_exit_during_initialization(
271           "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
272       }
273     }
274     sp = sp->next();
275   }
276 
277   if (module_patching_disables_cds()) {
278     vm_exit_during_initialization(
279             "Cannot use the following option when dumping the shared archive", "--patch-module");
280   }
281 
282 
283   // Check for an exploded module build in use with -Xshare:dump.
284   if (!Arguments::has_jimage()) {
285     vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
286   }
287 }
288 
289 bool CDSConfig::check_unsupported_cds_runtime_properties() {
290   assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}");
291   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
292   if (ArchiveClassesAtExit != nullptr) {
293     // dynamic dumping, just return false for now.
294     // check_unsupported_dumping_properties() will be called later to check the same set of
295     // properties, and will exit the VM with the correct error message if the unsupported properties
296     // are used.
297     return false;
298   }
299   for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
300     if (Arguments::get_property(unsupported_properties[i]) != nullptr) {
301       if (RequireSharedSpaces) {
302         warning("CDS is disabled when the %s option is specified.", unsupported_options[i]);
303       } else {
304         log_info(cds)("CDS is disabled when the %s option is specified.", unsupported_options[i]);
305       }
306       return true;
307     }
308   }
309 
310   if (module_patching_disables_cds()) {
311     if (RequireSharedSpaces) {
312       warning("CDS is disabled when the %s option is specified.", "--patch-module");
313     } else {
314       log_info(cds)("CDS is disabled when the %s option is specified.", "--patch-module");
315     }
316     return true;
317   }
318 
319   return false;
320 }
321 
322 bool CDSConfig::check_vm_args_consistency(bool mode_flag_cmd_line) {
323   if (is_dumping_static_archive()) {
324     if (!mode_flag_cmd_line) {
325       // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
326       //
327       // If your classlist is large and you don't care about deterministic dumping, you can use
328       // -Xshare:dump -Xmixed to improve dumping speed.
329       Arguments::set_mode_flags(Arguments::_int);
330     } else if (Arguments::mode() == Arguments::_comp) {
331       // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
332       // Java code, so there's not much benefit in running -Xcomp.
333       log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
334       Arguments::set_mode_flags(Arguments::_mixed);
335     }
336 
337     // String deduplication may cause CDS to iterate the strings in different order from one
338     // run to another which resulting in non-determinstic CDS archives.
339     // Disable UseStringDeduplication while dumping CDS archive.
340     UseStringDeduplication = false;
341   }
342 

347     return false;
348   }
349 
350   if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
351     disable_dumping_dynamic_archive();
352   } else {
353     enable_dumping_dynamic_archive();
354   }
355 
356   if (AutoCreateSharedArchive) {
357     if (SharedArchiveFile == nullptr) {
358       log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
359       return false;
360     }
361     if (ArchiveClassesAtExit != nullptr) {
362       log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
363       return false;
364     }
365   }
366 
367   if (UseSharedSpaces && java_base_module_patching_disables_cds() && module_patching_disables_cds()) {
368     Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
369   }
370   if (UseSharedSpaces && check_unsupported_cds_runtime_properties()) {
371     UseSharedSpaces = false;
372   }
373 
374   if (is_dumping_archive()) {
375     // Always verify non-system classes during CDS dump
376     if (!BytecodeVerificationRemote) {
377       BytecodeVerificationRemote = true;
378       log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
379     }
380   }
381 
382   return true;
383 }
384 
385 #if INCLUDE_CDS_JAVA_HEAP
386 bool CDSConfig::is_dumping_heap() {
387   if (is_valhalla_preview()) {
388     // Not working yet -- e.g., HeapShared::oop_hash() needs to be implemented for value oops
389     return false;
390   }
391   // heap dump is not supported in dynamic dump
392   return is_dumping_static_archive() && HeapShared::can_write();
393 }
394 
395 bool CDSConfig::is_dumping_full_module_graph() {
396   if (!_dumping_full_module_graph_disabled &&
397       is_dumping_heap() &&
398       MetaspaceShared::use_optimized_module_handling()) {
399     return true;
400   } else {
401     return false;
402   }
403 }
404 
405 bool CDSConfig::is_loading_full_module_graph() {
406   if (ClassLoaderDataShared::is_full_module_graph_loaded()) {
407     return true;
408   }
409 
410   if (!_loading_full_module_graph_disabled &&
< prev index next >