Skip to content

Commit d1e94ee

Browse files
committed
8253909: Implement detailed map file for CDS
Reviewed-by: stuefe, ccheung
1 parent 7733a0e commit d1e94ee

File tree

10 files changed

+376
-60
lines changed

10 files changed

+376
-60
lines changed

src/hotspot/share/logging/logTag.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
LOG_TAG(loader) \
9999
LOG_TAG(logging) \
100100
LOG_TAG(malloc) \
101+
LOG_TAG(map) \
101102
LOG_TAG(mark) \
102103
LOG_TAG(marking) \
103104
LOG_TAG(membername) \

src/hotspot/share/memory/archiveBuilder.cpp

Lines changed: 201 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
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+
595792
void ArchiveBuilder::print_stats(int ro_all, int rw_all, int mc_all) {
596793
_alloc_stats->print_stats(ro_all, rw_all, mc_all);
597794
}

src/hotspot/share/memory/archiveBuilder.hpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
#include "utilities/resourceHash.hpp"
3535

3636
class CHeapBitMap;
37+
class DumpAllocStats;
38+
class FileMapInfo;
3739
class Klass;
40+
class MemRegion;
3841
class Symbol;
39-
class DumpAllocStats;
4042

4143
class ArchiveBuilder : public StackObj {
4244
public:
@@ -68,11 +70,18 @@ class ArchiveBuilder : public StackObj {
6870
uintx _ptrmap_end; // The bit-offset of the end of this object (exclusive)
6971
bool _read_only;
7072
FollowMode _follow_mode;
73+
int _size_in_bytes;
74+
MetaspaceObj::Type _msotype;
7175
address _dumped_addr; // Address this->obj(), as used by the dumped archive.
76+
address _orig_obj; // The value of the original object (_ref->obj()) when this
77+
// SourceObjInfo was created. Note that _ref->obj() may change
78+
// later if _ref is relocated.
7279

7380
public:
7481
SourceObjInfo(MetaspaceClosure::Ref* ref, bool read_only, FollowMode follow_mode) :
75-
_ref(ref), _ptrmap_start(0), _ptrmap_end(0), _read_only(read_only), _follow_mode(follow_mode) {
82+
_ref(ref), _ptrmap_start(0), _ptrmap_end(0), _read_only(read_only), _follow_mode(follow_mode),
83+
_size_in_bytes(ref->size() * BytesPerWord), _msotype(ref->msotype()),
84+
_orig_obj(ref->obj()) {
7685
if (follow_mode == point_to_it) {
7786
_dumped_addr = ref->obj();
7887
} else {
@@ -93,8 +102,10 @@ class ArchiveBuilder : public StackObj {
93102
uintx ptrmap_start() const { return _ptrmap_start; } // inclusive
94103
uintx ptrmap_end() const { return _ptrmap_end; } // exclusive
95104
bool read_only() const { return _read_only; }
96-
int size_in_bytes() const { return _ref->size() * BytesPerWord; }
105+
int size_in_bytes() const { return _size_in_bytes; }
106+
address orig_obj() const { return _orig_obj; }
97107
address dumped_addr() const { return _dumped_addr; }
108+
MetaspaceObj::Type msotype() const { return _msotype; }
98109

99110
// convenience accessor
100111
address obj() const { return ref()->obj(); }
@@ -127,9 +138,12 @@ class ArchiveBuilder : public StackObj {
127138
}
128139
};
129140

141+
class CDSMapLogger;
142+
130143
static const int INITIAL_TABLE_SIZE = 15889;
131144
static const int MAX_TABLE_SIZE = 1000000;
132145

146+
DumpRegion* _mc_region;
133147
DumpRegion* _rw_region;
134148
DumpRegion* _ro_region;
135149

@@ -180,19 +194,12 @@ class ArchiveBuilder : public StackObj {
180194

181195
bool is_excluded(Klass* k);
182196
void clean_up_src_obj_table();
183-
184197
protected:
185198
virtual void iterate_roots(MetaspaceClosure* it, bool is_relocating_pointers) = 0;
186199

187200
// Conservative estimate for number of bytes needed for:
188201
size_t _estimated_metsapceobj_bytes; // all archived MetsapceObj's.
189202

190-
void set_dump_regions(DumpRegion* rw_region, DumpRegion* ro_region) {
191-
assert(_rw_region == NULL && _ro_region == NULL, "do not change");
192-
_rw_region = rw_region;
193-
_ro_region = ro_region;
194-
}
195-
196203
protected:
197204
DumpRegion* _current_dump_space;
198205
address _alloc_bottom;
@@ -225,7 +232,7 @@ class ArchiveBuilder : public StackObj {
225232
}
226233

227234
public:
228-
ArchiveBuilder(DumpRegion* rw_region, DumpRegion* ro_region);
235+
ArchiveBuilder(DumpRegion* mc_region, DumpRegion* rw_region, DumpRegion* ro_region);
229236
~ArchiveBuilder();
230237

231238
void gather_klasses_and_symbols();
@@ -240,6 +247,11 @@ class ArchiveBuilder : public StackObj {
240247
void relocate_pointers();
241248
void relocate_well_known_klasses();
242249
void make_klasses_shareable();
250+
void write_cds_map_to_log(FileMapInfo* mapinfo,
251+
GrowableArray<MemRegion> *closed_heap_regions,
252+
GrowableArray<MemRegion> *open_heap_regions,
253+
char* bitmap, size_t bitmap_size_in_bytes);
254+
243255
address get_dumped_addr(address src_obj) const;
244256

245257
// All klasses and symbols that will be copied into the archive

src/hotspot/share/memory/dynamicArchive.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ class DynamicArchiveBuilder : public ArchiveBuilder {
123123
}
124124

125125
public:
126-
DynamicArchiveBuilder() : ArchiveBuilder(NULL, NULL) {
126+
DynamicArchiveBuilder() : ArchiveBuilder(MetaspaceShared::misc_code_dump_space(),
127+
MetaspaceShared::read_write_dump_space(),
128+
MetaspaceShared::read_only_dump_space()) {
127129
_estimated_hashtable_bytes = 0;
128130
_estimated_trampoline_bytes = 0;
129131

@@ -177,7 +179,6 @@ class DynamicArchiveBuilder : public ArchiveBuilder {
177179

178180
// rw space starts ...
179181
address reserved_bottom = reserve_space_and_init_buffer_to_target_delta();
180-
set_dump_regions(MetaspaceShared::read_write_dump_space(), MetaspaceShared::read_only_dump_space());
181182
init_header(reserved_bottom);
182183

183184
CHeapBitMap ptrmap;
@@ -566,12 +567,17 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) {
566567
// Now write the archived data including the file offsets.
567568
const char* archive_name = Arguments::GetSharedDynamicArchivePath();
568569
dynamic_info->open_for_write(archive_name);
569-
MetaspaceShared::write_core_archive_regions(dynamic_info, NULL, NULL);
570+
size_t bitmap_size_in_bytes;
571+
char* bitmap = MetaspaceShared::write_core_archive_regions(dynamic_info, NULL, NULL, bitmap_size_in_bytes);
570572
dynamic_info->set_final_requested_base((char*)MetaspaceShared::requested_base_address());
571573
dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
572574
dynamic_info->write_header();
573575
dynamic_info->close();
574576

577+
write_cds_map_to_log(dynamic_info, NULL, NULL,
578+
bitmap, bitmap_size_in_bytes);
579+
FREE_C_HEAP_ARRAY(char, bitmap);
580+
575581
address base = to_target(_alloc_bottom);
576582
address top = address(current_dump_space()->top()) + _buffer_to_target_delta;
577583
size_t file_size = pointer_delta(top, base, sizeof(char));

0 commit comments

Comments
 (0)