--- old/src/share/vm/memory/filemap.cpp 2017-08-08 17:40:44.576317019 -0400 +++ new/src/share/vm/memory/filemap.cpp 2017-08-08 17:40:43.260242224 -0400 @@ -461,22 +461,25 @@ write_bytes_aligned(base, (int)size); } -// Write the current archive heap region, which contains one or multiple GC(G1) regions. -// When current archive heap region size is smaller than one GC region of the dump time, -// all archive heap data is written out as one region. -// -// If the current archive heap region size is bigger than one GC region, there would be more -// than one GC regions allocated for archive heap data. The first/bottom GC region might -// be a partial GC region with the empty portion at the higher address within that region. -// The non-empty portion of the first region is written into the archive as one archive -// region. The rest are consecutive full GC regions if they exist, which can be written -// out in one chunk as another archive region. +// Write out the given archive heap memory regions. GC code combines multiple +// consequetive archive GC regions into one MemRegion whenever possible and +// produces the 'heap_mem' array. // -// Here's the mapping from (archive heap regions) -> (GrowableArray *regions). +// If the archive heap memory size is smaller than a single dump time GC region +// size, there is only one MemRegion in the array. +// +// If the archive heap memory size is bigger than one dump time GC region size, +// the 'heap_mem' array may contain more than one consolidated MemRegions. When +// the first/bottom archive GC region is a partial GC region(with the empty +// portion at the higher address within the region), one MemRegion is used for +// the bottom partial archive GC region. The rest of the consqusective archive +// GC regions are combined into another MemRegion. +// +// Here's the mapping from (archive heap GC regions) -> (GrowableArray *regions). // + We have 1 or more archive heap regions: ah0, ah1, ah2 ..... ahn -// + We have 2 consolidate heap memory regions: r0 and r1 +// + We have 1 or 2 consolidated heap memory regions: r0 and r1 // -// If there's a single archive heap region (ah0), then r0 == ah0, and r1 is empty. +// If there's a single archive GC region (ah0), then r0 == ah0, and r1 is empty. // Otherwise: // // "X" represented space that's occupied by heap objects. @@ -489,37 +492,33 @@ // ^^^ // | // +-- gap -void FileMapInfo::write_archive_heap_regions(GrowableArray *regions, - int first_region, int max_num_regions, - char** r0_start, char** r0_top, - char** r1_start, char** r1_top) { - int arr_len = regions == NULL ? 0 : regions->length(); - assert(max_num_regions <= 2, "this loop doesn't work for any other value"); - assert(arr_len <= max_num_regions, "number of memory regions exceeds maximum"); - - *r0_start = *r0_top = NULL; - *r1_start = *r1_top = NULL; - - for (int i = first_region, arr_idx = 0; i < first_region + max_num_regions; i++, arr_idx++) { +size_t FileMapInfo::write_archive_heap_regions(GrowableArray *heap_mem, + int first_region_id, int max_num_regions) { + assert(max_num_regions <= 2, "Only support maximum 2 memory regions"); + + int arr_len = heap_mem == NULL ? 0 : heap_mem->length(); + if(arr_len > max_num_regions) { + fail_stop("Unable to write archive heap memory regions: " + "number of memory regions exceeds maximum due to fragmentation"); + } + + size_t total_size = 0; + for (int i = first_region_id, arr_idx = 0; + i < first_region_id + max_num_regions; + i++, arr_idx++) { char* start = NULL; size_t size = 0; if (arr_idx < arr_len) { - start = (char*)regions->at(arr_idx).start(); - size = regions->at(arr_idx).byte_size(); - } - if (i == first_region) { - *r0_start = start; - *r0_top = start + size; - } else { - assert(i == first_region + 1, "must be"); - *r1_start = start; - *r1_top = start + size; + start = (char*)heap_mem->at(arr_idx).start(); + size = heap_mem->at(arr_idx).byte_size(); + total_size += size; } log_info(cds)("Archive heap region %d " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes", i, p2i(start), p2i(start + size), size); write_region(i, start, size, false, false); } + return total_size; } // Dump bytes to file -- at the current file position. @@ -687,7 +686,7 @@ // the references are updated by GC. // void FileMapInfo::map_heap_regions() { - if (MetaspaceShared::allow_archive_heap_object()) { + if (MetaspaceShared::is_heap_object_archiving_allowed()) { // Check that all the narrow oop and klass encodings match the archive if (narrow_oop_mode() != Universe::narrow_oop_mode() || narrow_oop_shift() != Universe::narrow_oop_shift() || @@ -734,7 +733,7 @@ } } -bool FileMapInfo::map_heap_data(MemRegion **mem_regions, int first, +bool FileMapInfo::map_heap_data(MemRegion **heap_mem, int first, int max, int* num, bool is_open_archive) { MemRegion * regions = new MemRegion[max]; struct FileMapInfo::FileMapHeader::space_info* si; @@ -805,7 +804,7 @@ } // the shared heap data is mapped successfully - *mem_regions = regions; + *heap_mem = regions; *num = region_num; return true; }