2626#include " classfile/classLoaderDataShared.hpp"
2727#include " classfile/systemDictionaryShared.hpp"
2828#include " logging/log.hpp"
29- #include " logging/logMessage.hpp"
29+ #include " logging/logStream.hpp"
30+ #include " memory/allStatic.hpp"
3031#include " memory/archiveBuilder.hpp"
3132#include " memory/archiveUtils.hpp"
3233#include " memory/cppVtables.hpp"
3334#include " memory/dumpAllocStats.hpp"
35+ #include " memory/memRegion.hpp"
3436#include " memory/metaspaceShared.hpp"
3537#include " memory/resourceArea.hpp"
3638#include " oops/instanceKlass.hpp"
@@ -134,7 +136,7 @@ void ArchiveBuilder::SourceObjList::relocate(int i, ArchiveBuilder* builder) {
134136 _ptrmap.iterate(&relocator, start, end);
135137}
136138
137- ArchiveBuilder::ArchiveBuilder (DumpRegion* rw_region, DumpRegion* ro_region)
139+ ArchiveBuilder::ArchiveBuilder (DumpRegion* mc_region, DumpRegion* rw_region, DumpRegion* ro_region)
138140 : _rw_src_objs(), _ro_src_objs(), _src_obj_table(INITIAL_TABLE_SIZE) {
139141 assert (_singleton == NULL , " must be" );
140142 _singleton = this ;
@@ -148,6 +150,7 @@ ArchiveBuilder::ArchiveBuilder(DumpRegion* rw_region, DumpRegion* ro_region)
148150 _num_type_array_klasses = 0 ;
149151 _alloc_stats = new (ResourceObj::C_HEAP, mtClassShared) DumpAllocStats;
150152
153+ _mc_region = mc_region;
151154 _rw_region = rw_region;
152155 _ro_region = ro_region;
153156
@@ -294,13 +297,13 @@ void ArchiveBuilder::iterate_sorted_roots(MetaspaceClosure* it, bool is_relocati
294297 // original symbols.
295298 int num_symbols = _symbols->length ();
296299 for (i = 0 ; i < num_symbols; i++) {
297- it->push (& _symbols->at (i));
300+ it->push (_symbols->adr_at (i));
298301 }
299302 }
300303
301304 int num_klasses = _klasses->length ();
302305 for (i = 0 ; i < num_klasses; i++) {
303- it->push (& _klasses->at (i));
306+ it->push (_klasses->adr_at (i));
304307 }
305308
306309 iterate_roots (it, is_relocating_pointers);
@@ -592,6 +595,200 @@ void ArchiveBuilder::make_klasses_shareable() {
592595 }
593596}
594597
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+
595792void ArchiveBuilder::print_stats (int ro_all, int rw_all, int mc_all) {
596793 _alloc_stats->print_stats (ro_all, rw_all, mc_all);
597794}
0 commit comments