# HG changeset patch # User stuefe # Date 1589451433 -7200 # Thu May 14 12:17:13 2020 +0200 # Node ID 48755534c27f227d095ae3ebcc6f3911232950d2 # Parent a44396903fd82fbed8eb97006669a397dfe32da6 [mq]: nmt-os-split-reserved-memory diff -r a44396903fd8 -r 48755534c27f src/hotspot/share/services/memTracker.hpp --- a/src/hotspot/share/services/memTracker.hpp Thu May 14 08:48:36 2020 +0200 +++ b/src/hotspot/share/services/memTracker.hpp Thu May 14 12:17:13 2020 +0200 @@ -240,6 +240,20 @@ } } + // Given an existing memory mapping registered with NMT, split the mapping in two. + // This is called in the context of os::split_reserved_memory(..., realloc=true), so we do not have to care + // about committed memory in the unsplit region (we can treat this as a release, followed by two independent reserve operations). + // The newly created two mappings will be registered under the call stack and the memory flags of the original section. + static inline void record_virtual_memory_split_reserved(void* addr, size_t size, size_t split) { + if (tracking_level() < NMT_summary) return; + if (addr != NULL) { + ThreadCritical tc; + // Recheck to avoid potential racing during NMT shutdown + if (tracking_level() < NMT_summary) return; + VirtualMemoryTracker::split_reserved_region((address)addr, size, split); + } + } + static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { if (tracking_level() < NMT_summary) return; if (addr != NULL) { diff -r a44396903fd8 -r 48755534c27f src/hotspot/share/services/virtualMemoryTracker.cpp --- a/src/hotspot/share/services/virtualMemoryTracker.cpp Thu May 14 08:48:36 2020 +0200 +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp Thu May 14 12:17:13 2020 +0200 @@ -490,6 +490,32 @@ } } +// Given an existing memory mapping registered with NMT, split the mapping in two. +// The newly created two mappings will be registered under the call stack and the memory flags of the original section. +bool VirtualMemoryTracker::split_reserved_region(address addr, size_t size, size_t split) { + + ReservedMemoryRegion rgn(addr, size); + ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); + assert(reserved_rgn != NULL, "No reserved region"); + + // Squirrel away the old region flags and stack for later. + MEMFLAGS flags = reserved_rgn->flag(); + NativeCallStack stack = *reserved_rgn->call_stack(); + + // The original region must be completely uncommitted. + assert(reserved_rgn->committed_size() == 0, "Splitting committed region?"); + + // Remove the region. + _reserved_regions->remove(rgn); + + // Now, create two new regions. + add_reserved_region(addr, split, stack, flags); + add_reserved_region(addr + split, size - split, stack, flags); + + return true; +} + + // Iterate the range, find committed region within its bound. class RegionIterator : public StackObj { private: diff -r a44396903fd8 -r 48755534c27f src/hotspot/share/services/virtualMemoryTracker.hpp --- a/src/hotspot/share/services/virtualMemoryTracker.hpp Thu May 14 08:48:36 2020 +0200 +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp Thu May 14 12:17:13 2020 +0200 @@ -405,6 +405,10 @@ static bool remove_released_region (address base_addr, size_t size); static void set_reserved_region_type (address addr, MEMFLAGS flag); + // Given an existing memory mapping registered with NMT, split the mapping in two. + // The newly created two mappings will be registered under the call stack and the memory flags of the original section. + static bool split_reserved_region(address addr, size_t size, size_t split); + // Walk virtual memory data structure for creating baseline, etc. static bool walk_virtual_memory(VirtualMemoryWalker* walker);