< prev index next >

src/hotspot/share/services/virtualMemoryTracker.cpp

Print this page

        

*** 46,106 **** int compare_reserved_region_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) { return r1.compare(r2); } bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const NativeCallStack& stack) { assert(addr != NULL, "Invalid address"); assert(size > 0, "Invalid size"); assert(contain_region(addr, size), "Not contain this region"); ! if (all_committed()) return true; ! ! CommittedMemoryRegion committed_rgn(addr, size, stack); ! LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head(); ! while (node != NULL) { CommittedMemoryRegion* rgn = node->data(); - if (rgn->same_region(addr, size)) { - return true; - } ! if (rgn->adjacent_to(addr, size)) { ! // special case to expand prior region if there is no next region ! LinkedListNode<CommittedMemoryRegion>* next = node->next(); ! if (next == NULL && rgn->call_stack()->equals(stack)) { ! VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag()); ! // the two adjacent regions have the same call stack, merge them ! rgn->expand_region(addr, size); ! VirtualMemorySummary::record_committed_memory(rgn->size(), flag()); return true; } - } if (rgn->overlap_region(addr, size)) { - // Clear a space for this region in the case it overlaps with any regions. remove_uncommitted_region(addr, size); ! break; // commit below } ! if (rgn->end() >= addr + size){ break; } ! node = node->next(); } ! // New committed region VirtualMemorySummary::record_committed_memory(size, flag()); ! return add_committed_region(committed_rgn); } ! void ReservedMemoryRegion::set_all_committed(bool b) { ! if (all_committed() != b) { ! _all_committed = b; ! if (b) { ! VirtualMemorySummary::record_committed_memory(size(), flag()); } } } bool ReservedMemoryRegion::remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node, address addr, size_t size) { assert(addr != NULL, "Invalid address"); --- 46,141 ---- int compare_reserved_region_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) { return r1.compare(r2); } + static bool is_mergeable_with(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) { + return rgn->adjacent_to(addr, size) && rgn->call_stack()->equals(stack); + } + + static bool is_same_as(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) { + // It would have made sense to use rgn->equals(...), but equals returns true for overlapping regions. + return rgn->same_region(addr, size) && rgn->call_stack()->equals(stack); + } + + void ReservedMemoryRegion::merge_with(LinkedListNode<CommittedMemoryRegion>* node, address addr, size_t size, const NativeCallStack& stack) { + CommittedMemoryRegion* rgn = node->data(); + assert(rgn->call_stack()->equals(stack), "Stack mismatch"); + assert(rgn->adjacent_to(addr, size), "Not adjacent"); + + rgn->expand_region(addr, size); + + LinkedListNode<CommittedMemoryRegion>* next = node->next(); + if (next != NULL) { + address next_addr = next->data()->base(); + size_t next_size = next->data()->size(); + const NativeCallStack& next_stack = *next->data()->call_stack(); + + if (is_mergeable_with(rgn, next_addr, next_size, next_stack)) { + rgn->expand_region(next_addr, next_size); + _committed_regions.remove(next); + } + } + } + bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const NativeCallStack& stack) { assert(addr != NULL, "Invalid address"); assert(size > 0, "Invalid size"); assert(contain_region(addr, size), "Not contain this region"); ! LinkedListNode<CommittedMemoryRegion>* prev = NULL; ! for (LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head(); ! node != NULL; ! node = node->next()) { CommittedMemoryRegion* rgn = node->data(); ! // Ignore request if region already exists. ! if (is_same_as(rgn, addr, size, stack)) { return true; } + // Found an overlapping region + // - remove _all_ overlapping regions in preparation + // for the addition of this new region. if (rgn->overlap_region(addr, size)) { remove_uncommitted_region(addr, size); ! break; } ! ! // We searched past this new region. ! if (rgn->base() >= addr + size) { break; } ! ! prev = node; } ! // At this point the previous overlapping regions have been ! // cleared, and the full region guaranteed to be inserted. VirtualMemorySummary::record_committed_memory(size, flag()); ! ! // Try to merge if possible. ! ! // Preceding node might be prev, or a node created by remove_uncommitted_region. ! for (LinkedListNode<CommittedMemoryRegion>* node = (prev != NULL) ? prev : _committed_regions.head(); ! node != NULL; ! node = node->next()) { ! CommittedMemoryRegion* rgn = node->data(); ! ! if (is_mergeable_with(rgn, addr, size, stack)) { ! merge_with(node, addr, size, stack); ! return true; } ! if (rgn->base() >= addr + size) { ! break; } } + + // Couldn't merge with any regions - create a new region. + return add_committed_region(CommittedMemoryRegion(addr, size, stack)); } bool ReservedMemoryRegion::remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node, address addr, size_t size) { assert(addr != NULL, "Invalid address");
*** 133,181 **** return false; } bool ReservedMemoryRegion::remove_uncommitted_region(address addr, size_t sz) { - // uncommit stack guard pages - if (flag() == mtThreadStack && !same_region(addr, sz)) { - return true; - } - assert(addr != NULL, "Invalid address"); assert(sz > 0, "Invalid size"); - if (all_committed()) { - assert(_committed_regions.is_empty(), "Sanity check"); - assert(contain_region(addr, sz), "Reserved region does not contain this region"); - set_all_committed(false); - VirtualMemorySummary::record_uncommitted_memory(sz, flag()); - if (same_region(addr, sz)) { - return true; - } else { - CommittedMemoryRegion rgn(base(), size(), *call_stack()); - if (rgn.base() == addr || rgn.end() == (addr + sz)) { - rgn.exclude_region(addr, sz); - return add_committed_region(rgn); - } else { - // split this region - // top of the whole region - address top =rgn.end(); - // use this region for lower part - size_t exclude_size = rgn.end() - addr; - rgn.exclude_region(addr, exclude_size); - if (add_committed_region(rgn)) { - // higher part - address high_base = addr + sz; - size_t high_size = top - high_base; - CommittedMemoryRegion high_rgn(high_base, high_size, NativeCallStack::EMPTY_STACK); - return add_committed_region(high_rgn); - } else { - return false; - } - } - } - } else { CommittedMemoryRegion del_rgn(addr, sz, *call_stack()); address end = addr + sz; LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head(); LinkedListNode<CommittedMemoryRegion>* prev = NULL; --- 168,180 ----
*** 221,231 **** } prev = head; head = head->next(); } - } return true; } void ReservedMemoryRegion::move_committed_regions(address addr, ReservedMemoryRegion& rgn) { --- 220,229 ----
*** 254,275 **** rgn._committed_regions.set_head(head); } size_t ReservedMemoryRegion::committed_size() const { - if (all_committed()) { - return size(); - } else { size_t committed = 0; LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head(); while (head != NULL) { committed += head->data()->size(); head = head->next(); } return committed; - } } void ReservedMemoryRegion::set_flag(MEMFLAGS f) { assert((flag() == mtNone || flag() == f), "Overwrite memory type"); if (flag() != f) { --- 252,269 ----
*** 294,319 **** } return true; } bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, ! const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) { assert(base_addr != NULL, "Invalid address"); assert(size > 0, "Invalid size"); assert(_reserved_regions != NULL, "Sanity check"); ReservedMemoryRegion rgn(base_addr, size, stack, flag); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); ! LinkedListNode<ReservedMemoryRegion>* node; if (reserved_rgn == NULL) { VirtualMemorySummary::record_reserved_memory(size, flag); ! node = _reserved_regions->add(rgn); ! if (node != NULL) { ! node->data()->set_all_committed(all_committed); ! return true; ! } else { ! return false; ! } } else { if (reserved_rgn->same_region(base_addr, size)) { reserved_rgn->set_call_stack(stack); reserved_rgn->set_flag(flag); return true; --- 288,307 ---- } return true; } bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, ! const NativeCallStack& stack, MEMFLAGS flag) { assert(base_addr != NULL, "Invalid address"); assert(size > 0, "Invalid size"); assert(_reserved_regions != NULL, "Sanity check"); ReservedMemoryRegion rgn(base_addr, size, stack, flag); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); ! if (reserved_rgn == NULL) { VirtualMemorySummary::record_reserved_memory(size, flag); ! return _reserved_regions->add(rgn) != NULL; } else { if (reserved_rgn->same_region(base_addr, size)) { reserved_rgn->set_call_stack(stack); reserved_rgn->set_flag(flag); return true;
< prev index next >