26
26
#include " classfile/classLoaderDataShared.hpp"
27
27
#include " classfile/systemDictionaryShared.hpp"
28
28
#include " logging/log.hpp"
29
- #include " logging/logMessage.hpp"
29
+ #include " logging/logStream.hpp"
30
+ #include " memory/allStatic.hpp"
30
31
#include " memory/archiveBuilder.hpp"
31
32
#include " memory/archiveUtils.hpp"
32
33
#include " memory/cppVtables.hpp"
33
34
#include " memory/dumpAllocStats.hpp"
35
+ #include " memory/memRegion.hpp"
34
36
#include " memory/metaspaceShared.hpp"
35
37
#include " memory/resourceArea.hpp"
36
38
#include " oops/instanceKlass.hpp"
@@ -134,7 +136,7 @@ void ArchiveBuilder::SourceObjList::relocate(int i, ArchiveBuilder* builder) {
134
136
_ptrmap.iterate(&relocator, start, end);
135
137
}
136
138
137
- ArchiveBuilder::ArchiveBuilder (DumpRegion* rw_region, DumpRegion* ro_region)
139
+ ArchiveBuilder::ArchiveBuilder (DumpRegion* mc_region, DumpRegion* rw_region, DumpRegion* ro_region)
138
140
: _rw_src_objs(), _ro_src_objs(), _src_obj_table(INITIAL_TABLE_SIZE) {
139
141
assert (_singleton == NULL , " must be" );
140
142
_singleton = this ;
@@ -148,6 +150,7 @@ ArchiveBuilder::ArchiveBuilder(DumpRegion* rw_region, DumpRegion* ro_region)
148
150
_num_type_array_klasses = 0 ;
149
151
_alloc_stats = new (ResourceObj::C_HEAP, mtClassShared) DumpAllocStats;
150
152
153
+ _mc_region = mc_region;
151
154
_rw_region = rw_region;
152
155
_ro_region = ro_region;
153
156
@@ -294,13 +297,13 @@ void ArchiveBuilder::iterate_sorted_roots(MetaspaceClosure* it, bool is_relocati
294
297
// original symbols.
295
298
int num_symbols = _symbols->length ();
296
299
for (i = 0 ; i < num_symbols; i++) {
297
- it->push (& _symbols->at (i));
300
+ it->push (_symbols->adr_at (i));
298
301
}
299
302
}
300
303
301
304
int num_klasses = _klasses->length ();
302
305
for (i = 0 ; i < num_klasses; i++) {
303
- it->push (& _klasses->at (i));
306
+ it->push (_klasses->adr_at (i));
304
307
}
305
308
306
309
iterate_roots (it, is_relocating_pointers);
@@ -592,6 +595,200 @@ void ArchiveBuilder::make_klasses_shareable() {
592
595
}
593
596
}
594
597
598
+ // Write detailed info to a mapfile to analyze contents of the archive.
599
+ // static dump:
600
+ // java -Xshare:dump -Xlog:cds+map=trace:file=cds.map:none:filesize=0
601
+ // dynamic dump:
602
+ // java -cp MyApp.jar -XX:ArchiveClassesAtExit=MyApp.jsa \
603
+ // -Xlog:cds+map=trace:file=cds.map:none:filesize=0 MyApp
604
+ //
605
+ // We need to do some address translation because the buffers used at dump time may be mapped to
606
+ // a different location at runtime. At dump time, the buffers may be at arbitrary locations
607
+ // picked by the OS. At runtime, we try to map at a fixed location (SharedBaseAddress). For
608
+ // consistency, we log everything using runtime addresses.
609
+ class ArchiveBuilder ::CDSMapLogger : AllStatic {
610
+ static intx buffer_to_runtime_delta () {
611
+ // Translate the buffers used by the MC/RW/RO regions to their eventual locations
612
+ // at runtime.
613
+ return _buffer_to_target_delta + MetaspaceShared::final_delta ();
614
+ }
615
+
616
+ // mc/rw/ro regions only
617
+ static void write_dump_region (const char * name, DumpRegion* region) {
618
+ address region_base = address (region->base ());
619
+ address region_top = address (region->top ());
620
+ write_region (name, region_base, region_top, region_base + buffer_to_runtime_delta ());
621
+ }
622
+
623
+ #define _LOG_PREFIX PTR_FORMAT " : @@ %-17s %d"
624
+
625
+ static void write_klass (Klass* k, address runtime_dest, const char * type_name, int bytes, Thread* THREAD) {
626
+ ResourceMark rm (THREAD);
627
+ log_debug (cds, map)(_LOG_PREFIX " %s" ,
628
+ p2i (runtime_dest), type_name, bytes, k->external_name ());
629
+ }
630
+ static void write_method (Method* m, address runtime_dest, const char * type_name, int bytes, Thread* THREAD) {
631
+ ResourceMark rm (THREAD);
632
+ log_debug (cds, map)(_LOG_PREFIX " %s" ,
633
+ p2i (runtime_dest), type_name, bytes, m->external_name ());
634
+ }
635
+
636
+ // rw/ro regions only
637
+ static void write_objects (DumpRegion* region, const ArchiveBuilder::SourceObjList* src_objs) {
638
+ address last_obj_base = address (region->base ());
639
+ address last_obj_end = address (region->base ());
640
+ address region_end = address (region->end ());
641
+ Thread* THREAD = Thread::current ();
642
+ for (int i = 0 ; i < src_objs->objs ()->length (); i++) {
643
+ SourceObjInfo* src_info = src_objs->at (i);
644
+ address src = src_info->orig_obj ();
645
+ address dest = src_info->dumped_addr ();
646
+ write_data (last_obj_base, dest, last_obj_base + buffer_to_runtime_delta ());
647
+ address runtime_dest = dest + buffer_to_runtime_delta ();
648
+ int bytes = src_info->size_in_bytes ();
649
+
650
+ MetaspaceObj::Type type = src_info->msotype ();
651
+ const char * type_name = MetaspaceObj::type_name (type);
652
+
653
+ switch (type) {
654
+ case MetaspaceObj::ClassType:
655
+ write_klass ((Klass*)src, runtime_dest, type_name, bytes, THREAD);
656
+ break ;
657
+ case MetaspaceObj::ConstantPoolType:
658
+ write_klass (((ConstantPool*)src)->pool_holder (),
659
+ runtime_dest, type_name, bytes, THREAD);
660
+ break ;
661
+ case MetaspaceObj::ConstantPoolCacheType:
662
+ write_klass (((ConstantPoolCache*)src)->constant_pool ()->pool_holder (),
663
+ runtime_dest, type_name, bytes, THREAD);
664
+ break ;
665
+ case MetaspaceObj::MethodType:
666
+ write_method ((Method*)src, runtime_dest, type_name, bytes, THREAD);
667
+ break ;
668
+ case MetaspaceObj::ConstMethodType:
669
+ write_method (((ConstMethod*)src)->method (), runtime_dest, type_name, bytes, THREAD);
670
+ break ;
671
+ case MetaspaceObj::SymbolType:
672
+ {
673
+ ResourceMark rm (THREAD);
674
+ Symbol* s = (Symbol*)src;
675
+ log_debug (cds, map)(_LOG_PREFIX " %s" , p2i (runtime_dest), type_name, bytes,
676
+ s->as_quoted_ascii ());
677
+ }
678
+ break ;
679
+ default :
680
+ log_debug (cds, map)(_LOG_PREFIX, p2i (runtime_dest), type_name, bytes);
681
+ break ;
682
+ }
683
+
684
+ last_obj_base = dest;
685
+ last_obj_end = dest + bytes;
686
+ }
687
+
688
+ write_data (last_obj_base, last_obj_end, last_obj_base + buffer_to_runtime_delta ());
689
+ if (last_obj_end < region_end) {
690
+ log_debug (cds, map)(PTR_FORMAT " : @@ Misc data " SIZE_FORMAT " bytes" ,
691
+ p2i (last_obj_end + buffer_to_runtime_delta ()),
692
+ size_t (region_end - last_obj_end));
693
+ write_data (last_obj_end, region_end, last_obj_end + buffer_to_runtime_delta ());
694
+ }
695
+ }
696
+
697
+ #undef _LOG_PREFIX
698
+
699
+ // Write information about a region, whose address at dump time is [base .. top). At
700
+ // runtime, this region will be mapped to runtime_base. runtime_base is 0 if this
701
+ // region will be mapped at os-selected addresses (such as the bitmap region), or will
702
+ // be accessed with os::read (the header).
703
+ static void write_region (const char * name, address base, address top, address runtime_base) {
704
+ size_t size = top - base;
705
+ base = runtime_base;
706
+ top = runtime_base + size;
707
+ log_info (cds, map)(" [%-18s " PTR_FORMAT " - " PTR_FORMAT " " SIZE_FORMAT_W (9 ) " bytes]" ,
708
+ name, p2i (base), p2i (top), size);
709
+ }
710
+
711
+ // open and closed archive regions
712
+ static void write_heap_region (const char * which, GrowableArray<MemRegion> *regions) {
713
+ for (int i = 0 ; i < regions->length (); i++) {
714
+ address start = address (regions->at (i).start ());
715
+ address end = address (regions->at (i).end ());
716
+ write_region (which, start, end, start);
717
+ write_data (start, end, start);
718
+ }
719
+ }
720
+
721
+ // Dump all the data [base...top). Pretend that the base address
722
+ // will be mapped to runtime_base at run-time.
723
+ static void write_data (address base, address top, address runtime_base) {
724
+ assert (top >= base, " must be" );
725
+
726
+ LogStreamHandle (Trace, cds, map) lsh;
727
+ if (lsh.is_enabled ()) {
728
+ os::print_hex_dump (&lsh, base, top, sizeof (address), 32 , runtime_base);
729
+ }
730
+ }
731
+
732
+ static void write_header (FileMapInfo* mapinfo) {
733
+ LogStreamHandle (Info, cds, map) lsh;
734
+ if (lsh.is_enabled ()) {
735
+ mapinfo->print (&lsh);
736
+ }
737
+ }
738
+
739
+ public:
740
+ static void write (ArchiveBuilder* builder, FileMapInfo* mapinfo,
741
+ GrowableArray<MemRegion> *closed_heap_regions,
742
+ GrowableArray<MemRegion> *open_heap_regions,
743
+ char * bitmap, size_t bitmap_size_in_bytes) {
744
+ log_info (cds, map)(" %s CDS archive map for %s" , DumpSharedSpaces ? " Static" : " Dynamic" , mapinfo->full_path ());
745
+
746
+ address header = address (mapinfo->header ());
747
+ address header_end = header + mapinfo->header ()->header_size ();
748
+ write_region (" header" , header, header_end, 0 );
749
+ write_header (mapinfo);
750
+ write_data (header, header_end, 0 );
751
+
752
+ DumpRegion* mc_region = builder->_mc_region ;
753
+ DumpRegion* rw_region = builder->_rw_region ;
754
+ DumpRegion* ro_region = builder->_ro_region ;
755
+
756
+ address mc = address (mc_region->base ());
757
+ address mc_end = address (mc_region->end ());
758
+ write_dump_region (" mc region" , mc_region);
759
+ write_data (mc, mc_end, mc + buffer_to_runtime_delta ());
760
+
761
+ write_dump_region (" rw region" , rw_region);
762
+ write_objects (rw_region, &builder->_rw_src_objs );
763
+
764
+ write_dump_region (" ro region" , ro_region);
765
+ write_objects (ro_region, &builder->_ro_src_objs );
766
+
767
+ address bitmap_end = address (bitmap + bitmap_size_in_bytes);
768
+ write_region (" bitmap" , address (bitmap), bitmap_end, 0 );
769
+ write_data (header, header_end, 0 );
770
+
771
+ if (closed_heap_regions != NULL ) {
772
+ write_heap_region (" closed heap region" , closed_heap_regions);
773
+ }
774
+ if (open_heap_regions != NULL ) {
775
+ write_heap_region (" open heap region" , open_heap_regions);
776
+ }
777
+
778
+ log_info (cds, map)(" [End of CDS archive map]" );
779
+ }
780
+ };
781
+
782
+ void ArchiveBuilder::write_cds_map_to_log (FileMapInfo* mapinfo,
783
+ GrowableArray<MemRegion> *closed_heap_regions,
784
+ GrowableArray<MemRegion> *open_heap_regions,
785
+ char * bitmap, size_t bitmap_size_in_bytes) {
786
+ if (log_is_enabled (Info, cds, map)) {
787
+ CDSMapLogger::write (this , mapinfo, closed_heap_regions, open_heap_regions,
788
+ bitmap, bitmap_size_in_bytes);
789
+ }
790
+ }
791
+
595
792
void ArchiveBuilder::print_stats (int ro_all, int rw_all, int mc_all) {
596
793
_alloc_stats->print_stats (ro_all, rw_all, mc_all);
597
794
}
0 commit comments