# HG changeset patch # User asaha # Date 1421970091 28800 # Node ID 344ff6e45a1e2960ac4a583f63ebfb54cd52e6b4 # Parent 64bad154d3b9b2b1afbc18428b2f061bc18e6b88# Parent 0e67683b700174eab71ea205d1cfa4f1cf4523ba Merge diff -r 64bad154d3b9 -r 344ff6e45a1e .hgtags --- a/.hgtags Tue Jan 20 12:29:04 2015 -0800 +++ b/.hgtags Thu Jan 22 15:41:31 2015 -0800 @@ -587,6 +587,8 @@ c3933f52eeb33f70ee562464edddfe9f01d944fd jdk8u40-b20 d2e9a6bec4f2eec8506eed16f7324992a85d8480 hs25.40-b24 25ec4a67433744bbe3406e5069e7fd1876ebbf2f jdk8u40-b21 +0f0cb4eeab2d871274f4ffdcd6017d2fdfa89238 hs25.40-b25 +0ee548a1cda08c884eccd563e2d5fdb6ee769b5a jdk8u40-b22 b95f13f05f553309cd74d6ccf8fcedb259c6716c jdk8u45-b00 41c3c456e326185053f0654be838f4b0bfb38078 jdk8u45-b01 626fd8c2eec63e2a2dff3839bfe12c0431bf00a4 jdk8u45-b02 diff -r 64bad154d3b9 -r 344ff6e45a1e make/hotspot_version diff -r 64bad154d3b9 -r 344ff6e45a1e src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp --- a/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Tue Jan 20 12:29:04 2015 -0800 +++ b/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Thu Jan 22 15:41:31 2015 -0800 @@ -45,7 +45,8 @@ #include "utilities/bitMap.inline.hpp" G1PageBasedVirtualSpace::G1PageBasedVirtualSpace() : _low_boundary(NULL), - _high_boundary(NULL), _committed(), _page_size(0), _special(false), _executable(false) { + _high_boundary(NULL), _committed(), _page_size(0), _special(false), + _dirty(), _executable(false) { } bool G1PageBasedVirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t page_size) { @@ -66,6 +67,9 @@ assert(_committed.size() == 0, "virtual space initialized more than once"); uintx size_in_bits = rs.size() / page_size; _committed.resize(size_in_bits, /* in_resource_area */ false); + if (_special) { + _dirty.resize(size_in_bits, /* in_resource_area */ false); + } return true; } @@ -84,6 +88,7 @@ _executable = false; _page_size = 0; _committed.resize(0, false); + _dirty.resize(0, false); } size_t G1PageBasedVirtualSpace::committed_size() const { @@ -120,31 +125,40 @@ return num * _page_size; } -MemRegion G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) { +bool G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) { // We need to make sure to commit all pages covered by the given area. guarantee(is_area_uncommitted(start, size_in_pages), "Specified area is not uncommitted"); - if (!_special) { + bool zero_filled = true; + uintptr_t end = start + size_in_pages; + + if (_special) { + // Check for dirty pages and update zero_filled if any found. + if (_dirty.get_next_one_offset(start,end) < end) { + zero_filled = false; + _dirty.clear_range(start, end); + } + } else { os::commit_memory_or_exit(page_start(start), byte_size_for_pages(size_in_pages), _executable, err_msg("Failed to commit pages from "SIZE_FORMAT" of length "SIZE_FORMAT, start, size_in_pages)); } - _committed.set_range(start, start + size_in_pages); + _committed.set_range(start, end); - MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize); - return result; + return zero_filled; } -MemRegion G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) { +void G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) { guarantee(is_area_committed(start, size_in_pages), "checking"); - if (!_special) { + if (_special) { + // Mark that memory is dirty. If committed again the memory might + // need to be cleared explicitly. + _dirty.set_range(start, start + size_in_pages); + } else { os::uncommit_memory(page_start(start), byte_size_for_pages(size_in_pages)); } _committed.clear_range(start, start + size_in_pages); - - MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize); - return result; } bool G1PageBasedVirtualSpace::contains(const void* p) const { @@ -154,7 +168,7 @@ #ifndef PRODUCT void G1PageBasedVirtualSpace::print_on(outputStream* out) { out->print ("Virtual space:"); - if (special()) out->print(" (pinned in memory)"); + if (_special) out->print(" (pinned in memory)"); out->cr(); out->print_cr(" - committed: " SIZE_FORMAT, committed_size()); out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); diff -r 64bad154d3b9 -r 344ff6e45a1e src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp --- a/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp Tue Jan 20 12:29:04 2015 -0800 +++ b/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp Thu Jan 22 15:41:31 2015 -0800 @@ -49,6 +49,12 @@ // Bitmap used for verification of commit/uncommit operations. BitMap _committed; + // Bitmap used to keep track of which pages are dirty or not for _special + // spaces. This is needed because for those spaces the underlying memory + // will only be zero filled the first time it is committed. Calls to commit + // will use this bitmap and return whether or not the memory is zero filled. + BitMap _dirty; + // Indicates that the entire space has been committed and pinned in memory, // os::commit_memory() or os::uncommit_memory() have no function. bool _special; @@ -71,12 +77,11 @@ public: // Commit the given area of pages starting at start being size_in_pages large. - MemRegion commit(uintptr_t start, size_t size_in_pages); + // Returns true if the given area is zero filled upon completion. + bool commit(uintptr_t start, size_t size_in_pages); // Uncommit the given area of pages starting at start being size_in_pages large. - MemRegion uncommit(uintptr_t start, size_t size_in_pages); - - bool special() const { return _special; } + void uncommit(uintptr_t start, size_t size_in_pages); // Initialization G1PageBasedVirtualSpace(); diff -r 64bad154d3b9 -r 344ff6e45a1e src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp --- a/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp Tue Jan 20 12:29:04 2015 -0800 +++ b/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp Thu Jan 22 15:41:31 2015 -0800 @@ -67,9 +67,9 @@ } virtual void commit_regions(uintptr_t start_idx, size_t num_regions) { - _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region); + bool zero_filled = _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region); _commit_map.set_range(start_idx, start_idx + num_regions); - fire_on_commit(start_idx, num_regions, true); + fire_on_commit(start_idx, num_regions, zero_filled); } virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) { @@ -117,8 +117,7 @@ uint old_refcount = _refcounts.get_by_index(idx); bool zero_filled = false; if (old_refcount == 0) { - _storage.commit(idx, 1); - zero_filled = true; + zero_filled = _storage.commit(idx, 1); } _refcounts.set_by_index(idx, old_refcount + 1); _commit_map.set_bit(i);