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/vmSymbols.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logMessage.hpp"
30 #include "logging/logStream.hpp"
31 #include "memory/heapShared.hpp"
32 #include "memory/iterator.inline.hpp"
33 #include "memory/metadataFactory.hpp"
34 #include "memory/metaspaceClosure.hpp"
35 #include "memory/metaspaceShared.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/compressedOops.inline.hpp"
38 #include "oops/oop.inline.hpp"
39
40 #if INCLUDE_CDS_JAVA_HEAP
41 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
42 int HeapShared::_num_archived_subgraph_info_records = 0;
43 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
44
45 // Currently there is only one class mirror (ArchivedModuleGraph) with archived
46 // sub-graphs.
47 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
48 KlassSubGraphInfo* info = _subgraph_info_list;
49 while (info != NULL) {
50 if (info->klass() == k) {
51 return info;
53 info = info->next();
54 }
55 return NULL;
56 }
57
58 // Get the subgraph_info for Klass k. A new subgraph_info is created if
59 // there is no existing one for k. The subgraph_info records the relocated
60 // Klass* of the original k.
61 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
62 Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
63 KlassSubGraphInfo* info = find_subgraph_info(relocated_k);
64 if (info != NULL) {
65 return info;
66 }
67
68 info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
69 _subgraph_info_list = info;
70 return info;
71 }
72
73 int HeapShared::num_of_subgraph_infos() {
74 int num = 0;
75 KlassSubGraphInfo* info = _subgraph_info_list;
76 while (info != NULL) {
77 num ++;
78 info = info->next();
79 }
80 return num;
81 }
82
83 // Add an entry field to the current KlassSubGraphInfo.
84 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
85 assert(DumpSharedSpaces, "dump time only");
86 if (_subgraph_entry_fields == NULL) {
87 _subgraph_entry_fields =
88 new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
89 }
90 _subgraph_entry_fields->append((juint)static_field_offset);
91 _subgraph_entry_fields->append(CompressedOops::encode(v));
92 }
294 CLEAR_PENDING_EXCEPTION;
295 // None of the field value will be set if there was an exception.
296 // The java code will not see any of the archived objects in the
297 // subgraphs referenced from k in this case.
298 return;
299 }
300
301 // Load the subgraph entry fields from the record and store them back to
302 // the corresponding fields within the mirror.
303 oop m = k->java_mirror();
304 Array<juint>* entry_field_records = record->entry_field_records();
305 if (entry_field_records != NULL) {
306 int efr_len = entry_field_records->length();
307 assert(efr_len % 2 == 0, "sanity");
308 for (i = 0; i < efr_len;) {
309 int field_offset = entry_field_records->at(i);
310 // The object refereced by the field becomes 'known' by GC from this
311 // point. All objects in the subgraph reachable from the object are
312 // also 'known' by GC.
313 oop v = MetaspaceShared::materialize_archived_object(
314 CompressedOops::decode(entry_field_records->at(i+1)));
315 m->obj_field_put(field_offset, v);
316 i += 2;
317 }
318 }
319
320 // Done. Java code can see the archived sub-graphs referenced from k's
321 // mirror after this point.
322 return;
323 }
324 }
325 }
326
327 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
328 int _level;
329 KlassSubGraphInfo* _subgraph_info;
330 oop _orig_referencing_obj;
331 oop _archived_referencing_obj;
332 public:
333 WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
334 oop orig, oop archived) : _level(level),
486 Klass *orig_k = f->klass();
487 subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
488 } else {
489 // The field contains null, we still need to record the entry point,
490 // so it can be restored at runtime.
491 subgraph_info->add_subgraph_entry_field(field_offset, NULL);
492 }
493 } else {
494 ShouldNotReachHere();
495 }
496 }
497
498 #define do_module_object_graph(archive_object_graph_do) \
499 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedSystemModules_offset(), T_OBJECT, CHECK); \
500 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedModuleFinder_offset(), T_OBJECT, CHECK); \
501 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK)
502
503 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
504 do_module_object_graph(archive_reachable_objects_from_static_field);
505 }
506 #endif // INCLUDE_CDS_JAVA_HEAP
|
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/vmSymbols.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logMessage.hpp"
30 #include "logging/logStream.hpp"
31 #include "memory/heapShared.inline.hpp"
32 #include "memory/iterator.inline.hpp"
33 #include "memory/metadataFactory.hpp"
34 #include "memory/metaspaceClosure.hpp"
35 #include "memory/metaspaceShared.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/compressedOops.inline.hpp"
38 #include "oops/oop.inline.hpp"
39
40 #if INCLUDE_CDS_JAVA_HEAP
41 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
42 int HeapShared::_num_archived_subgraph_info_records = 0;
43 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
44
45 // Currently there is only one class mirror (ArchivedModuleGraph) with archived
46 // sub-graphs.
47 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
48 KlassSubGraphInfo* info = _subgraph_info_list;
49 while (info != NULL) {
50 if (info->klass() == k) {
51 return info;
53 info = info->next();
54 }
55 return NULL;
56 }
57
58 // Get the subgraph_info for Klass k. A new subgraph_info is created if
59 // there is no existing one for k. The subgraph_info records the relocated
60 // Klass* of the original k.
61 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
62 Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
63 KlassSubGraphInfo* info = find_subgraph_info(relocated_k);
64 if (info != NULL) {
65 return info;
66 }
67
68 info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
69 _subgraph_info_list = info;
70 return info;
71 }
72
73 address HeapShared::_narrow_oop_base;
74 int HeapShared::_narrow_oop_shift;
75
76 int HeapShared::num_of_subgraph_infos() {
77 int num = 0;
78 KlassSubGraphInfo* info = _subgraph_info_list;
79 while (info != NULL) {
80 num ++;
81 info = info->next();
82 }
83 return num;
84 }
85
86 // Add an entry field to the current KlassSubGraphInfo.
87 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
88 assert(DumpSharedSpaces, "dump time only");
89 if (_subgraph_entry_fields == NULL) {
90 _subgraph_entry_fields =
91 new(ResourceObj::C_HEAP, mtClass) GrowableArray<juint>(10, true);
92 }
93 _subgraph_entry_fields->append((juint)static_field_offset);
94 _subgraph_entry_fields->append(CompressedOops::encode(v));
95 }
297 CLEAR_PENDING_EXCEPTION;
298 // None of the field value will be set if there was an exception.
299 // The java code will not see any of the archived objects in the
300 // subgraphs referenced from k in this case.
301 return;
302 }
303
304 // Load the subgraph entry fields from the record and store them back to
305 // the corresponding fields within the mirror.
306 oop m = k->java_mirror();
307 Array<juint>* entry_field_records = record->entry_field_records();
308 if (entry_field_records != NULL) {
309 int efr_len = entry_field_records->length();
310 assert(efr_len % 2 == 0, "sanity");
311 for (i = 0; i < efr_len;) {
312 int field_offset = entry_field_records->at(i);
313 // The object refereced by the field becomes 'known' by GC from this
314 // point. All objects in the subgraph reachable from the object are
315 // also 'known' by GC.
316 oop v = MetaspaceShared::materialize_archived_object(
317 entry_field_records->at(i+1));
318 m->obj_field_put(field_offset, v);
319 i += 2;
320 }
321 }
322
323 // Done. Java code can see the archived sub-graphs referenced from k's
324 // mirror after this point.
325 return;
326 }
327 }
328 }
329
330 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
331 int _level;
332 KlassSubGraphInfo* _subgraph_info;
333 oop _orig_referencing_obj;
334 oop _archived_referencing_obj;
335 public:
336 WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
337 oop orig, oop archived) : _level(level),
489 Klass *orig_k = f->klass();
490 subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
491 } else {
492 // The field contains null, we still need to record the entry point,
493 // so it can be restored at runtime.
494 subgraph_info->add_subgraph_entry_field(field_offset, NULL);
495 }
496 } else {
497 ShouldNotReachHere();
498 }
499 }
500
501 #define do_module_object_graph(archive_object_graph_do) \
502 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedSystemModules_offset(), T_OBJECT, CHECK); \
503 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedModuleFinder_offset(), T_OBJECT, CHECK); \
504 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK)
505
506 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
507 do_module_object_graph(archive_reachable_objects_from_static_field);
508 }
509
510 void HeapShared::init_narrow_oop_decoding(address base, int shift) {
511 _narrow_oop_base = base;
512 _narrow_oop_shift = shift;
513 }
514
515 #endif // INCLUDE_CDS_JAVA_HEAP
|