47 InstanceKlass* klass;
48 int offset;
49 BasicType type;
50 };
51
52 // A dump time sub-graph info for Klass _k. It includes the entry points
53 // (static fields in _k's mirror) of the archived sub-graphs reachable
54 // from _k's mirror. It also contains a list of Klasses of the objects
55 // within the sub-graphs.
56 class KlassSubGraphInfo: public CHeapObj<mtClass> {
57 private:
58 // The class that contains the static field(s) as the entry point(s)
59 // of archived object sub-graph(s).
60 Klass* _k;
61 // A list of classes need to be loaded and initialized before the archived
62 // object sub-graphs can be accessed at runtime.
63 GrowableArray<Klass*>* _subgraph_object_klasses;
64 // A list of _k's static fields as the entry points of archived sub-graphs.
65 // For each entry field, it is a tuple of field_offset, field_value and
66 // is_closed_archive flag.
67 GrowableArray<juint>* _subgraph_entry_fields;
68
69 bool _is_full_module_graph;
70 public:
71 KlassSubGraphInfo(Klass* k, bool is_full_module_graph) :
72 _k(k), _subgraph_object_klasses(NULL),
73 _subgraph_entry_fields(NULL),
74 _is_full_module_graph(is_full_module_graph) {}
75 ~KlassSubGraphInfo() {
76 if (_subgraph_object_klasses != NULL) {
77 delete _subgraph_object_klasses;
78 }
79 if (_subgraph_entry_fields != NULL) {
80 delete _subgraph_entry_fields;
81 }
82 };
83
84 Klass* klass() { return _k; }
85 GrowableArray<Klass*>* subgraph_object_klasses() {
86 return _subgraph_object_klasses;
87 }
88 GrowableArray<juint>* subgraph_entry_fields() {
89 return _subgraph_entry_fields;
90 }
91 void add_subgraph_entry_field(int static_field_offset, oop v,
92 bool is_closed_archive);
93 void add_subgraph_object_klass(Klass *orig_k, Klass *relocated_k);
94 int num_subgraph_object_klasses() {
95 return _subgraph_object_klasses == NULL ? 0 :
96 _subgraph_object_klasses->length();
97 }
98 bool is_full_module_graph() const { return _is_full_module_graph; }
99 };
100
101 // An archived record of object sub-graphs reachable from static
102 // fields within _k's mirror. The record is reloaded from the archive
103 // at runtime.
104 class ArchivedKlassSubGraphInfoRecord {
105 private:
106 Klass* _k;
107 bool _is_full_module_graph;
108
109 // contains pairs of field offset and value for each subgraph entry field
110 Array<juint>* _entry_field_records;
111
112 // klasses of objects in archived sub-graphs referenced from the entry points
113 // (static fields) in the containing class
114 Array<Klass*>* _subgraph_object_klasses;
115 public:
116 ArchivedKlassSubGraphInfoRecord() :
117 _k(NULL), _entry_field_records(NULL), _subgraph_object_klasses(NULL) {}
118 void init(KlassSubGraphInfo* info);
119 Klass* klass() const { return _k; }
120 Array<juint>* entry_field_records() const { return _entry_field_records; }
121 Array<Klass*>* subgraph_object_klasses() const { return _subgraph_object_klasses; }
122 bool is_full_module_graph() const { return _is_full_module_graph; }
123 };
124 #endif // INCLUDE_CDS_JAVA_HEAP
125
126 class HeapShared: AllStatic {
127 friend class VerifySharedOopClosure;
128 private:
129
130 #if INCLUDE_CDS_JAVA_HEAP
131 static bool _closed_archive_heap_region_mapped;
132 static bool _open_archive_heap_region_mapped;
133 static bool _archive_heap_region_fixed;
134 static DumpedInternedStrings *_dumped_interned_strings;
135
136 public:
137 static bool oop_equals(oop const& p1, oop const& p2) {
138 return p1 == p2;
139 }
140 static unsigned oop_hash(oop const& p);
141 static unsigned string_oop_hash(oop const& string) {
142 return java_lang_String::hash_code(string);
237 // Statistics (for one round of start_recording_subgraph ... done_recording_subgraph)
238 static int _num_new_walked_objs;
239 static int _num_new_archived_objs;
240 static int _num_old_recorded_klasses;
241
242 // Statistics (for all archived subgraphs)
243 static int _num_total_subgraph_recordings;
244 static int _num_total_walked_objs;
245 static int _num_total_archived_objs;
246 static int _num_total_recorded_klasses;
247 static int _num_total_verifications;
248
249 static void start_recording_subgraph(InstanceKlass *k, const char* klass_name,
250 bool is_full_module_graph);
251 static void done_recording_subgraph(InstanceKlass *k, const char* klass_name);
252
253 static bool has_been_seen_during_subgraph_recording(oop obj);
254 static void set_has_been_seen_during_subgraph_recording(oop obj);
255
256 static void check_module_oop(oop orig_module_obj);
257
258 public:
259 static void reset_archived_object_states(TRAPS);
260 static void create_archived_object_cache() {
261 _archived_object_cache =
262 new (ResourceObj::C_HEAP, mtClass)ArchivedObjectCache();
263 }
264 static void destroy_archived_object_cache() {
265 delete _archived_object_cache;
266 _archived_object_cache = NULL;
267 }
268 static ArchivedObjectCache* archived_object_cache() {
269 return _archived_object_cache;
270 }
271
272 static oop find_archived_heap_object(oop obj);
273 static oop archive_heap_object(oop obj, Thread* THREAD);
274 static oop materialize_archived_object(narrowOop v);
275
276 static void archive_klass_objects(Thread* THREAD);
277
278 static void set_archive_heap_region_fixed() {
279 _archive_heap_region_fixed = true;
280 }
281 static bool archive_heap_region_fixed() {
282 return _archive_heap_region_fixed;
283 }
284
285 static void archive_java_heap_objects(GrowableArray<MemRegion> *closed,
286 GrowableArray<MemRegion> *open);
287 static void copy_closed_archive_heap_objects(GrowableArray<MemRegion> * closed_archive);
288 static void copy_open_archive_heap_objects(GrowableArray<MemRegion> * open_archive);
289
290 static oop archive_reachable_objects_from(int level,
291 KlassSubGraphInfo* subgraph_info,
292 oop orig_obj,
293 bool is_closed_archive,
294 TRAPS);
295
296 static ResourceBitMap calculate_oopmap(MemRegion region);
297 static void add_to_dumped_interned_strings(oop string);
298 #endif // INCLUDE_CDS_JAVA_HEAP
299
300 public:
301 static void run_full_gc_in_vm_thread() NOT_CDS_JAVA_HEAP_RETURN;
302
303 static bool is_heap_object_archiving_allowed() {
304 CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);)
305 NOT_CDS_JAVA_HEAP(return false;)
306 }
307
308 static bool is_heap_region(int idx) {
309 CDS_JAVA_HEAP_ONLY(return (idx >= MetaspaceShared::first_closed_archive_heap_region &&
310 idx <= MetaspaceShared::last_open_archive_heap_region));
311 NOT_CDS_JAVA_HEAP_RETURN_(false);
312 }
313
314 static void set_closed_archive_heap_region_mapped() {
315 CDS_JAVA_HEAP_ONLY(_closed_archive_heap_region_mapped = true);
316 NOT_CDS_JAVA_HEAP_RETURN;
317 }
318 static bool closed_archive_heap_region_mapped() {
319 CDS_JAVA_HEAP_ONLY(return _closed_archive_heap_region_mapped);
320 NOT_CDS_JAVA_HEAP_RETURN_(false);
321 }
322 static void set_open_archive_heap_region_mapped() {
323 CDS_JAVA_HEAP_ONLY(_open_archive_heap_region_mapped = true);
324 NOT_CDS_JAVA_HEAP_RETURN;
325 }
326 static bool open_archive_heap_region_mapped() {
327 CDS_JAVA_HEAP_ONLY(return _open_archive_heap_region_mapped);
328 NOT_CDS_JAVA_HEAP_RETURN_(false);
329 }
330
331 static void fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
332
333 inline static bool is_archived_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
334
335 static void initialize_from_archived_subgraph(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
336
337 // NarrowOops stored in the CDS archive may use a different encoding scheme
338 // than CompressedOops::{base,shift} -- see FileMapInfo::map_heap_regions_impl.
339 // To decode them, do not use CompressedOops::decode_not_null. Use this
340 // function instead.
341 inline static oop decode_from_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
342
343 static void init_narrow_oop_decoding(address base, int shift) NOT_CDS_JAVA_HEAP_RETURN;
344
345 static void patch_archived_heap_embedded_pointers(MemRegion mem, address oopmap,
346 size_t oopmap_in_bits) NOT_CDS_JAVA_HEAP_RETURN;
347
348 static void init_for_dumping(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
349 static void init_subgraph_entry_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
350 static void write_subgraph_info_table() NOT_CDS_JAVA_HEAP_RETURN;
351 static void serialize_subgraph_info_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
352 };
353
354 #if INCLUDE_CDS_JAVA_HEAP
|
47 InstanceKlass* klass;
48 int offset;
49 BasicType type;
50 };
51
52 // A dump time sub-graph info for Klass _k. It includes the entry points
53 // (static fields in _k's mirror) of the archived sub-graphs reachable
54 // from _k's mirror. It also contains a list of Klasses of the objects
55 // within the sub-graphs.
56 class KlassSubGraphInfo: public CHeapObj<mtClass> {
57 private:
58 // The class that contains the static field(s) as the entry point(s)
59 // of archived object sub-graph(s).
60 Klass* _k;
61 // A list of classes need to be loaded and initialized before the archived
62 // object sub-graphs can be accessed at runtime.
63 GrowableArray<Klass*>* _subgraph_object_klasses;
64 // A list of _k's static fields as the entry points of archived sub-graphs.
65 // For each entry field, it is a tuple of field_offset, field_value and
66 // is_closed_archive flag.
67 GrowableArray<int>* _subgraph_entry_fields;
68
69 // Does this KlassSubGraphInfo belong to the arcived full module graph
70 bool _is_full_module_graph;
71
72 // Does this KlassSubGraphInfo references any classes that were loaded while
73 // JvmtiExport::is_early_phase()!=true. If so, this KlassSubGraphInfo cannot be
74 // used at runtime if JVMTI ClassFileLoadHook is enabled.
75 bool _has_non_early_klasses;
76 static bool is_non_early_klass(Klass* k);
77
78 public:
79 KlassSubGraphInfo(Klass* k, bool is_full_module_graph) :
80 _k(k), _subgraph_object_klasses(NULL),
81 _subgraph_entry_fields(NULL),
82 _is_full_module_graph(is_full_module_graph),
83 _has_non_early_klasses(false) {}
84 ~KlassSubGraphInfo() {
85 if (_subgraph_object_klasses != NULL) {
86 delete _subgraph_object_klasses;
87 }
88 if (_subgraph_entry_fields != NULL) {
89 delete _subgraph_entry_fields;
90 }
91 };
92
93 Klass* klass() { return _k; }
94 GrowableArray<Klass*>* subgraph_object_klasses() {
95 return _subgraph_object_klasses;
96 }
97 GrowableArray<int>* subgraph_entry_fields() {
98 return _subgraph_entry_fields;
99 }
100 void add_subgraph_entry_field(int static_field_offset, oop v,
101 bool is_closed_archive);
102 void add_subgraph_object_klass(Klass *orig_k, Klass *relocated_k);
103 int num_subgraph_object_klasses() {
104 return _subgraph_object_klasses == NULL ? 0 :
105 _subgraph_object_klasses->length();
106 }
107 bool is_full_module_graph() const { return _is_full_module_graph; }
108 bool has_non_early_klasses() const { return _has_non_early_klasses; }
109 };
110
111 // An archived record of object sub-graphs reachable from static
112 // fields within _k's mirror. The record is reloaded from the archive
113 // at runtime.
114 class ArchivedKlassSubGraphInfoRecord {
115 private:
116 Klass* _k;
117 bool _is_full_module_graph;
118 bool _has_non_early_klasses;
119
120 // contains pairs of field offset and value for each subgraph entry field
121 Array<int>* _entry_field_records;
122
123 // klasses of objects in archived sub-graphs referenced from the entry points
124 // (static fields) in the containing class
125 Array<Klass*>* _subgraph_object_klasses;
126 public:
127 ArchivedKlassSubGraphInfoRecord() :
128 _k(NULL), _entry_field_records(NULL), _subgraph_object_klasses(NULL) {}
129 void init(KlassSubGraphInfo* info);
130 Klass* klass() const { return _k; }
131 Array<int>* entry_field_records() const { return _entry_field_records; }
132 Array<Klass*>* subgraph_object_klasses() const { return _subgraph_object_klasses; }
133 bool is_full_module_graph() const { return _is_full_module_graph; }
134 bool has_non_early_klasses() const { return _has_non_early_klasses; }
135 };
136 #endif // INCLUDE_CDS_JAVA_HEAP
137
138 class HeapShared: AllStatic {
139 friend class VerifySharedOopClosure;
140 private:
141
142 #if INCLUDE_CDS_JAVA_HEAP
143 static bool _closed_archive_heap_region_mapped;
144 static bool _open_archive_heap_region_mapped;
145 static bool _archive_heap_region_fixed;
146 static DumpedInternedStrings *_dumped_interned_strings;
147
148 public:
149 static bool oop_equals(oop const& p1, oop const& p2) {
150 return p1 == p2;
151 }
152 static unsigned oop_hash(oop const& p);
153 static unsigned string_oop_hash(oop const& string) {
154 return java_lang_String::hash_code(string);
249 // Statistics (for one round of start_recording_subgraph ... done_recording_subgraph)
250 static int _num_new_walked_objs;
251 static int _num_new_archived_objs;
252 static int _num_old_recorded_klasses;
253
254 // Statistics (for all archived subgraphs)
255 static int _num_total_subgraph_recordings;
256 static int _num_total_walked_objs;
257 static int _num_total_archived_objs;
258 static int _num_total_recorded_klasses;
259 static int _num_total_verifications;
260
261 static void start_recording_subgraph(InstanceKlass *k, const char* klass_name,
262 bool is_full_module_graph);
263 static void done_recording_subgraph(InstanceKlass *k, const char* klass_name);
264
265 static bool has_been_seen_during_subgraph_recording(oop obj);
266 static void set_has_been_seen_during_subgraph_recording(oop obj);
267
268 static void check_module_oop(oop orig_module_obj);
269 static void copy_roots();
270
271 static void resolve_classes_for_subgraphs(ArchivableStaticFieldInfo fields[],
272 int num, TRAPS);
273 static void resolve_classes_for_subgraph_of(Klass* k, TRAPS);
274 static void clear_archived_roots_of(Klass* k);
275 static const ArchivedKlassSubGraphInfoRecord*
276 resolve_or_init_classes_for_subgraph_of(Klass* k, bool do_init, TRAPS);
277 static void resolve_or_init(Klass* k, bool do_init, TRAPS);
278 static void init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record, TRAPS);
279 public:
280 static void reset_archived_object_states(TRAPS);
281 static void create_archived_object_cache() {
282 _archived_object_cache =
283 new (ResourceObj::C_HEAP, mtClass)ArchivedObjectCache();
284 }
285 static void destroy_archived_object_cache() {
286 delete _archived_object_cache;
287 _archived_object_cache = NULL;
288 }
289 static ArchivedObjectCache* archived_object_cache() {
290 return _archived_object_cache;
291 }
292
293 static oop find_archived_heap_object(oop obj);
294 static oop archive_heap_object(oop obj, Thread* THREAD);
295 static oop materialize_archived_object(narrowOop v);
296
297 static void archive_klass_objects(Thread* THREAD);
298
299 static void set_archive_heap_region_fixed() {
300 _archive_heap_region_fixed = true;
301 }
302 static bool archive_heap_region_fixed() {
303 return _archive_heap_region_fixed;
304 }
305
306 static void archive_java_heap_objects(GrowableArray<MemRegion> *closed,
307 GrowableArray<MemRegion> *open);
308 static void copy_closed_archive_heap_objects(GrowableArray<MemRegion> * closed_archive);
309 static void copy_open_archive_heap_objects(GrowableArray<MemRegion> * open_archive);
310
311 static oop archive_reachable_objects_from(int level,
312 KlassSubGraphInfo* subgraph_info,
313 oop orig_obj,
314 bool is_closed_archive,
315 TRAPS);
316
317 static ResourceBitMap calculate_oopmap(MemRegion region);
318 static void add_to_dumped_interned_strings(oop string);
319
320 // We use the HeapShared::roots() array to make sure that objects stored in the
321 // archived heap regions are not prematurely collected. These roots include:
322 //
323 // - mirrors of classes that have not yet been loaded.
324 // - ConstantPool::resolved_references() of classes that have not yet been loaded.
325 // - ArchivedKlassSubGraphInfoRecords that have not been initialized
326 // - java.lang.Module objects that have not yet been added to the module graph
327 //
328 // When a mirror M becomes referenced by a newly loaded class K, M will be removed
329 // from HeapShared::roots() via clear_root(), and K will be responsible for
330 // keeping M alive.
331 //
332 // Other types of roots are also cleared similarly when they become referenced.
333
334 // Dump-time only. Returns the index of the root, which can be used at run time to read
335 // the root using get_root(index, ...).
336 static int append_root(oop obj);
337
338 // Dump-time and runtime
339 static objArrayOop roots();
340 static oop get_root(int index, bool clear=false);
341
342 // Run-time only
343 static void set_roots(narrowOop roots);
344 static void clear_root(int index);
345 #endif // INCLUDE_CDS_JAVA_HEAP
346
347 public:
348 static void run_full_gc_in_vm_thread() NOT_CDS_JAVA_HEAP_RETURN;
349
350 static bool is_heap_object_archiving_allowed() {
351 CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);)
352 NOT_CDS_JAVA_HEAP(return false;)
353 }
354
355 static bool is_heap_region(int idx) {
356 CDS_JAVA_HEAP_ONLY(return (idx >= MetaspaceShared::first_closed_archive_heap_region &&
357 idx <= MetaspaceShared::last_open_archive_heap_region));
358 NOT_CDS_JAVA_HEAP_RETURN_(false);
359 }
360
361 static void set_closed_archive_heap_region_mapped() {
362 CDS_JAVA_HEAP_ONLY(_closed_archive_heap_region_mapped = true);
363 NOT_CDS_JAVA_HEAP_RETURN;
364 }
365 static bool closed_archive_heap_region_mapped() {
366 CDS_JAVA_HEAP_ONLY(return _closed_archive_heap_region_mapped);
367 NOT_CDS_JAVA_HEAP_RETURN_(false);
368 }
369 static void set_open_archive_heap_region_mapped() {
370 CDS_JAVA_HEAP_ONLY(_open_archive_heap_region_mapped = true);
371 NOT_CDS_JAVA_HEAP_RETURN;
372 }
373 static bool open_archive_heap_region_mapped() {
374 CDS_JAVA_HEAP_ONLY(return _open_archive_heap_region_mapped);
375 NOT_CDS_JAVA_HEAP_RETURN_(false);
376 }
377 static bool is_mapped() {
378 return closed_archive_heap_region_mapped() && open_archive_heap_region_mapped();
379 }
380
381 static void fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
382
383 inline static bool is_archived_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
384
385 static void resolve_classes(TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
386 static void initialize_from_archived_subgraph(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
387
388 // NarrowOops stored in the CDS archive may use a different encoding scheme
389 // than CompressedOops::{base,shift} -- see FileMapInfo::map_heap_regions_impl.
390 // To decode them, do not use CompressedOops::decode_not_null. Use this
391 // function instead.
392 inline static oop decode_from_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
393
394 static void init_narrow_oop_decoding(address base, int shift) NOT_CDS_JAVA_HEAP_RETURN;
395
396 static void patch_archived_heap_embedded_pointers(MemRegion mem, address oopmap,
397 size_t oopmap_in_bits) NOT_CDS_JAVA_HEAP_RETURN;
398
399 static void init_for_dumping(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
400 static void init_subgraph_entry_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
401 static void write_subgraph_info_table() NOT_CDS_JAVA_HEAP_RETURN;
402 static void serialize_subgraph_info_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
403 };
404
405 #if INCLUDE_CDS_JAVA_HEAP
|