1 /*
2 * Copyright (c) 2019, 2021, 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 "jvm.h"
27 #include "cds/archiveBuilder.hpp"
28 #include "cds/archiveUtils.inline.hpp"
29 #include "cds/dynamicArchive.hpp"
30 #include "cds/lambdaFormInvokers.hpp"
31 #include "cds/metaspaceShared.hpp"
32 #include "classfile/classLoaderData.inline.hpp"
33 #include "classfile/symbolTable.hpp"
34 #include "classfile/systemDictionaryShared.hpp"
35 #include "classfile/vmSymbols.hpp"
36 #include "gc/shared/collectedHeap.hpp"
37 #include "gc/shared/gcVMOperations.hpp"
38 #include "gc/shared/gc_globals.hpp"
39 #include "logging/log.hpp"
40 #include "memory/metaspaceClosure.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "oops/klass.inline.hpp"
43 #include "runtime/arguments.hpp"
44 #include "runtime/os.hpp"
45 #include "runtime/sharedRuntime.hpp"
46 #include "runtime/vmThread.hpp"
47 #include "runtime/vmOperations.hpp"
48 #include "utilities/align.hpp"
49 #include "utilities/bitMap.inline.hpp"
50
51
52 class DynamicArchiveBuilder : public ArchiveBuilder {
53 public:
mark_pointer(address * ptr_loc)54 void mark_pointer(address* ptr_loc) {
55 ArchivePtrMarker::mark_pointer(ptr_loc);
56 }
57
get_dumped_addr(T obj)58 template <typename T> T get_dumped_addr(T obj) {
59 return (T)ArchiveBuilder::get_dumped_addr((address)obj);
60 }
61
dynamic_dump_method_comparator(Method * a,Method * b)62 static int dynamic_dump_method_comparator(Method* a, Method* b) {
63 Symbol* a_name = a->name();
64 Symbol* b_name = b->name();
65
66 if (a_name == b_name) {
67 return 0;
68 }
69
70 u4 a_offset = ArchiveBuilder::current()->any_to_offset_u4(a_name);
71 u4 b_offset = ArchiveBuilder::current()->any_to_offset_u4(b_name);
72
73 if (a_offset < b_offset) {
74 return -1;
75 } else {
76 assert(a_offset > b_offset, "must be");
77 return 1;
78 }
79 }
80
81 public:
82 DynamicArchiveHeader *_header;
83
84 void init_header();
85 void release_header();
86 void sort_methods();
87 void sort_methods(InstanceKlass* ik) const;
88 void remark_pointers_for_instance_klass(InstanceKlass* k, bool should_mark) const;
89 void write_archive(char* serialized_data);
90
91 public:
DynamicArchiveBuilder()92 DynamicArchiveBuilder() : ArchiveBuilder() { }
93
94 // Do this before and after the archive dump to see if any corruption
95 // is caused by dynamic dumping.
verify_universe(const char * info)96 void verify_universe(const char* info) {
97 if (VerifyBeforeExit) {
98 log_info(cds)("Verify %s", info);
99 // Among other things, this ensures that Eden top is correct.
100 Universe::heap()->prepare_for_verify();
101 Universe::verify(info);
102 }
103 }
104
doit()105 void doit() {
106 SystemDictionaryShared::start_dumping();
107
108 verify_universe("Before CDS dynamic dump");
109 DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm);
110
111 // Block concurrent class unloading from changing the _dumptime_table
112 MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
113 SystemDictionaryShared::check_excluded_classes();
114
115 init_header();
116 gather_source_objs();
117 reserve_buffer();
118
119 log_info(cds, dynamic)("Copying %d klasses and %d symbols",
120 klasses()->length(), symbols()->length());
121 dump_rw_metadata();
122 dump_ro_metadata();
123 relocate_metaspaceobj_embedded_pointers();
124 relocate_roots();
125
126 verify_estimate_size(_estimated_metaspaceobj_bytes, "MetaspaceObjs");
127
128 char* serialized_data;
129 {
130 // Write the symbol table and system dictionaries to the RO space.
131 // Note that these tables still point to the *original* objects, so
132 // they would need to call DynamicArchive::original_to_target() to
133 // get the correct addresses.
134 assert(current_dump_space() == ro_region(), "Must be RO space");
135 SymbolTable::write_to_archive(symbols());
136
137 ArchiveBuilder::OtherROAllocMark mark;
138 SystemDictionaryShared::write_to_archive(false);
139
140 serialized_data = ro_region()->top();
141 WriteClosure wc(ro_region());
142 SymbolTable::serialize_shared_table_header(&wc, false);
143 SystemDictionaryShared::serialize_dictionary_headers(&wc, false);
144 }
145
146 verify_estimate_size(_estimated_hashtable_bytes, "Hashtables");
147
148 sort_methods();
149
150 log_info(cds)("Make classes shareable");
151 make_klasses_shareable();
152
153 log_info(cds)("Adjust lambda proxy class dictionary");
154 SystemDictionaryShared::adjust_lambda_proxy_class_dictionary();
155
156 relocate_to_requested();
157
158 write_archive(serialized_data);
159 release_header();
160
161 assert(_num_dump_regions_used == _total_dump_regions, "must be");
162 verify_universe("After CDS dynamic dump");
163 }
164
iterate_roots(MetaspaceClosure * it,bool is_relocating_pointers)165 virtual void iterate_roots(MetaspaceClosure* it, bool is_relocating_pointers) {
166 FileMapInfo::metaspace_pointers_do(it);
167 SystemDictionaryShared::dumptime_classes_do(it);
168 }
169 };
170
init_header()171 void DynamicArchiveBuilder::init_header() {
172 FileMapInfo* mapinfo = new FileMapInfo(false);
173 assert(FileMapInfo::dynamic_info() == mapinfo, "must be");
174 _header = mapinfo->dynamic_header();
175
176 FileMapInfo* base_info = FileMapInfo::current_info();
177 _header->set_base_header_crc(base_info->crc());
178 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
179 _header->set_base_region_crc(i, base_info->space_crc(i));
180 }
181 _header->populate(base_info, base_info->core_region_alignment());
182 }
183
release_header()184 void DynamicArchiveBuilder::release_header() {
185 // We temporarily allocated a dynamic FileMapInfo for dumping, which makes it appear we
186 // have mapped a dynamic archive, but we actually have not. We are in a safepoint now.
187 // Let's free it so that if class loading happens after we leave the safepoint, nothing
188 // bad will happen.
189 assert(SafepointSynchronize::is_at_safepoint(), "must be");
190 FileMapInfo *mapinfo = FileMapInfo::dynamic_info();
191 assert(mapinfo != NULL && _header == mapinfo->dynamic_header(), "must be");
192 delete mapinfo;
193 assert(!DynamicArchive::is_mapped(), "must be");
194 _header = NULL;
195 }
196
sort_methods()197 void DynamicArchiveBuilder::sort_methods() {
198 InstanceKlass::disable_method_binary_search();
199 for (int i = 0; i < klasses()->length(); i++) {
200 Klass* k = klasses()->at(i);
201 if (k->is_instance_klass()) {
202 sort_methods(InstanceKlass::cast(k));
203 }
204 }
205 }
206
207 // The address order of the copied Symbols may be different than when the original
208 // klasses were created. Re-sort all the tables. See Method::sort_methods().
sort_methods(InstanceKlass * ik) const209 void DynamicArchiveBuilder::sort_methods(InstanceKlass* ik) const {
210 assert(ik != NULL, "DynamicArchiveBuilder currently doesn't support dumping the base archive");
211 if (MetaspaceShared::is_in_shared_metaspace(ik)) {
212 // We have reached a supertype that's already in the base archive
213 return;
214 }
215
216 if (ik->java_mirror() == NULL) {
217 // NULL mirror means this class has already been visited and methods are already sorted
218 return;
219 }
220 ik->remove_java_mirror();
221
222 if (log_is_enabled(Debug, cds, dynamic)) {
223 ResourceMark rm;
224 log_debug(cds, dynamic)("sorting methods for " PTR_FORMAT " (" PTR_FORMAT ") %s",
225 p2i(ik), p2i(to_requested(ik)), ik->external_name());
226 }
227
228 // Method sorting may re-layout the [iv]tables, which would change the offset(s)
229 // of the locations in an InstanceKlass that would contain pointers. Let's clear
230 // all the existing pointer marking bits, and re-mark the pointers after sorting.
231 remark_pointers_for_instance_klass(ik, false);
232
233 // Make sure all supertypes have been sorted
234 sort_methods(ik->java_super());
235 Array<InstanceKlass*>* interfaces = ik->local_interfaces();
236 int len = interfaces->length();
237 for (int i = 0; i < len; i++) {
238 sort_methods(interfaces->at(i));
239 }
240
241 #ifdef ASSERT
242 if (ik->methods() != NULL) {
243 for (int m = 0; m < ik->methods()->length(); m++) {
244 Symbol* name = ik->methods()->at(m)->name();
245 assert(MetaspaceShared::is_in_shared_metaspace(name) || is_in_buffer_space(name), "must be");
246 }
247 }
248 if (ik->default_methods() != NULL) {
249 for (int m = 0; m < ik->default_methods()->length(); m++) {
250 Symbol* name = ik->default_methods()->at(m)->name();
251 assert(MetaspaceShared::is_in_shared_metaspace(name) || is_in_buffer_space(name), "must be");
252 }
253 }
254 #endif
255
256 Method::sort_methods(ik->methods(), /*set_idnums=*/true, dynamic_dump_method_comparator);
257 if (ik->default_methods() != NULL) {
258 Method::sort_methods(ik->default_methods(), /*set_idnums=*/false, dynamic_dump_method_comparator);
259 }
260 ik->vtable().initialize_vtable();
261 ik->itable().initialize_itable();
262
263 // Set all the pointer marking bits after sorting.
264 remark_pointers_for_instance_klass(ik, true);
265 }
266
267 template<bool should_mark>
268 class PointerRemarker: public MetaspaceClosure {
269 public:
do_ref(Ref * ref,bool read_only)270 virtual bool do_ref(Ref* ref, bool read_only) {
271 if (should_mark) {
272 ArchivePtrMarker::mark_pointer(ref->addr());
273 } else {
274 ArchivePtrMarker::clear_pointer(ref->addr());
275 }
276 return false; // don't recurse
277 }
278 };
279
remark_pointers_for_instance_klass(InstanceKlass * k,bool should_mark) const280 void DynamicArchiveBuilder::remark_pointers_for_instance_klass(InstanceKlass* k, bool should_mark) const {
281 if (should_mark) {
282 PointerRemarker<true> marker;
283 k->metaspace_pointers_do(&marker);
284 marker.finish();
285 } else {
286 PointerRemarker<false> marker;
287 k->metaspace_pointers_do(&marker);
288 marker.finish();
289 }
290 }
291
write_archive(char * serialized_data)292 void DynamicArchiveBuilder::write_archive(char* serialized_data) {
293 Array<u8>* table = FileMapInfo::saved_shared_path_table().table();
294 SharedPathTable runtime_table(table, FileMapInfo::shared_path_table().size());
295 _header->set_shared_path_table(runtime_table);
296 _header->set_serialized_data(serialized_data);
297
298 FileMapInfo* dynamic_info = FileMapInfo::dynamic_info();
299 assert(dynamic_info != NULL, "Sanity");
300
301 dynamic_info->open_for_write(Arguments::GetSharedDynamicArchivePath());
302 ArchiveBuilder::write_archive(dynamic_info, NULL, NULL, NULL, NULL);
303
304 address base = _requested_dynamic_archive_bottom;
305 address top = _requested_dynamic_archive_top;
306 size_t file_size = pointer_delta(top, base, sizeof(char));
307
308 log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT
309 " [" SIZE_FORMAT " bytes header, " SIZE_FORMAT " bytes total]",
310 p2i(base), p2i(top), _header->header_size(), file_size);
311
312 log_info(cds, dynamic)("%d klasses; %d symbols", klasses()->length(), symbols()->length());
313 }
314
315 class VM_PopulateDynamicDumpSharedSpace: public VM_GC_Sync_Operation {
316 DynamicArchiveBuilder builder;
317 public:
VM_PopulateDynamicDumpSharedSpace()318 VM_PopulateDynamicDumpSharedSpace() : VM_GC_Sync_Operation() {}
type() const319 VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
doit()320 void doit() {
321 ResourceMark rm;
322 if (SystemDictionaryShared::empty_dumptime_table()) {
323 log_warning(cds, dynamic)("There is no class to be included in the dynamic archive.");
324 return;
325 }
326 if (AllowArchivingWithJavaAgent) {
327 warning("This archive was created with AllowArchivingWithJavaAgent. It should be used "
328 "for testing purposes only and should not be used in a production environment");
329 }
330 FileMapInfo::check_nonempty_dir_in_shared_path_table();
331
332 builder.doit();
333 }
334 };
335
prepare_for_dynamic_dumping_at_exit()336 void DynamicArchive::prepare_for_dynamic_dumping_at_exit() {
337 EXCEPTION_MARK;
338 ResourceMark rm(THREAD);
339 MetaspaceShared::link_and_cleanup_shared_classes(THREAD);
340 if (HAS_PENDING_EXCEPTION) {
341 log_error(cds)("ArchiveClassesAtExit has failed");
342 log_error(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(),
343 java_lang_String::as_utf8_string(java_lang_Throwable::message(PENDING_EXCEPTION)));
344 // We cannot continue to dump the archive anymore.
345 DynamicDumpSharedSpaces = false;
346 CLEAR_PENDING_EXCEPTION;
347 }
348 }
349
350 bool DynamicArchive::_has_been_dumped_once = false;
351
dump(const char * archive_name,TRAPS)352 void DynamicArchive::dump(const char* archive_name, TRAPS) {
353 assert(UseSharedSpaces && RecordDynamicDumpInfo, "already checked in arguments.cpp?");
354 assert(ArchiveClassesAtExit == nullptr, "already checked in arguments.cpp?");
355 // During dynamic archive dumping, some of the data structures are overwritten so
356 // we cannot dump the dynamic archive again. TODO: this should be fixed.
357 if (has_been_dumped_once()) {
358 THROW_MSG(vmSymbols::java_lang_RuntimeException(),
359 "Dynamic dump has been done, and should only be done once");
360 } else {
361 // prevent multiple dumps.
362 set_has_been_dumped_once();
363 ArchiveClassesAtExit = archive_name;
364 if (Arguments::init_shared_archive_paths()) {
365 dump();
366 } else {
367 ArchiveClassesAtExit = nullptr;
368 THROW_MSG(vmSymbols::java_lang_RuntimeException(),
369 "Could not setup SharedDynamicArchivePath");
370 }
371 // prevent do dynamic dump at exit.
372 ArchiveClassesAtExit = nullptr;
373 if (!Arguments::init_shared_archive_paths()) {
374 THROW_MSG(vmSymbols::java_lang_RuntimeException(),
375 "Could not restore SharedDynamicArchivePath");
376 }
377 }
378 }
379
dump()380 void DynamicArchive::dump() {
381 if (Arguments::GetSharedDynamicArchivePath() == NULL) {
382 log_warning(cds, dynamic)("SharedDynamicArchivePath is not specified");
383 return;
384 }
385
386 VM_PopulateDynamicDumpSharedSpace op;
387 VMThread::execute(&op);
388 }
389
validate(FileMapInfo * dynamic_info)390 bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
391 assert(!dynamic_info->is_static(), "must be");
392 // Check if the recorded base archive matches with the current one
393 FileMapInfo* base_info = FileMapInfo::current_info();
394 DynamicArchiveHeader* dynamic_header = dynamic_info->dynamic_header();
395
396 // Check the header crc
397 if (dynamic_header->base_header_crc() != base_info->crc()) {
398 FileMapInfo::fail_continue("Dynamic archive cannot be used: static archive header checksum verification failed.");
399 return false;
400 }
401
402 // Check each space's crc
403 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
404 if (dynamic_header->base_region_crc(i) != base_info->space_crc(i)) {
405 FileMapInfo::fail_continue("Dynamic archive cannot be used: static archive region #%d checksum verification failed.", i);
406 return false;
407 }
408 }
409
410 return true;
411 }
412