1 /*
2 * Copyright (c) 2019, 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/archiveBuilder.hpp"
27 #include "cds/archiveHeapWriter.hpp"
28 #include "cds/archiveUtils.inline.hpp"
29 #include "cds/cds_globals.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/classPrelinker.hpp"
32 #include "cds/dynamicArchive.hpp"
33 #include "cds/regeneratedClasses.hpp"
34 #include "classfile/classLoaderData.inline.hpp"
35 #include "classfile/symbolTable.hpp"
36 #include "classfile/systemDictionaryShared.hpp"
37 #include "classfile/vmSymbols.hpp"
38 #include "gc/shared/collectedHeap.hpp"
39 #include "gc/shared/gcVMOperations.hpp"
40 #include "gc/shared/gc_globals.hpp"
41 #include "jvm.h"
42 #include "logging/log.hpp"
43 #include "memory/metaspaceClosure.hpp"
44 #include "memory/resourceArea.hpp"
45 #include "oops/klass.inline.hpp"
46 #include "runtime/arguments.hpp"
47 #include "runtime/os.hpp"
48 #include "runtime/sharedRuntime.hpp"
49 #include "runtime/vmThread.hpp"
50 #include "runtime/vmOperations.hpp"
51 #include "utilities/align.hpp"
52 #include "utilities/bitMap.inline.hpp"
53
101 log_info(cds)("Verify %s", info);
102 // Among other things, this ensures that Eden top is correct.
103 Universe::heap()->prepare_for_verify();
104 Universe::verify(info);
105 }
106 }
107
108 void doit() {
109 verify_universe("Before CDS dynamic dump");
110 DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm);
111
112 // Block concurrent class unloading from changing the _dumptime_table
113 MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
114 SystemDictionaryShared::check_excluded_classes();
115
116 if (SystemDictionaryShared::is_dumptime_table_empty()) {
117 log_warning(cds, dynamic)("There is no class to be included in the dynamic archive.");
118 return;
119 }
120
121 init_header();
122 gather_source_objs();
123 gather_array_klasses();
124 reserve_buffer();
125
126 log_info(cds, dynamic)("Copying %d klasses and %d symbols",
127 klasses()->length(), symbols()->length());
128 dump_rw_metadata();
129 dump_ro_metadata();
130 relocate_metaspaceobj_embedded_pointers();
131
132 verify_estimate_size(_estimated_metaspaceobj_bytes, "MetaspaceObjs");
133
134 char* serialized_data;
135 {
136 // Write the symbol table and system dictionaries to the RO space.
137 // Note that these tables still point to the *original* objects, so
138 // they would need to call DynamicArchive::original_to_target() to
139 // get the correct addresses.
140 assert(current_dump_region() == ro_region(), "Must be RO space");
141 SymbolTable::write_to_archive(symbols());
142
143 ArchiveBuilder::OtherROAllocMark mark;
144 SystemDictionaryShared::write_to_archive(false);
145 DynamicArchive::dump_array_klasses();
146
147 serialized_data = ro_region()->top();
148 WriteClosure wc(ro_region());
149 ArchiveBuilder::serialize_dynamic_archivable_items(&wc);
150 }
151
152 verify_estimate_size(_estimated_hashtable_bytes, "Hashtables");
153
154 sort_methods();
155
156 log_info(cds)("Make classes shareable");
157 make_klasses_shareable();
158
159 log_info(cds)("Adjust lambda proxy class dictionary");
160 SystemDictionaryShared::adjust_lambda_proxy_class_dictionary();
161
162 relocate_to_requested();
163
164 write_archive(serialized_data);
165 release_header();
166 DynamicArchive::post_dump();
167
168 post_dump();
169
170 assert(_num_dump_regions_used == _total_dump_regions, "must be");
171 verify_universe("After CDS dynamic dump");
172 }
173
174 virtual void iterate_roots(MetaspaceClosure* it) {
175 FileMapInfo::metaspace_pointers_do(it);
176 SystemDictionaryShared::dumptime_classes_do(it);
177 iterate_primitive_array_klasses(it);
178 }
179
180 void iterate_primitive_array_klasses(MetaspaceClosure* it) {
181 for (int i = T_BOOLEAN; i <= T_LONG; i++) {
182 assert(is_java_primitive((BasicType)i), "sanity");
183 Klass* k = Universe::typeArrayKlass((BasicType)i); // this give you "[I", etc
184 assert(MetaspaceShared::is_shared_static((void*)k),
185 "one-dimensional primitive array should be in static archive");
186 ArrayKlass* ak = ArrayKlass::cast(k);
187 while (ak != nullptr && ak->is_shared()) {
188 Klass* next_k = ak->array_klass_or_null();
189 if (next_k != nullptr) {
190 ak = ArrayKlass::cast(next_k);
191 } else {
192 ak = nullptr;
193 }
194 }
195 if (ak != nullptr) {
196 assert(ak->dimension() > 1, "sanity");
213 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
214 _header->set_base_region_crc(i, base_info->region_crc(i));
215 }
216 }
217
218 void DynamicArchiveBuilder::release_header() {
219 // We temporarily allocated a dynamic FileMapInfo for dumping, which makes it appear we
220 // have mapped a dynamic archive, but we actually have not. We are in a safepoint now.
221 // Let's free it so that if class loading happens after we leave the safepoint, nothing
222 // bad will happen.
223 assert(SafepointSynchronize::is_at_safepoint(), "must be");
224 FileMapInfo *mapinfo = FileMapInfo::dynamic_info();
225 assert(mapinfo != nullptr && _header == mapinfo->dynamic_header(), "must be");
226 delete mapinfo;
227 assert(!DynamicArchive::is_mapped(), "must be");
228 _header = nullptr;
229 }
230
231 void DynamicArchiveBuilder::post_dump() {
232 ArchivePtrMarker::reset_map_and_vs();
233 ClassPrelinker::dispose();
234 }
235
236 void DynamicArchiveBuilder::sort_methods() {
237 InstanceKlass::disable_method_binary_search();
238 for (int i = 0; i < klasses()->length(); i++) {
239 Klass* k = get_buffered_addr(klasses()->at(i));
240 if (k->is_instance_klass()) {
241 sort_methods(InstanceKlass::cast(k));
242 }
243 }
244 }
245
246 // The address order of the copied Symbols may be different than when the original
247 // klasses were created. Re-sort all the tables. See Method::sort_methods().
248 void DynamicArchiveBuilder::sort_methods(InstanceKlass* ik) const {
249 assert(ik != nullptr, "DynamicArchiveBuilder currently doesn't support dumping the base archive");
250 if (MetaspaceShared::is_in_shared_metaspace(ik)) {
251 // We have reached a supertype that's already in the base archive
252 return;
484 } else {
485 assert(ArchiveClassesAtExit != nullptr, "sanity");
486 log_warning(cds)("-XX:ArchiveClassesAtExit" __THEMSG);
487 }
488 #undef __THEMSG
489 CDSConfig::disable_dumping_dynamic_archive();
490 }
491 }
492
493 void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) {
494 ExceptionMark em(current);
495 ResourceMark rm(current);
496
497 if (!CDSConfig::is_dumping_dynamic_archive() || archive_name == nullptr) {
498 return;
499 }
500
501 log_info(cds, dynamic)("Preparing for dynamic dump at exit in thread %s", current->name());
502
503 JavaThread* THREAD = current; // For TRAPS processing related to link_shared_classes
504 MetaspaceShared::link_shared_classes(false/*not from jcmd*/, THREAD);
505 if (!HAS_PENDING_EXCEPTION) {
506 // copy shared path table to saved.
507 if (!HAS_PENDING_EXCEPTION) {
508 VM_PopulateDynamicDumpSharedSpace op(archive_name);
509 VMThread::execute(&op);
510 return;
511 }
512 }
513
514 // One of the prepatory steps failed
515 oop ex = current->pending_exception();
516 log_error(cds)("Dynamic dump has failed");
517 log_error(cds)("%s: %s", ex->klass()->external_name(),
518 java_lang_String::as_utf8_string(java_lang_Throwable::message(ex)));
519 CLEAR_PENDING_EXCEPTION;
520 CDSConfig::disable_dumping_dynamic_archive(); // Just for good measure
521 }
522
523 // This is called by "jcmd VM.cds dynamic_dump"
524 void DynamicArchive::dump_for_jcmd(const char* archive_name, TRAPS) {
525 assert(UseSharedSpaces && RecordDynamicDumpInfo, "already checked in arguments.cpp");
526 assert(ArchiveClassesAtExit == nullptr, "already checked in arguments.cpp");
527 assert(CDSConfig::is_dumping_dynamic_archive(), "already checked by check_for_dynamic_dump() during VM startup");
528 MetaspaceShared::link_shared_classes(true/*from jcmd*/, CHECK);
529 // copy shared path table to saved.
530 VM_PopulateDynamicDumpSharedSpace op(archive_name);
531 VMThread::execute(&op);
532 }
533
534 bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
535 assert(!dynamic_info->is_static(), "must be");
536 // Check if the recorded base archive matches with the current one
537 FileMapInfo* base_info = FileMapInfo::current_info();
538 DynamicArchiveHeader* dynamic_header = dynamic_info->dynamic_header();
539
540 // Check the header crc
541 if (dynamic_header->base_header_crc() != base_info->crc()) {
542 log_warning(cds)("Dynamic archive cannot be used: static archive header checksum verification failed.");
543 return false;
544 }
545
546 // Check each space's crc
547 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
548 if (dynamic_header->base_region_crc(i) != base_info->region_crc(i)) {
549 log_warning(cds)("Dynamic archive cannot be used: static archive region #%d checksum verification failed.", i);
|
1 /*
2 * Copyright (c) 2019, 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/archiveBuilder.hpp"
27 #include "cds/archiveHeapWriter.hpp"
28 #include "cds/archiveUtils.inline.hpp"
29 #include "cds/cds_globals.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/classPrelinker.hpp"
32 #include "cds/classPreloader.hpp"
33 #include "cds/dynamicArchive.hpp"
34 #include "cds/metaspaceShared.hpp"
35 #include "cds/regeneratedClasses.hpp"
36 #include "classfile/classLoader.hpp"
37 #include "classfile/classLoaderData.inline.hpp"
38 #include "classfile/symbolTable.hpp"
39 #include "classfile/systemDictionaryShared.hpp"
40 #include "classfile/vmSymbols.hpp"
41 #include "gc/shared/collectedHeap.hpp"
42 #include "gc/shared/gcVMOperations.hpp"
43 #include "gc/shared/gc_globals.hpp"
44 #include "jvm.h"
45 #include "logging/log.hpp"
46 #include "memory/metaspaceClosure.hpp"
47 #include "memory/resourceArea.hpp"
48 #include "oops/klass.inline.hpp"
49 #include "runtime/arguments.hpp"
50 #include "runtime/os.hpp"
51 #include "runtime/sharedRuntime.hpp"
52 #include "runtime/vmThread.hpp"
53 #include "runtime/vmOperations.hpp"
54 #include "utilities/align.hpp"
55 #include "utilities/bitMap.inline.hpp"
56
104 log_info(cds)("Verify %s", info);
105 // Among other things, this ensures that Eden top is correct.
106 Universe::heap()->prepare_for_verify();
107 Universe::verify(info);
108 }
109 }
110
111 void doit() {
112 verify_universe("Before CDS dynamic dump");
113 DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm);
114
115 // Block concurrent class unloading from changing the _dumptime_table
116 MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
117 SystemDictionaryShared::check_excluded_classes();
118
119 if (SystemDictionaryShared::is_dumptime_table_empty()) {
120 log_warning(cds, dynamic)("There is no class to be included in the dynamic archive.");
121 return;
122 }
123
124 log_info(cds,dynamic)("CDS dynamic dump: clinit = %ldms)",
125 ClassLoader::class_init_time_ms());
126
127 init_header();
128 gather_source_objs();
129 gather_array_klasses();
130 reserve_buffer();
131
132 log_info(cds, dynamic)("Copying %d klasses and %d symbols",
133 klasses()->length(), symbols()->length());
134 dump_rw_metadata();
135 dump_ro_metadata();
136 relocate_metaspaceobj_embedded_pointers();
137
138 verify_estimate_size(_estimated_metaspaceobj_bytes, "MetaspaceObjs");
139
140 sort_methods();
141
142 {
143 ArchiveBuilder::OtherROAllocMark mark;
144 ClassPreloader::record_preloaded_classes(false);
145 }
146
147 log_info(cds)("Make classes shareable");
148 make_klasses_shareable();
149
150 char* serialized_data;
151 {
152 // Write the symbol table and system dictionaries to the RO space.
153 // Note that these tables still point to the *original* objects, so
154 // they would need to call DynamicArchive::original_to_target() to
155 // get the correct addresses.
156 assert(current_dump_region() == ro_region(), "Must be RO space");
157 SymbolTable::write_to_archive(symbols());
158
159 ArchiveBuilder::OtherROAllocMark mark;
160 SystemDictionaryShared::write_to_archive(false);
161
162 DynamicArchive::dump_array_klasses();
163 ClassPreloader::record_initiated_classes(false);
164 TrainingData::dump_training_data();
165
166 serialized_data = ro_region()->top();
167 WriteClosure wc(ro_region());
168 ArchiveBuilder::serialize_dynamic_archivable_items(&wc);
169 }
170
171 verify_estimate_size(_estimated_hashtable_bytes, "Hashtables");
172
173 log_info(cds)("Adjust lambda proxy class dictionary");
174 SystemDictionaryShared::adjust_lambda_proxy_class_dictionary();
175
176 log_info(cds)("Adjust method info dictionary");
177 SystemDictionaryShared::adjust_method_info_dictionary();
178
179 log_info(cds)("Make training data shareable");
180 make_training_data_shareable();
181
182 relocate_to_requested();
183
184 write_archive(serialized_data);
185 release_header();
186 DynamicArchive::post_dump();
187
188 post_dump();
189
190 assert(_num_dump_regions_used == _total_dump_regions, "must be");
191 verify_universe("After CDS dynamic dump");
192 }
193
194 virtual void iterate_roots(MetaspaceClosure* it) {
195 FileMapInfo::metaspace_pointers_do(it);
196 SystemDictionaryShared::dumptime_classes_do(it);
197 TrainingData::iterate_roots(it);
198 iterate_primitive_array_klasses(it);
199 }
200
201 void iterate_primitive_array_klasses(MetaspaceClosure* it) {
202 for (int i = T_BOOLEAN; i <= T_LONG; i++) {
203 assert(is_java_primitive((BasicType)i), "sanity");
204 Klass* k = Universe::typeArrayKlass((BasicType)i); // this give you "[I", etc
205 assert(MetaspaceShared::is_shared_static((void*)k),
206 "one-dimensional primitive array should be in static archive");
207 ArrayKlass* ak = ArrayKlass::cast(k);
208 while (ak != nullptr && ak->is_shared()) {
209 Klass* next_k = ak->array_klass_or_null();
210 if (next_k != nullptr) {
211 ak = ArrayKlass::cast(next_k);
212 } else {
213 ak = nullptr;
214 }
215 }
216 if (ak != nullptr) {
217 assert(ak->dimension() > 1, "sanity");
234 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
235 _header->set_base_region_crc(i, base_info->region_crc(i));
236 }
237 }
238
239 void DynamicArchiveBuilder::release_header() {
240 // We temporarily allocated a dynamic FileMapInfo for dumping, which makes it appear we
241 // have mapped a dynamic archive, but we actually have not. We are in a safepoint now.
242 // Let's free it so that if class loading happens after we leave the safepoint, nothing
243 // bad will happen.
244 assert(SafepointSynchronize::is_at_safepoint(), "must be");
245 FileMapInfo *mapinfo = FileMapInfo::dynamic_info();
246 assert(mapinfo != nullptr && _header == mapinfo->dynamic_header(), "must be");
247 delete mapinfo;
248 assert(!DynamicArchive::is_mapped(), "must be");
249 _header = nullptr;
250 }
251
252 void DynamicArchiveBuilder::post_dump() {
253 ArchivePtrMarker::reset_map_and_vs();
254 ClassPreloader::dispose();
255 ClassPrelinker::dispose();
256 }
257
258 void DynamicArchiveBuilder::sort_methods() {
259 InstanceKlass::disable_method_binary_search();
260 for (int i = 0; i < klasses()->length(); i++) {
261 Klass* k = get_buffered_addr(klasses()->at(i));
262 if (k->is_instance_klass()) {
263 sort_methods(InstanceKlass::cast(k));
264 }
265 }
266 }
267
268 // The address order of the copied Symbols may be different than when the original
269 // klasses were created. Re-sort all the tables. See Method::sort_methods().
270 void DynamicArchiveBuilder::sort_methods(InstanceKlass* ik) const {
271 assert(ik != nullptr, "DynamicArchiveBuilder currently doesn't support dumping the base archive");
272 if (MetaspaceShared::is_in_shared_metaspace(ik)) {
273 // We have reached a supertype that's already in the base archive
274 return;
506 } else {
507 assert(ArchiveClassesAtExit != nullptr, "sanity");
508 log_warning(cds)("-XX:ArchiveClassesAtExit" __THEMSG);
509 }
510 #undef __THEMSG
511 CDSConfig::disable_dumping_dynamic_archive();
512 }
513 }
514
515 void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) {
516 ExceptionMark em(current);
517 ResourceMark rm(current);
518
519 if (!CDSConfig::is_dumping_dynamic_archive() || archive_name == nullptr) {
520 return;
521 }
522
523 log_info(cds, dynamic)("Preparing for dynamic dump at exit in thread %s", current->name());
524
525 JavaThread* THREAD = current; // For TRAPS processing related to link_shared_classes
526
527 {
528 // FIXME-HACK - make sure we have at least one class in the dynamic archive
529 TempNewSymbol class_name = SymbolTable::new_symbol("sun/nio/cs/IBM850"); // unusual class; shouldn't be used by our tests cases.
530 SystemDictionary::resolve_or_null(class_name, Handle(), Handle(), THREAD);
531 guarantee(!HAS_PENDING_EXCEPTION, "must have this class");
532 }
533
534 MetaspaceShared::link_shared_classes(false/*not from jcmd*/, THREAD);
535 if (!HAS_PENDING_EXCEPTION) {
536 // copy shared path table to saved.
537 TrainingData::init_dumptime_table(CHECK); // captures TrainingDataSetLocker
538 if (!HAS_PENDING_EXCEPTION) {
539 VM_PopulateDynamicDumpSharedSpace op(archive_name);
540 VMThread::execute(&op);
541 return;
542 }
543 }
544
545 // One of the prepatory steps failed
546 oop ex = current->pending_exception();
547 log_error(cds)("Dynamic dump has failed");
548 log_error(cds)("%s: %s", ex->klass()->external_name(),
549 java_lang_String::as_utf8_string(java_lang_Throwable::message(ex)));
550 CLEAR_PENDING_EXCEPTION;
551 CDSConfig::disable_dumping_dynamic_archive(); // Just for good measure
552 }
553
554 // This is called by "jcmd VM.cds dynamic_dump"
555 void DynamicArchive::dump_for_jcmd(const char* archive_name, TRAPS) {
556 assert(UseSharedSpaces && RecordDynamicDumpInfo, "already checked in arguments.cpp");
557 assert(ArchiveClassesAtExit == nullptr, "already checked in arguments.cpp");
558 assert(CDSConfig::is_dumping_dynamic_archive(), "already checked by check_for_dynamic_dump() during VM startup");
559 MetaspaceShared::link_shared_classes(true/*from jcmd*/, CHECK);
560 // copy shared path table to saved.
561 TrainingData::init_dumptime_table(CHECK); // captures TrainingDataSetLocker
562 VM_PopulateDynamicDumpSharedSpace op(archive_name);
563 VMThread::execute(&op);
564 }
565
566 bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
567 assert(!dynamic_info->is_static(), "must be");
568 // Check if the recorded base archive matches with the current one
569 FileMapInfo* base_info = FileMapInfo::current_info();
570 DynamicArchiveHeader* dynamic_header = dynamic_info->dynamic_header();
571
572 // Check the header crc
573 if (dynamic_header->base_header_crc() != base_info->crc()) {
574 log_warning(cds)("Dynamic archive cannot be used: static archive header checksum verification failed.");
575 return false;
576 }
577
578 // Check each space's crc
579 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
580 if (dynamic_header->base_region_crc(i) != base_info->region_crc(i)) {
581 log_warning(cds)("Dynamic archive cannot be used: static archive region #%d checksum verification failed.", i);
|