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.find_node(committed_rgn); if (node != NULL) { CommittedMemoryRegion* rgn = node->data(); if (rgn->same_region(addr, size)) { return true; } if (rgn->adjacent_to(addr, size)) { // check if the next region covers this committed region, // the regions may not be merged due to different call stacks LinkedListNode<CommittedMemoryRegion>* next = node->next(); if (next != NULL && next->data()->contain_region(addr, size)) { if (next->data()->same_region(addr, size)) { next->data()->set_call_stack(stack); } return true; } if (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; } VirtualMemorySummary::record_committed_memory(size, flag()); if (rgn->base() > addr) { return _committed_regions.insert_before(committed_rgn, node) != NULL; } else { return _committed_regions.insert_after(committed_rgn, node) != NULL; } } assert(rgn->contain_region(addr, size), "Must cover this region"); return true; } else { // New committed region VirtualMemorySummary::record_committed_memory(size, flag()); return add_committed_region(committed_rgn); } }
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); }