1/*
2 * Copyright (c) 2018, 2019, 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 "classfile/javaClasses.inline.hpp"
27#include "classfile/stringTable.hpp"
28#include "classfile/symbolTable.hpp"
29#include "classfile/vmSymbols.hpp"
30#include "logging/log.hpp"
31#include "logging/logMessage.hpp"
32#include "logging/logStream.hpp"
33#include "memory/filemap.hpp"
34#include "memory/heapShared.inline.hpp"
35#include "memory/iterator.inline.hpp"
36#include "memory/metadataFactory.hpp"
37#include "memory/metaspaceClosure.hpp"
38#include "memory/resourceArea.hpp"
39#include "memory/universe.hpp"
40#include "oops/compressedOops.inline.hpp"
41#include "oops/fieldStreams.hpp"
42#include "oops/oop.inline.hpp"
43#include "runtime/fieldDescriptor.inline.hpp"
44#include "runtime/safepointVerifiers.hpp"
45#include "utilities/bitMap.inline.hpp"
46#if INCLUDE_G1GC
47#include "gc/g1/g1CollectedHeap.hpp"
48#endif
49
50#if INCLUDE_CDS_JAVA_HEAP
51
52bool HeapShared::_closed_archive_heap_region_mapped = false;
53bool HeapShared::_open_archive_heap_region_mapped = false;
54bool HeapShared::_archive_heap_region_fixed = false;
55
56address HeapShared::_narrow_oop_base;
57int HeapShared::_narrow_oop_shift;
58
59//
60// If you add new entries to the following tables, you should know what you're doing!
61//
62
63// Entry fields for shareable subgraphs archived in the closed archive heap
64// region. Warning: Objects in the subgraphs should not have reference fields
65// assigned at runtime.
66static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = {
67 {"java/lang/Integer$IntegerCache", "archivedCache"},
68 {"java/lang/Long$LongCache", "archivedCache"},
69 {"java/lang/Byte$ByteCache", "archivedCache"},
70 {"java/lang/Short$ShortCache", "archivedCache"},
71 {"java/lang/Character$CharacterCache", "archivedCache"},
72 {"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
73 {"sun/util/locale/BaseLocale", "constantBaseLocales"},
74};
75// Entry fields for subgraphs archived in the open archive heap region.
76static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = {
77 {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
78 {"java/util/ImmutableCollections$ListN", "EMPTY_LIST"},
79 {"java/util/ImmutableCollections$MapN", "EMPTY_MAP"},
80 {"java/util/ImmutableCollections$SetN", "EMPTY_SET"},
81 {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
82};
83
84const static int num_closed_archive_subgraph_entry_fields =
85 sizeof(closed_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
86const static int num_open_archive_subgraph_entry_fields =
87 sizeof(open_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
88
89////////////////////////////////////////////////////////////////
90//
91// Java heap object archiving support
92//
93////////////////////////////////////////////////////////////////
94void HeapShared::fixup_mapped_heap_regions() {
95 FileMapInfo *mapinfo = FileMapInfo::current_info();
96 mapinfo->fixup_mapped_heap_regions();
97 set_archive_heap_region_fixed();
98}
99
100unsigned HeapShared::oop_hash(oop const& p) {
101 assert(!p->mark()->has_bias_pattern(),
102 "this object should never have been locked"); // so identity_hash won't safepoin
103 unsigned hash = (unsigned)p->identity_hash();
104 return hash;
105}
106
107HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = NULL;
108oop HeapShared::find_archived_heap_object(oop obj) {
109 assert(DumpSharedSpaces, "dump-time only");
110 ArchivedObjectCache* cache = archived_object_cache();
111 oop* p = cache->get(obj);
112 if (p != NULL) {
113 return *p;
114 } else {
115 return NULL;
116 }
117}
118
119oop HeapShared::archive_heap_object(oop obj, Thread* THREAD) {
120 assert(DumpSharedSpaces, "dump-time only");
121
122 oop ao = find_archived_heap_object(obj);
123 if (ao != NULL) {
124 // already archived
125 return ao;
126 }
127
128 int len = obj->size();
129 if (G1CollectedHeap::heap()->is_archive_alloc_too_large(len)) {
130 log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT,
131 p2i(obj), (size_t)obj->size());
132 return NULL;
133 }
134
135 // Pre-compute object identity hash at CDS dump time.
136 obj->identity_hash();
137
138 oop archived_oop = (oop)G1CollectedHeap::heap()->archive_mem_allocate(len);
139 if (archived_oop != NULL) {
140 Copy::aligned_disjoint_words((HeapWord*)obj, (HeapWord*)archived_oop, len);
141 MetaspaceShared::relocate_klass_ptr(archived_oop);
142 ArchivedObjectCache* cache = archived_object_cache();
143 cache->put(obj, archived_oop);
144 log_debug(cds, heap)("Archived heap object " PTR_FORMAT " ==> " PTR_FORMAT,
145 p2i(obj), p2i(archived_oop));
146 } else {
147 log_error(cds, heap)(
148 "Cannot allocate space for object " PTR_FORMAT " in archived heap region",
149 p2i(obj));
150 vm_exit(1);
151 }
152 return archived_oop;
153}
154
155oop HeapShared::materialize_archived_object(narrowOop v) {
156 assert(archive_heap_region_fixed(),
157 "must be called after archive heap regions are fixed");
158 if (!CompressedOops::is_null(v)) {
159 oop obj = HeapShared::decode_from_archive(v);
160 return G1CollectedHeap::heap()->materialize_archived_object(obj);
161 }
162 return NULL;
163}
164
165void HeapShared::archive_klass_objects(Thread* THREAD) {
166 GrowableArray<Klass*>* klasses = MetaspaceShared::collected_klasses();
167 assert(klasses != NULL, "sanity");
168 for (int i = 0; i < klasses->length(); i++) {
169 Klass* k = klasses->at(i);
170
171 // archive mirror object
172 java_lang_Class::archive_mirror(k, CHECK);
173
174 // archive the resolved_referenes array
175 if (k->is_instance_klass()) {
176 InstanceKlass* ik = InstanceKlass::cast(k);
177 ik->constants()->archive_resolved_references(THREAD);
178 }
179 }
180}
181
182void HeapShared::archive_java_heap_objects(GrowableArray<MemRegion> *closed,
183 GrowableArray<MemRegion> *open) {
184 if (!is_heap_object_archiving_allowed()) {
185 if (log_is_enabled(Info, cds)) {
186 log_info(cds)(
187 "Archived java heap is not supported as UseG1GC, "
188 "UseCompressedOops and UseCompressedClassPointers are required."
189 "Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.",
190 BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops),
191 BOOL_TO_STR(UseCompressedClassPointers));
192 }
193 return;
194 }
195
196 G1HeapVerifier::verify_ready_for_archiving();
197
198 {
199 NoSafepointVerifier nsv;
200
201 // Cache for recording where the archived objects are copied to
202 create_archived_object_cache();
203
204 tty->print_cr("Dumping objects to closed archive heap region ...");
205 NOT_PRODUCT(StringTable::verify());
206 copy_closed_archive_heap_objects(closed);
207
208 tty->print_cr("Dumping objects to open archive heap region ...");
209 copy_open_archive_heap_objects(open);
210
211 destroy_archived_object_cache();
212 }
213
214 G1HeapVerifier::verify_archive_regions();
215}
216
217void HeapShared::copy_closed_archive_heap_objects(
218 GrowableArray<MemRegion> * closed_archive) {
219 assert(is_heap_object_archiving_allowed(), "Cannot archive java heap objects");
220
221 Thread* THREAD = Thread::current();
222 G1CollectedHeap::heap()->begin_archive_alloc_range();
223
224 // Archive interned string objects
225 StringTable::write_to_archive();
226
227 archive_object_subgraphs(closed_archive_subgraph_entry_fields,
228 num_closed_archive_subgraph_entry_fields,
229 true /* is_closed_archive */, THREAD);
230
231 G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
232 os::vm_allocation_granularity());
233}
234
235void HeapShared::copy_open_archive_heap_objects(
236 GrowableArray<MemRegion> * open_archive) {
237 assert(is_heap_object_archiving_allowed(), "Cannot archive java heap objects");
238
239 Thread* THREAD = Thread::current();
240 G1CollectedHeap::heap()->begin_archive_alloc_range(true /* open */);
241
242 java_lang_Class::archive_basic_type_mirrors(THREAD);
243
244 archive_klass_objects(THREAD);
245
246 archive_object_subgraphs(open_archive_subgraph_entry_fields,
247 num_open_archive_subgraph_entry_fields,
248 false /* is_closed_archive */,
249 THREAD);
250
251 G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
252 os::vm_allocation_granularity());
253}
254
255void HeapShared::init_narrow_oop_decoding(address base, int shift) {
256 _narrow_oop_base = base;
257 _narrow_oop_shift = shift;
258}
259
260//
261// Subgraph archiving support
262//
263HeapShared::DumpTimeKlassSubGraphInfoTable* HeapShared::_dump_time_subgraph_info_table = NULL;
264HeapShared::RunTimeKlassSubGraphInfoTable HeapShared::_run_time_subgraph_info_table;
265
266// Get the subgraph_info for Klass k. A new subgraph_info is created if
267// there is no existing one for k. The subgraph_info records the relocated
268// Klass* of the original k.
269KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
270 assert(DumpSharedSpaces, "dump time only");
271 Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
272 KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(relocated_k);
273 if (info == NULL) {
274 _dump_time_subgraph_info_table->put(relocated_k, KlassSubGraphInfo(relocated_k));
275 info = _dump_time_subgraph_info_table->get(relocated_k);
276 ++ _dump_time_subgraph_info_table->_count;
277 }
278 return info;
279}
280
281// Add an entry field to the current KlassSubGraphInfo.
282void KlassSubGraphInfo::add_subgraph_entry_field(
283 int static_field_offset, oop v, bool is_closed_archive) {
284 assert(DumpSharedSpaces, "dump time only");
285 if (_subgraph_entry_fields == NULL) {
286 _subgraph_entry_fields =
287 new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
288 }
289 _subgraph_entry_fields->append((juint)static_field_offset);
290 _subgraph_entry_fields->append(CompressedOops::encode(v));
291 _subgraph_entry_fields->append(is_closed_archive ? 1 : 0);
292}
293
294// Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
295// Only objects of boot classes can be included in sub-graph.
296void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k, Klass *relocated_k) {
297 assert(DumpSharedSpaces, "dump time only");
298 assert(relocated_k == MetaspaceShared::get_relocated_klass(orig_k),
299 "must be the relocated Klass in the shared space");
300
301 if (_subgraph_object_klasses == NULL) {
302 _subgraph_object_klasses =
303 new(ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(50, true);
304 }
305
306 assert(relocated_k->is_shared(), "must be a shared class");
307
308 if (_k == relocated_k) {
309 // Don't add the Klass containing the sub-graph to it's own klass
310 // initialization list.
311 return;
312 }
313
314 if (relocated_k->is_instance_klass()) {
315 assert(InstanceKlass::cast(relocated_k)->is_shared_boot_class(),
316 "must be boot class");
317 // SystemDictionary::xxx_klass() are not updated, need to check
318 // the original Klass*
319 if (orig_k == SystemDictionary::String_klass() ||
320 orig_k == SystemDictionary::Object_klass()) {
321 // Initialized early during VM initialization. No need to be added
322 // to the sub-graph object class list.
323 return;
324 }
325 } else if (relocated_k->is_objArray_klass()) {
326 Klass* abk = ObjArrayKlass::cast(relocated_k)->bottom_klass();
327 if (abk->is_instance_klass()) {
328 assert(InstanceKlass::cast(abk)->is_shared_boot_class(),
329 "must be boot class");
330 }
331 if (relocated_k == Universe::objectArrayKlassObj()) {
332 // Initialized early during Universe::genesis. No need to be added
333 // to the list.
334 return;
335 }
336 } else {
337 assert(relocated_k->is_typeArray_klass(), "must be");
338 // Primitive type arrays are created early during Universe::genesis.
339 return;
340 }
341
342 if (log_is_enabled(Debug, cds, heap)) {
343 if (!_subgraph_object_klasses->contains(relocated_k)) {
344 ResourceMark rm;
345 log_debug(cds, heap)("Adding klass %s", orig_k->external_name());
346 }
347 }
348
349 _subgraph_object_klasses->append_if_missing(relocated_k);
350}
351
352// Initialize an archived subgraph_info_record from the given KlassSubGraphInfo.
353void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) {
354 _k = info->klass();
355 _entry_field_records = NULL;
356 _subgraph_object_klasses = NULL;
357
358 // populate the entry fields
359 GrowableArray<juint>* entry_fields = info->subgraph_entry_fields();
360 if (entry_fields != NULL) {
361 int num_entry_fields = entry_fields->length();
362 assert(num_entry_fields % 3 == 0, "sanity");
363 _entry_field_records =
364 MetaspaceShared::new_ro_array<juint>(num_entry_fields);
365 for (int i = 0 ; i < num_entry_fields; i++) {
366 _entry_field_records->at_put(i, entry_fields->at(i));
367 }
368 }
369
370 // the Klasses of the objects in the sub-graphs
371 GrowableArray<Klass*>* subgraph_object_klasses = info->subgraph_object_klasses();
372 if (subgraph_object_klasses != NULL) {
373 int num_subgraphs_klasses = subgraph_object_klasses->length();
374 _subgraph_object_klasses =
375 MetaspaceShared::new_ro_array<Klass*>(num_subgraphs_klasses);
376 for (int i = 0; i < num_subgraphs_klasses; i++) {
377 Klass* subgraph_k = subgraph_object_klasses->at(i);
378 if (log_is_enabled(Info, cds, heap)) {
379 ResourceMark rm;
380 log_info(cds, heap)(
381 "Archived object klass %s (%2d) => %s",
382 _k->external_name(), i, subgraph_k->external_name());
383 }
384 _subgraph_object_klasses->at_put(i, subgraph_k);
385 }
386 }
387}
388
389struct CopyKlassSubGraphInfoToArchive : StackObj {
390 CompactHashtableWriter* _writer;
391 CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
392
393 bool do_entry(Klass* klass, KlassSubGraphInfo& info) {
394 if (info.subgraph_object_klasses() != NULL || info.subgraph_entry_fields() != NULL) {
395 ArchivedKlassSubGraphInfoRecord* record =
396 (ArchivedKlassSubGraphInfoRecord*)MetaspaceShared::read_only_space_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
397 record->init(&info);
398
399 unsigned int hash = primitive_hash<Klass*>(klass);
400 u4 delta = MetaspaceShared::object_delta_u4(record);
401 _writer->add(hash, delta);
402 }
403 return true; // keep on iterating
404 }
405};
406
407// Build the records of archived subgraph infos, which include:
408// - Entry points to all subgraphs from the containing class mirror. The entry
409// points are static fields in the mirror. For each entry point, the field
410// offset, value and is_closed_archive flag are recorded in the sub-graph
411// info. The value is stored back to the corresponding field at runtime.
412// - A list of klasses that need to be loaded/initialized before archived
413// java object sub-graph can be accessed at runtime.
414void HeapShared::write_subgraph_info_table() {
415 // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
416 DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
417 CompactHashtableStats stats;
418
419 _run_time_subgraph_info_table.reset();
420
421 CompactHashtableWriter writer(d_table->_count, &stats);
422 CopyKlassSubGraphInfoToArchive copy(&writer);
423 d_table->iterate(&copy);
424
425 writer.dump(&_run_time_subgraph_info_table, "subgraphs");
426}
427
428void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) {
429 _run_time_subgraph_info_table.serialize_header(soc);
430}
431
432void HeapShared::initialize_from_archived_subgraph(Klass* k) {
433 if (!open_archive_heap_region_mapped()) {
434 return; // nothing to do
435 }
436 assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
437
438 unsigned int hash = primitive_hash<Klass*>(k);
439 const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
440
441 // Initialize from archived data. Currently this is done only
442 // during VM initialization time. No lock is needed.
443 if (record != NULL) {
444 Thread* THREAD = Thread::current();
445
446 int i;
447 // Load/link/initialize the klasses of the objects in the subgraph.
448 // NULL class loader is used.
449 Array<Klass*>* klasses = record->subgraph_object_klasses();
450 if (klasses != NULL) {
451 for (i = 0; i < klasses->length(); i++) {
452 Klass* obj_k = klasses->at(i);
453 Klass* resolved_k = SystemDictionary::resolve_or_null(
454 (obj_k)->name(), THREAD);
455 if (resolved_k != obj_k) {
456 assert(!SystemDictionary::is_well_known_klass(resolved_k),
457 "shared well-known classes must not be replaced by JVMTI ClassFileLoadHook");
458 ResourceMark rm(THREAD);
459 log_info(cds, heap)("Failed to load subgraph because %s was not loaded from archive",
460 resolved_k->external_name());
461 return;
462 }
463 if ((obj_k)->is_instance_klass()) {
464 InstanceKlass* ik = InstanceKlass::cast(obj_k);
465 ik->initialize(THREAD);
466 } else if ((obj_k)->is_objArray_klass()) {
467 ObjArrayKlass* oak = ObjArrayKlass::cast(obj_k);
468 oak->initialize(THREAD);
469 }
470 }
471 }
472
473 if (HAS_PENDING_EXCEPTION) {
474 CLEAR_PENDING_EXCEPTION;
475 // None of the field value will be set if there was an exception.
476 // The java code will not see any of the archived objects in the
477 // subgraphs referenced from k in this case.
478 return;
479 }
480
481 // Load the subgraph entry fields from the record and store them back to
482 // the corresponding fields within the mirror.
483 oop m = k->java_mirror();
484 Array<juint>* entry_field_records = record->entry_field_records();
485 if (entry_field_records != NULL) {
486 int efr_len = entry_field_records->length();
487 assert(efr_len % 3 == 0, "sanity");
488 for (i = 0; i < efr_len;) {
489 int field_offset = entry_field_records->at(i);
490 narrowOop nv = entry_field_records->at(i+1);
491 int is_closed_archive = entry_field_records->at(i+2);
492 oop v;
493 if (is_closed_archive == 0) {
494 // It's an archived object in the open archive heap regions, not shared.
495 // The object refereced by the field becomes 'known' by GC from this
496 // point. All objects in the subgraph reachable from the object are
497 // also 'known' by GC.
498 v = materialize_archived_object(nv);
499 } else {
500 // Shared object in the closed archive heap regions. Decode directly.
501 assert(!CompressedOops::is_null(nv), "shared object is null");
502 v = HeapShared::decode_from_archive(nv);
503 }
504 m->obj_field_put(field_offset, v);
505 i += 3;
506
507 log_debug(cds, heap)(" " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v));
508 }
509
510 // Done. Java code can see the archived sub-graphs referenced from k's
511 // mirror after this point.
512 if (log_is_enabled(Info, cds, heap)) {
513 ResourceMark rm;
514 log_info(cds, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT,
515 k->external_name(), p2i(k));
516 }
517 }
518 }
519}
520
521class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
522 int _level;
523 bool _is_closed_archive;
524 bool _record_klasses_only;
525 KlassSubGraphInfo* _subgraph_info;
526 oop _orig_referencing_obj;
527 oop _archived_referencing_obj;
528 Thread* _thread;
529 public:
530 WalkOopAndArchiveClosure(int level,
531 bool is_closed_archive,
532 bool record_klasses_only,
533 KlassSubGraphInfo* subgraph_info,
534 oop orig, oop archived, TRAPS) :
535 _level(level), _is_closed_archive(is_closed_archive),
536 _record_klasses_only(record_klasses_only),
537 _subgraph_info(subgraph_info),
538 _orig_referencing_obj(orig), _archived_referencing_obj(archived),
539 _thread(THREAD) {}
540 void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
541 void do_oop( oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
542
543 protected:
544 template <class T> void do_oop_work(T *p) {
545 oop obj = RawAccess<>::oop_load(p);
546 if (!CompressedOops::is_null(obj)) {
547 assert(!HeapShared::is_archived_object(obj),
548 "original objects must not point to archived objects");
549
550 size_t field_delta = pointer_delta(p, _orig_referencing_obj, sizeof(char));
551 T* new_p = (T*)(address(_archived_referencing_obj) + field_delta);
552 Thread* THREAD = _thread;
553
554 if (!_record_klasses_only && log_is_enabled(Debug, cds, heap)) {
555 ResourceMark rm;
556 log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size %d %s", _level,
557 _orig_referencing_obj->klass()->external_name(), field_delta,
558 p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name());
559 LogTarget(Trace, cds, heap) log;
560 LogStream out(log);
561 obj->print_on(&out);
562 }
563
564 oop archived = HeapShared::archive_reachable_objects_from(
565 _level + 1, _subgraph_info, obj, _is_closed_archive, THREAD);
566 assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
567 assert(HeapShared::is_archived_object(archived), "must be");
568
569 if (!_record_klasses_only) {
570 // Update the reference in the archived copy of the referencing object.
571 log_debug(cds, heap)("(%d) updating oop @[" PTR_FORMAT "] " PTR_FORMAT " ==> " PTR_FORMAT,
572 _level, p2i(new_p), p2i(obj), p2i(archived));
573 RawAccess<IS_NOT_NULL>::oop_store(new_p, archived);
574 }
575 }
576 }
577};
578
579void HeapShared::check_closed_archive_heap_region_object(InstanceKlass* k,
580 Thread* THREAD) {
581 // Check fields in the object
582 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
583 if (!fs.access_flags().is_static()) {
584 BasicType ft = fs.field_descriptor().field_type();
585 if (!fs.access_flags().is_final() && (ft == T_ARRAY || ft == T_OBJECT)) {
586 ResourceMark rm(THREAD);
587 log_warning(cds, heap)(
588 "Please check reference field in %s instance in closed archive heap region: %s %s",
589 k->external_name(), (fs.name())->as_C_string(),
590 (fs.signature())->as_C_string());
591 }
592 }
593 }
594}
595
596// (1) If orig_obj has not been archived yet, archive it.
597// (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
598// trace all objects that are reachable from it, and make sure these objects are archived.
599// (3) Record the klasses of all orig_obj and all reachable objects.
600oop HeapShared::archive_reachable_objects_from(int level,
601 KlassSubGraphInfo* subgraph_info,
602 oop orig_obj,
603 bool is_closed_archive,
604 TRAPS) {
605 assert(orig_obj != NULL, "must be");
606 assert(!is_archived_object(orig_obj), "sanity");
607
608 // java.lang.Class instances cannot be included in an archived
609 // object sub-graph.
610 if (java_lang_Class::is_instance(orig_obj)) {
611 log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
612 vm_exit(1);
613 }
614
615 oop archived_obj = find_archived_heap_object(orig_obj);
616 if (java_lang_String::is_instance(orig_obj) && archived_obj != NULL) {
617 // To save time, don't walk strings that are already archived. They just contain
618 // pointers to a type array, whose klass doesn't need to be recorded.
619 return archived_obj;
620 }
621
622 if (has_been_seen_during_subgraph_recording(orig_obj)) {
623 // orig_obj has already been archived and traced. Nothing more to do.
624 return archived_obj;
625 } else {
626 set_has_been_seen_during_subgraph_recording(orig_obj);
627 }
628
629 bool record_klasses_only = (archived_obj != NULL);
630 if (archived_obj == NULL) {
631 ++_num_new_archived_objs;
632 archived_obj = archive_heap_object(orig_obj, THREAD);
633 if (archived_obj == NULL) {
634 // Skip archiving the sub-graph referenced from the current entry field.
635 ResourceMark rm;
636 log_error(cds, heap)(
637 "Cannot archive the sub-graph referenced from %s object ("
638 PTR_FORMAT ") size %d, skipped.",
639 orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize);
640 if (level == 1) {
641 // Don't archive a subgraph root that's too big. For archives static fields, that's OK
642 // as the Java code will take care of initializing this field dynamically.
643 return NULL;
644 } else {
645 // We don't know how to handle an object that has been archived, but some of its reachable
646 // objects cannot be archived. Bail out for now. We might need to fix this in the future if
647 // we have a real use case.
648 vm_exit(1);
649 }
650 }
651 }
652
653 assert(archived_obj != NULL, "must be");
654 Klass *orig_k = orig_obj->klass();
655 Klass *relocated_k = archived_obj->klass();
656 subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
657
658 WalkOopAndArchiveClosure walker(level, is_closed_archive, record_klasses_only,
659 subgraph_info, orig_obj, archived_obj, THREAD);
660 orig_obj->oop_iterate(&walker);
661 if (is_closed_archive && orig_k->is_instance_klass()) {
662 check_closed_archive_heap_region_object(InstanceKlass::cast(orig_k), THREAD);
663 }
664 return archived_obj;
665}
666
667//
668// Start from the given static field in a java mirror and archive the
669// complete sub-graph of java heap objects that are reached directly
670// or indirectly from the starting object by following references.
671// Sub-graph archiving restrictions (current):
672//
673// - All classes of objects in the archived sub-graph (including the
674// entry class) must be boot class only.
675// - No java.lang.Class instance (java mirror) can be included inside
676// an archived sub-graph. Mirror can only be the sub-graph entry object.
677//
678// The Java heap object sub-graph archiving process (see
679// WalkOopAndArchiveClosure):
680//
681// 1) Java object sub-graph archiving starts from a given static field
682// within a Class instance (java mirror). If the static field is a
683// refererence field and points to a non-null java object, proceed to
684// the next step.
685//
686// 2) Archives the referenced java object. If an archived copy of the
687// current object already exists, updates the pointer in the archived
688// copy of the referencing object to point to the current archived object.
689// Otherwise, proceed to the next step.
690//
691// 3) Follows all references within the current java object and recursively
692// archive the sub-graph of objects starting from each reference.
693//
694// 4) Updates the pointer in the archived copy of referencing object to
695// point to the current archived object.
696//
697// 5) The Klass of the current java object is added to the list of Klasses
698// for loading and initialzing before any object in the archived graph can
699// be accessed at runtime.
700//
701void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k,
702 const char* klass_name,
703 int field_offset,
704 const char* field_name,
705 bool is_closed_archive,
706 TRAPS) {
707 assert(DumpSharedSpaces, "dump time only");
708 assert(k->is_shared_boot_class(), "must be boot class");
709
710 oop m = k->java_mirror();
711
712 KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
713 oop f = m->obj_field(field_offset);
714
715 log_debug(cds, heap)("Start archiving from: %s::%s (" PTR_FORMAT ")", klass_name, field_name, p2i(f));
716
717 if (!CompressedOops::is_null(f)) {
718 if (log_is_enabled(Trace, cds, heap)) {
719 LogTarget(Trace, cds, heap) log;
720 LogStream out(log);
721 f->print_on(&out);
722 }
723
724 oop af = archive_reachable_objects_from(1, subgraph_info, f,
725 is_closed_archive, CHECK);
726
727 if (af == NULL) {
728 log_error(cds, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)",
729 klass_name, field_name);
730 } else {
731 // Note: the field value is not preserved in the archived mirror.
732 // Record the field as a new subGraph entry point. The recorded
733 // information is restored from the archive at runtime.
734 subgraph_info->add_subgraph_entry_field(field_offset, af, is_closed_archive);
735 log_info(cds, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(af));
736 }
737 } else {
738 // The field contains null, we still need to record the entry point,
739 // so it can be restored at runtime.
740 subgraph_info->add_subgraph_entry_field(field_offset, NULL, false);
741 }
742}
743
744#ifndef PRODUCT
745class VerifySharedOopClosure: public BasicOopIterateClosure {
746 private:
747 bool _is_archived;
748
749 public:
750 VerifySharedOopClosure(bool is_archived) : _is_archived(is_archived) {}
751
752 void do_oop(narrowOop *p) { VerifySharedOopClosure::do_oop_work(p); }
753 void do_oop( oop *p) { VerifySharedOopClosure::do_oop_work(p); }
754
755 protected:
756 template <class T> void do_oop_work(T *p) {
757 oop obj = RawAccess<>::oop_load(p);
758 if (!CompressedOops::is_null(obj)) {
759 HeapShared::verify_reachable_objects_from(obj, _is_archived);
760 }
761 }
762};
763
764void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
765 assert(DumpSharedSpaces, "dump time only");
766 assert(k->is_shared_boot_class(), "must be boot class");
767
768 oop m = k->java_mirror();
769 oop f = m->obj_field(field_offset);
770 if (!CompressedOops::is_null(f)) {
771 verify_subgraph_from(f);
772 }
773}
774
775void HeapShared::verify_subgraph_from(oop orig_obj) {
776 oop archived_obj = find_archived_heap_object(orig_obj);
777 if (archived_obj == NULL) {
778 // It's OK for the root of a subgraph to be not archived. See comments in
779 // archive_reachable_objects_from().
780 return;
781 }
782
783 // Verify that all objects reachable from orig_obj are archived.
784 init_seen_objects_table();
785 verify_reachable_objects_from(orig_obj, false);
786 delete_seen_objects_table();
787
788 // Note: we could also verify that all objects reachable from the archived
789 // copy of orig_obj can only point to archived objects, with:
790 // init_seen_objects_table();
791 // verify_reachable_objects_from(archived_obj, true);
792 // init_seen_objects_table();
793 // but that's already done in G1HeapVerifier::verify_archive_regions so we
794 // won't do it here.
795}
796
797void HeapShared::verify_reachable_objects_from(oop obj, bool is_archived) {
798 _num_total_verifications ++;
799 if (!has_been_seen_during_subgraph_recording(obj)) {
800 set_has_been_seen_during_subgraph_recording(obj);
801
802 if (is_archived) {
803 assert(is_archived_object(obj), "must be");
804 assert(find_archived_heap_object(obj) == NULL, "must be");
805 } else {
806 assert(!is_archived_object(obj), "must be");
807 assert(find_archived_heap_object(obj) != NULL, "must be");
808 }
809
810 VerifySharedOopClosure walker(is_archived);
811 obj->oop_iterate(&walker);
812 }
813}
814#endif
815
816HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = NULL;
817int HeapShared::_num_new_walked_objs;
818int HeapShared::_num_new_archived_objs;
819int HeapShared::_num_old_recorded_klasses;
820
821int HeapShared::_num_total_subgraph_recordings = 0;
822int HeapShared::_num_total_walked_objs = 0;
823int HeapShared::_num_total_archived_objs = 0;
824int HeapShared::_num_total_recorded_klasses = 0;
825int HeapShared::_num_total_verifications = 0;
826
827bool HeapShared::has_been_seen_during_subgraph_recording(oop obj) {
828 return _seen_objects_table->get(obj) != NULL;
829}
830
831void HeapShared::set_has_been_seen_during_subgraph_recording(oop obj) {
832 assert(!has_been_seen_during_subgraph_recording(obj), "sanity");
833 _seen_objects_table->put(obj, true);
834 ++ _num_new_walked_objs;
835}
836
837void HeapShared::start_recording_subgraph(InstanceKlass *k, const char* class_name) {
838 log_info(cds, heap)("Start recording subgraph(s) for archived fields in %s", class_name);
839 init_seen_objects_table();
840 _num_new_walked_objs = 0;
841 _num_new_archived_objs = 0;
842 _num_old_recorded_klasses = get_subgraph_info(k)->num_subgraph_object_klasses();
843}
844
845void HeapShared::done_recording_subgraph(InstanceKlass *k, const char* class_name) {
846 int num_new_recorded_klasses = get_subgraph_info(k)->num_subgraph_object_klasses() -
847 _num_old_recorded_klasses;
848 log_info(cds, heap)("Done recording subgraph(s) for archived fields in %s: "
849 "walked %d objs, archived %d new objs, recorded %d classes",
850 class_name, _num_new_walked_objs, _num_new_archived_objs,
851 num_new_recorded_klasses);
852
853 delete_seen_objects_table();
854
855 _num_total_subgraph_recordings ++;
856 _num_total_walked_objs += _num_new_walked_objs;
857 _num_total_archived_objs += _num_new_archived_objs;
858 _num_total_recorded_klasses += num_new_recorded_klasses;
859}
860
861class ArchivableStaticFieldFinder: public FieldClosure {
862 InstanceKlass* _ik;
863 Symbol* _field_name;
864 bool _found;
865 int _offset;
866public:
867 ArchivableStaticFieldFinder(InstanceKlass* ik, Symbol* field_name) :
868 _ik(ik), _field_name(field_name), _found(false), _offset(-1) {}
869
870 virtual void do_field(fieldDescriptor* fd) {
871 if (fd->name() == _field_name) {
872 assert(!_found, "fields cannot be overloaded");
873 assert(fd->field_type() == T_OBJECT || fd->field_type() == T_ARRAY, "can archive only obj or array fields");
874 _found = true;
875 _offset = fd->offset();
876 }
877 }
878 bool found() { return _found; }
879 int offset() { return _offset; }
880};
881
882void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[],
883 int num, Thread* THREAD) {
884 for (int i = 0; i < num; i++) {
885 ArchivableStaticFieldInfo* info = &fields[i];
886 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
887 TempNewSymbol field_name = SymbolTable::new_symbol(info->field_name);
888
889 Klass* k = SystemDictionary::resolve_or_null(klass_name, THREAD);
890 assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
891 InstanceKlass* ik = InstanceKlass::cast(k);
892 assert(InstanceKlass::cast(ik)->is_shared_boot_class(),
893 "Only support boot classes");
894 ik->initialize(THREAD);
895 guarantee(!HAS_PENDING_EXCEPTION, "exception in initialize");
896
897 ArchivableStaticFieldFinder finder(ik, field_name);
898 ik->do_local_static_fields(&finder);
899 assert(finder.found(), "field must exist");
900
901 info->klass = ik;
902 info->offset = finder.offset();
903 }
904}
905
906void HeapShared::init_subgraph_entry_fields(Thread* THREAD) {
907 _dump_time_subgraph_info_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeKlassSubGraphInfoTable();
908
909 init_subgraph_entry_fields(closed_archive_subgraph_entry_fields,
910 num_closed_archive_subgraph_entry_fields,
911 THREAD);
912 init_subgraph_entry_fields(open_archive_subgraph_entry_fields,
913 num_open_archive_subgraph_entry_fields,
914 THREAD);
915}
916
917void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
918 int num, bool is_closed_archive,
919 Thread* THREAD) {
920 _num_total_subgraph_recordings = 0;
921 _num_total_walked_objs = 0;
922 _num_total_archived_objs = 0;
923 _num_total_recorded_klasses = 0;
924 _num_total_verifications = 0;
925
926 // For each class X that has one or more archived fields:
927 // [1] Dump the subgraph of each archived field
928 // [2] Create a list of all the class of the objects that can be reached
929 // by any of these static fields.
930 // At runtime, these classes are initialized before X's archived fields
931 // are restored by HeapShared::initialize_from_archived_subgraph().
932 int i;
933 for (i = 0; i < num; ) {
934 ArchivableStaticFieldInfo* info = &fields[i];
935 const char* klass_name = info->klass_name;
936 start_recording_subgraph(info->klass, klass_name);
937
938 // If you have specified consecutive fields of the same klass in
939 // fields[], these will be archived in the same
940 // {start_recording_subgraph ... done_recording_subgraph} pass to
941 // save time.
942 for (; i < num; i++) {
943 ArchivableStaticFieldInfo* f = &fields[i];
944 if (f->klass_name != klass_name) {
945 break;
946 }
947 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
948 f->offset, f->field_name,
949 is_closed_archive, CHECK);
950 }
951 done_recording_subgraph(info->klass, klass_name);
952 }
953
954 log_info(cds, heap)("Archived subgraph records in %s archive heap region = %d",
955 is_closed_archive ? "closed" : "open",
956 _num_total_subgraph_recordings);
957 log_info(cds, heap)(" Walked %d objects", _num_total_walked_objs);
958 log_info(cds, heap)(" Archived %d objects", _num_total_archived_objs);
959 log_info(cds, heap)(" Recorded %d klasses", _num_total_recorded_klasses);
960
961#ifndef PRODUCT
962 for (int i = 0; i < num; i++) {
963 ArchivableStaticFieldInfo* f = &fields[i];
964 verify_subgraph_from_static_field(f->klass, f->offset);
965 }
966 log_info(cds, heap)(" Verified %d references", _num_total_verifications);
967#endif
968}
969
970// At dump-time, find the location of all the non-null oop pointers in an archived heap
971// region. This way we can quickly relocate all the pointers without using
972// BasicOopIterateClosure at runtime.
973class FindEmbeddedNonNullPointers: public BasicOopIterateClosure {
974 narrowOop* _start;
975 BitMap *_oopmap;
976 int _num_total_oops;
977 int _num_null_oops;
978 public:
979 FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap)
980 : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {}
981
982 virtual bool should_verify_oops(void) {
983 return false;
984 }
985 virtual void do_oop(narrowOop* p) {
986 _num_total_oops ++;
987 narrowOop v = *p;
988 if (!CompressedOops::is_null(v)) {
989 size_t idx = p - _start;
990 _oopmap->set_bit(idx);
991 } else {
992 _num_null_oops ++;
993 }
994 }
995 virtual void do_oop(oop *p) {
996 ShouldNotReachHere();
997 }
998 int num_total_oops() const { return _num_total_oops; }
999 int num_null_oops() const { return _num_null_oops; }
1000};
1001
1002ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) {
1003 assert(UseCompressedOops, "must be");
1004 size_t num_bits = region.byte_size() / sizeof(narrowOop);
1005 ResourceBitMap oopmap(num_bits);
1006
1007 HeapWord* p = region.start();
1008 HeapWord* end = region.end();
1009 FindEmbeddedNonNullPointers finder((narrowOop*)p, &oopmap);
1010
1011 int num_objs = 0;
1012 while (p < end) {
1013 oop o = (oop)p;
1014 o->oop_iterate(&finder);
1015 p += o->size();
1016 ++ num_objs;
1017 }
1018
1019 log_info(cds, heap)("calculate_oopmap: objects = %6d, embedded oops = %7d, nulls = %7d",
1020 num_objs, finder.num_total_oops(), finder.num_null_oops());
1021 return oopmap;
1022}
1023
1024// Patch all the embedded oop pointers inside an archived heap region,
1025// to be consistent with the runtime oop encoding.
1026class PatchEmbeddedPointers: public BitMapClosure {
1027 narrowOop* _start;
1028
1029 public:
1030 PatchEmbeddedPointers(narrowOop* start) : _start(start) {}
1031
1032 bool do_bit(size_t offset) {
1033 narrowOop* p = _start + offset;
1034 narrowOop v = *p;
1035 assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time");
1036 oop o = HeapShared::decode_from_archive(v);
1037 RawAccess<IS_NOT_NULL>::oop_store(p, o);
1038 return true;
1039 }
1040};
1041
1042void HeapShared::patch_archived_heap_embedded_pointers(MemRegion region, address oopmap,
1043 size_t oopmap_size_in_bits) {
1044 BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits);
1045
1046#ifndef PRODUCT
1047 ResourceMark rm;
1048 ResourceBitMap checkBm = calculate_oopmap(region);
1049 assert(bm.is_same(checkBm), "sanity");
1050#endif
1051
1052 PatchEmbeddedPointers patcher((narrowOop*)region.start());
1053 bm.iterate(&patcher);
1054}
1055
1056#endif // INCLUDE_CDS_JAVA_HEAP
1057