bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) { assert(rec->is_deallocation_record(), "Sanity check"); VMMemRegion* cur = (VMMemRegion*)current(); assert(cur->is_reserved_region() && cur->contains_region(rec), "Sanity check"); if (rec->is_same_region(cur)) { // In snapshot, the virtual memory records are sorted in following orders: // 1. virtual memory's base address // 2. virtual memory reservation record, followed by commit records within this reservation. // The commit records are also in base address order. // When a reserved region is released, we want to remove the reservation record and all // commit records following it. #ifdef ASSERT address low_addr = cur->addr(); address high_addr = low_addr + cur->size(); #endif // remove virtual memory reservation record remove(); // remove committed regions within above reservation VMMemRegion* next_region = (VMMemRegion*)current(); while (next_region != NULL && next_region->is_committed_region()) { assert(next_region->addr() >= low_addr && next_region->addr() + next_region->size() <= high_addr, "Range check"); remove(); next_region = (VMMemRegion*)current(); } } else if (rec->addr() == cur->addr() || rec->addr() + rec->size() == cur->addr() + cur->size()) { // released region is at either end of this region cur->exclude_region(rec->addr(), rec->size()); assert(check_reserved_region(), "Integrity check"); } else { // split the reserved region and release the middle address high_addr = cur->addr() + cur->size(); size_t sz = high_addr - rec->addr(); cur->exclude_region(rec->addr(), sz); sz = high_addr - rec->addr() - rec->size(); if (MemTracker::track_callsite()) { MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz, ((VMMemRegionEx*)cur)->pc()); bool ret = insert_reserved_region(&tmp); assert(!ret || check_reserved_region(), "Integrity check"); return ret; } else { MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz); bool ret = insert_reserved_region(&tmp); assert(!ret || check_reserved_region(), "Integrity check"); return ret; } } return true; }
bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) { assert(rec->is_deallocation_record(), "Sanity check"); VMMemRegion* cur = (VMMemRegion*)current(); assert(cur->is_reserved_region() && cur->contains_region(rec), "Sanity check"); if (rec->is_same_region(cur)) { // release whole reserved region #ifdef ASSERT VMMemRegion* next_region = (VMMemRegion*)peek_next(); // should not have any committed memory in this reserved region assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check"); #endif remove(); } else if (rec->addr() == cur->addr() || rec->addr() + rec->size() == cur->addr() + cur->size()) { // released region is at either end of this region cur->exclude_region(rec->addr(), rec->size()); assert(check_reserved_region(), "Integrity check"); } else { // split the reserved region and release the middle address high_addr = cur->addr() + cur->size(); size_t sz = high_addr - rec->addr(); cur->exclude_region(rec->addr(), sz); sz = high_addr - rec->addr() - rec->size(); if (MemTracker::track_callsite()) { MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz, ((VMMemRegionEx*)cur)->pc()); bool ret = insert_reserved_region(&tmp); assert(!ret || check_reserved_region(), "Integrity check"); return ret; } else { MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz); bool ret = insert_reserved_region(&tmp); assert(!ret || check_reserved_region(), "Integrity check"); return ret; } } return true; }