< prev index next >

src/hotspot/share/services/virtualMemoryTracker.cpp

Print this page

        

*** 36,45 **** --- 36,51 ---- assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check"); // Use placement operator new to initialize static data area. ::new ((void*)_snapshot) VirtualMemorySnapshot(); } + void VirtualMemorySummary::snapshot(VirtualMemorySnapshot* s) { + // Snapshot current thread stacks + VirtualMemoryTracker::snapshot_thread_stacks(); + as_snapshot()->copy_to(s); + } + SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions; int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) { return r1.compare(r2); }
*** 75,98 **** 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) { --- 81,111 ---- return true; } } if (rgn->overlap_region(addr, size)) { ! if (addr < rgn->base()) { ! rgn->expand_region(addr, (rgn->base() - addr)); ! } ! ! if (addr + size > rgn->base() + rgn->size()) { ! rgn->expand_region(rgn->base() + rgn->size(), ! (addr + size) - (rgn->base() + rgn->size())); } + return true; + } + 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) {
*** 277,286 **** --- 290,318 ---- VirtualMemorySummary::move_committed_memory(flag(), f, committed_size()); _flag = f; } } + address ReservedMemoryRegion::thread_stack_uncommitted_bottom() const { + assert(flag() == mtThreadStack, "Only for thread stack"); + LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head(); + address bottom = base(); + address top = base() + size(); + while (head != NULL) { + address committed_top = head->data()->base() + head->data()->size(); + if (committed_top < top) { + // committed stack guard pages, skip them + bottom = head->data()->base() + head->data()->size(); + head = head->next(); + } else { + break; + } + } + + return bottom; + } + bool VirtualMemoryTracker::initialize(NMT_TrackingLevel level) { if (level >= NMT_summary) { VirtualMemorySummary::initialize(); } return true;
*** 457,466 **** --- 489,525 ---- } } } } + // Walk all known thread stacks, snapshot their committed ranges. + class SnapshotThreadStackWalker : public VirtualMemoryWalker { + public: + SnapshotThreadStackWalker() {} + + bool do_allocation_site(const ReservedMemoryRegion* rgn) { + if (rgn->flag() == mtThreadStack) { + address stack_bottom = rgn->thread_stack_uncommitted_bottom(); + size_t stack_size = rgn->base() + rgn->size() - stack_bottom; + + size_t committed_size = os::committed_stack_size(stack_bottom, stack_size); + if (committed_size > 0) { + ReservedMemoryRegion* region = const_cast<ReservedMemoryRegion*>(rgn); + NativeCallStack ncs; // empty stack + + // Stack grows downward + region->add_committed_region(rgn->base() + rgn->size() - committed_size, committed_size, ncs); + } + } + return true; + } + }; + + void VirtualMemoryTracker::snapshot_thread_stacks() { + SnapshotThreadStackWalker walker; + walk_virtual_memory(&walker); + } bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) { assert(_reserved_regions != NULL, "Sanity check"); ThreadCritical tc; // Check that the _reserved_regions haven't been deleted.
< prev index next >