bool VMMemPointerIterator::insert_reserved_region(MemPointerRecord* rec) { // skip all 'commit' records associated with previous reserved region VMMemRegion* p = (VMMemRegion*)next(); while (p != NULL && p->is_committed_region() && p->base() + p->size() < rec->addr()) { p = (VMMemRegion*)next(); } return insert_record(rec); }
bool VMMemPointerIterator::remove_uncommitted_region(MemPointerRecord* rec) { assert(rec->is_uncommit_record(), "sanity check"); VMMemRegion* cur; cur = (VMMemRegion*)current(); assert(cur->is_reserved_region() && cur->contains_region(rec), "Sanity check"); // thread's native stack is always marked as "committed", ignore // the "commit" operation for creating stack guard pages if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack && FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) { return true; } cur = (VMMemRegion*)next(); while (cur != NULL && cur->is_committed_region()) { // region already uncommitted, must be due to duplicated record if (cur->addr() >= rec->addr() + rec->size()) { break; } else if (cur->contains_region(rec)) { // uncommit whole region if (cur->is_same_region(rec)) { remove(); break; } else if (rec->addr() == cur->addr() || rec->addr() + rec->size() == cur->addr() + cur->size()) { // uncommitted from either end of current memory region. cur->exclude_region(rec->addr(), rec->size()); break; } else { // split the committed 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()); return insert_record_after(&tmp); } else { MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz); return insert_record_after(&tmp); } } } cur = (VMMemRegion*)next(); } // we may not find committed record due to duplicated records return true; }