// locate an exiting record that contains specified address, or
  // the record, where the record with specified address, should
  // be inserted
  virtual MemPointer* locate(address addr) {
    VMMemRegion* cur = (VMMemRegion*)current();
    VMMemRegion* next_p;

    while (cur != NULL) {
      if (cur->base() > addr) {
        return cur;
      } else {
        // find nearest existing range that has base address <= addr
        next_p = (VMMemRegion*)peek_next();
        if (next_p != NULL && next_p->base() <= addr) {
          cur = (VMMemRegion*)next();
          continue;
        }
      }

      if (cur->is_reserve_record() &&
        cur->base() <= addr &&
        (cur->base() + cur->size() > addr)) {
          return cur;
      } else if (cur->is_commit_record() &&
        cur->base() <= addr &&
        (cur->base() + cur->committed_size() > addr)) {
          return cur;
      }
      cur = (VMMemRegion*)next();
    }
    return NULL;
  }
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);
}
 // locate an existing reserved memory region that contains specified address,
 // or the reserved region just above this address, where the incoming
 // reserved region should be inserted.
 virtual MemPointer* locate(address addr) {
   reset();
   VMMemRegion* reg = (VMMemRegion*)current();
   while (reg != NULL) {
     if (reg->is_reserved_region()) {
       if (reg->contains_address(addr) || addr < reg->base()) {
         return reg;
     }
   }
     reg = (VMMemRegion*)next();
   }
     return NULL;
   }
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_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;
}
Exemple #6
0
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;
}