8062063: Usage of UseHugeTLBFS, UseLargePagesInMetaspace and huge SurvivorAlignmentInBytes cause crashes in CMBitMapClosure::do_bit

Mon, 12 Jan 2015 15:24:29 +0100

author
sjohanss
date
Mon, 12 Jan 2015 15:24:29 +0100
changeset 7509
ae52ee069062
parent 7508
5dd74b444f38
child 7510
0f0cb4eeab2d

8062063: Usage of UseHugeTLBFS, UseLargePagesInMetaspace and huge SurvivorAlignmentInBytes cause crashes in CMBitMapClosure::do_bit
Summary: Making sure committed memory is cleared when re-committed, even if using large pages.
Reviewed-by: jwilhelm, tschatzl

src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp	Fri Jan 16 11:00:29 2015 -0800
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp	Mon Jan 12 15:24:29 2015 +0100
     1.3 @@ -45,7 +45,8 @@
     1.4  #include "utilities/bitMap.inline.hpp"
     1.5  
     1.6  G1PageBasedVirtualSpace::G1PageBasedVirtualSpace() : _low_boundary(NULL),
     1.7 -  _high_boundary(NULL), _committed(), _page_size(0), _special(false), _executable(false) {
     1.8 +  _high_boundary(NULL), _committed(), _page_size(0), _special(false),
     1.9 +  _dirty(), _executable(false) {
    1.10  }
    1.11  
    1.12  bool G1PageBasedVirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t page_size) {
    1.13 @@ -66,6 +67,9 @@
    1.14    assert(_committed.size() == 0, "virtual space initialized more than once");
    1.15    uintx size_in_bits = rs.size() / page_size;
    1.16    _committed.resize(size_in_bits, /* in_resource_area */ false);
    1.17 +  if (_special) {
    1.18 +    _dirty.resize(size_in_bits, /* in_resource_area */ false);
    1.19 +  }
    1.20  
    1.21    return true;
    1.22  }
    1.23 @@ -84,6 +88,7 @@
    1.24    _executable             = false;
    1.25    _page_size              = 0;
    1.26    _committed.resize(0, false);
    1.27 +  _dirty.resize(0, false);
    1.28  }
    1.29  
    1.30  size_t G1PageBasedVirtualSpace::committed_size() const {
    1.31 @@ -120,31 +125,40 @@
    1.32    return num * _page_size;
    1.33  }
    1.34  
    1.35 -MemRegion G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
    1.36 +bool G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
    1.37    // We need to make sure to commit all pages covered by the given area.
    1.38    guarantee(is_area_uncommitted(start, size_in_pages), "Specified area is not uncommitted");
    1.39  
    1.40 -  if (!_special) {
    1.41 +  bool zero_filled = true;
    1.42 +  uintptr_t end = start + size_in_pages;
    1.43 +
    1.44 +  if (_special) {
    1.45 +    // Check for dirty pages and update zero_filled if any found.
    1.46 +    if (_dirty.get_next_one_offset(start,end) < end) {
    1.47 +      zero_filled = false;
    1.48 +      _dirty.clear_range(start, end);
    1.49 +    }
    1.50 +  } else {
    1.51      os::commit_memory_or_exit(page_start(start), byte_size_for_pages(size_in_pages), _executable,
    1.52                                err_msg("Failed to commit pages from "SIZE_FORMAT" of length "SIZE_FORMAT, start, size_in_pages));
    1.53    }
    1.54 -  _committed.set_range(start, start + size_in_pages);
    1.55 +  _committed.set_range(start, end);
    1.56  
    1.57 -  MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize);
    1.58 -  return result;
    1.59 +  return zero_filled;
    1.60  }
    1.61  
    1.62 -MemRegion G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
    1.63 +void G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
    1.64    guarantee(is_area_committed(start, size_in_pages), "checking");
    1.65  
    1.66 -  if (!_special) {
    1.67 +  if (_special) {
    1.68 +    // Mark that memory is dirty. If committed again the memory might
    1.69 +    // need to be cleared explicitly.
    1.70 +    _dirty.set_range(start, start + size_in_pages);
    1.71 +  } else {
    1.72      os::uncommit_memory(page_start(start), byte_size_for_pages(size_in_pages));
    1.73    }
    1.74  
    1.75    _committed.clear_range(start, start + size_in_pages);
    1.76 -
    1.77 -  MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize);
    1.78 -  return result;
    1.79  }
    1.80  
    1.81  bool G1PageBasedVirtualSpace::contains(const void* p) const {
    1.82 @@ -154,7 +168,7 @@
    1.83  #ifndef PRODUCT
    1.84  void G1PageBasedVirtualSpace::print_on(outputStream* out) {
    1.85    out->print   ("Virtual space:");
    1.86 -  if (special()) out->print(" (pinned in memory)");
    1.87 +  if (_special) out->print(" (pinned in memory)");
    1.88    out->cr();
    1.89    out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
    1.90    out->print_cr(" - reserved:  " SIZE_FORMAT, reserved_size());
     2.1 --- a/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp	Fri Jan 16 11:00:29 2015 -0800
     2.2 +++ b/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp	Mon Jan 12 15:24:29 2015 +0100
     2.3 @@ -49,6 +49,12 @@
     2.4    // Bitmap used for verification of commit/uncommit operations.
     2.5    BitMap _committed;
     2.6  
     2.7 +  // Bitmap used to keep track of which pages are dirty or not for _special
     2.8 +  // spaces. This is needed because for those spaces the underlying memory
     2.9 +  // will only be zero filled the first time it is committed. Calls to commit
    2.10 +  // will use this bitmap and return whether or not the memory is zero filled.
    2.11 +  BitMap _dirty;
    2.12 +
    2.13    // Indicates that the entire space has been committed and pinned in memory,
    2.14    // os::commit_memory() or os::uncommit_memory() have no function.
    2.15    bool _special;
    2.16 @@ -71,12 +77,11 @@
    2.17   public:
    2.18  
    2.19    // Commit the given area of pages starting at start being size_in_pages large.
    2.20 -  MemRegion commit(uintptr_t start, size_t size_in_pages);
    2.21 +  // Returns true if the given area is zero filled upon completion.
    2.22 +  bool commit(uintptr_t start, size_t size_in_pages);
    2.23  
    2.24    // Uncommit the given area of pages starting at start being size_in_pages large.
    2.25 -  MemRegion uncommit(uintptr_t start, size_t size_in_pages);
    2.26 -
    2.27 -  bool special() const { return _special; }
    2.28 +  void uncommit(uintptr_t start, size_t size_in_pages);
    2.29  
    2.30    // Initialization
    2.31    G1PageBasedVirtualSpace();
     3.1 --- a/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp	Fri Jan 16 11:00:29 2015 -0800
     3.2 +++ b/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp	Mon Jan 12 15:24:29 2015 +0100
     3.3 @@ -67,9 +67,9 @@
     3.4    }
     3.5  
     3.6    virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
     3.7 -    _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
     3.8 +    bool zero_filled = _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
     3.9      _commit_map.set_range(start_idx, start_idx + num_regions);
    3.10 -    fire_on_commit(start_idx, num_regions, true);
    3.11 +    fire_on_commit(start_idx, num_regions, zero_filled);
    3.12    }
    3.13  
    3.14    virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
    3.15 @@ -117,8 +117,7 @@
    3.16        uint old_refcount = _refcounts.get_by_index(idx);
    3.17        bool zero_filled = false;
    3.18        if (old_refcount == 0) {
    3.19 -        _storage.commit(idx, 1);
    3.20 -        zero_filled = true;
    3.21 +        zero_filled = _storage.commit(idx, 1);
    3.22        }
    3.23        _refcounts.set_by_index(idx, old_refcount + 1);
    3.24        _commit_map.set_bit(i);

mercurial