Print this page
rev 4499 : 8013120: NMT: Kitchensink crashes with assert(next_region == NULL || !next_region->is_committed_region()) failed: Sanity check
Summary: Fixed NMT to deal with releasing virtual memory region when there are still committed regions within it
Reviewed-by: acorn, coleenp

Split Split Close
Expand all
Collapse all
          --- old/src/share/vm/services/memSnapshot.cpp
          +++ new/src/share/vm/services/memSnapshot.cpp
↓ open down ↓ 254 lines elided ↑ open up ↑
 255  255    // we may not find committed record due to duplicated records
 256  256    return true;
 257  257  }
 258  258  
 259  259  bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
 260  260    assert(rec->is_deallocation_record(), "Sanity check");
 261  261    VMMemRegion* cur = (VMMemRegion*)current();
 262  262    assert(cur->is_reserved_region() && cur->contains_region(rec),
 263  263      "Sanity check");
 264  264    if (rec->is_same_region(cur)) {
 265      -    // release whole reserved region
      265 +
      266 +    // In snapshot, the virtual memory records are sorted in following orders:
      267 +    // 1. virtual memory's base address
      268 +    // 2. virtual memory reservation record, followed by commit records within this reservation.
      269 +    //    The commit records are also in base address order.
      270 +    // When a reserved region is released, we want to remove the reservation record and all
      271 +    // commit records following it.
 266  272  #ifdef ASSERT
 267      -    VMMemRegion* next_region = (VMMemRegion*)peek_next();
 268      -    // should not have any committed memory in this reserved region
 269      -    assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check");
      273 +    address low_addr = cur->addr();
      274 +    address high_addr = low_addr + cur->size();
 270  275  #endif
      276 +    // remove virtual memory reservation record
 271  277      remove();
      278 +    // remove committed regions within above reservation
      279 +    VMMemRegion* next_region = (VMMemRegion*)current();
      280 +    while (next_region != NULL && next_region->is_committed_region()) {
      281 +      assert(next_region->addr() >= low_addr &&
      282 +             next_region->addr() + next_region->size() <= high_addr,
      283 +            "Range check");
      284 +      remove();
      285 +      next_region = (VMMemRegion*)current();
      286 +    }
 272  287    } else if (rec->addr() == cur->addr() ||
 273  288      rec->addr() + rec->size() == cur->addr() + cur->size()) {
 274  289      // released region is at either end of this region
 275  290      cur->exclude_region(rec->addr(), rec->size());
 276  291      assert(check_reserved_region(), "Integrity check");
 277  292    } else { // split the reserved region and release the middle
 278  293      address high_addr = cur->addr() + cur->size();
 279  294      size_t sz = high_addr - rec->addr();
 280  295      cur->exclude_region(rec->addr(), sz);
 281  296      sz = high_addr - rec->addr() - rec->size();
↓ open down ↓ 450 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX