Skip to content

Commit bd1c156

Browse files
author
duke
committedJun 9, 2020
Automatic merge of jdk:master into master
2 parents 2efdf88 + 8dc6643 commit bd1c156

File tree

10 files changed

+91
-64
lines changed

10 files changed

+91
-64
lines changed
 

‎src/hotspot/os/posix/os_posix.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ void os::split_reserved_memory(char *base, size_t size, size_t split) {
370370
assert(split > 0, "Sanity");
371371
assert(is_aligned(base, os::vm_allocation_granularity()), "Sanity");
372372
assert(is_aligned(split_address, os::vm_allocation_granularity()), "Sanity");
373+
374+
// NMT: tell NMT to track both parts individually from now on.
375+
MemTracker::record_virtual_memory_split_reserved(base, size, split);
376+
373377
}
374378

375379
int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {

‎src/hotspot/os/windows/os_windows.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -3237,6 +3237,10 @@ void os::split_reserved_memory(char *base, size_t size, size_t split) {
32373237
reserve_memory(split, base);
32383238
reserve_memory(size - split, split_address);
32393239

3240+
// NMT: nothing to do here. Since Windows implements the split by
3241+
// releasing and re-reserving memory, the parts are already registered
3242+
// as individual mappings with NMT.
3243+
32403244
}
32413245

32423246
// Multiple threads can race in this code but it's not possible to unmap small sections of

‎src/hotspot/share/memory/filemap.cpp

+5-15
Original file line numberDiff line numberDiff line change
@@ -1499,11 +1499,6 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba
14991499
si->set_read_only(false); // Need to patch the pointers
15001500
}
15011501

1502-
if (rs.is_reserved()) {
1503-
assert(rs.contains(requested_addr) && rs.contains(requested_addr + size - 1), "must be");
1504-
MemTracker::record_virtual_memory_type((address)requested_addr, mtClassShared);
1505-
}
1506-
15071502
if (MetaspaceShared::use_windows_memory_mapping() && rs.is_reserved()) {
15081503
// This is the second time we try to map the archive(s). We have already created a ReservedSpace
15091504
// that covers all the FileMapRegions to ensure all regions can be mapped. However, Windows
@@ -1515,9 +1510,12 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba
15151510
return MAP_ARCHIVE_OTHER_FAILURE; // oom or I/O error.
15161511
}
15171512
} else {
1513+
// Note that this may either be a "fresh" mapping into unreserved address
1514+
// space (Windows, first mapping attempt), or a mapping into pre-reserved
1515+
// space (Posix). See also comment in MetaspaceShared::map_archives().
15181516
char* base = os::map_memory(_fd, _full_path, si->file_offset(),
15191517
requested_addr, size, si->read_only(),
1520-
si->allow_exec());
1518+
si->allow_exec(), mtClassShared);
15211519
if (base != requested_addr) {
15221520
log_info(cds)("Unable to map %s shared space at " INTPTR_FORMAT,
15231521
shared_region_name[i], p2i(requested_addr));
@@ -1528,14 +1526,6 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba
15281526
}
15291527
si->set_mapped_base(requested_addr);
15301528

1531-
if (!rs.is_reserved()) {
1532-
// When mapping on Windows for the first attempt, we don't reserve the address space for the regions
1533-
// (Windows can't mmap into a ReservedSpace). In this case, NMT requires we call it after
1534-
// os::map_memory has succeeded.
1535-
assert(MetaspaceShared::use_windows_memory_mapping(), "Windows memory mapping only");
1536-
MemTracker::record_virtual_memory_type((address)requested_addr, mtClassShared);
1537-
}
1538-
15391529
if (VerifySharedSpaces && !verify_region_checksum(i)) {
15401530
return MAP_ARCHIVE_OTHER_FAILURE;
15411531
}
@@ -1552,7 +1542,7 @@ char* FileMapInfo::map_bitmap_region() {
15521542
bool read_only = true, allow_exec = false;
15531543
char* requested_addr = NULL; // allow OS to pick any location
15541544
char* bitmap_base = os::map_memory(_fd, _full_path, si->file_offset(),
1555-
requested_addr, si->used_aligned(), read_only, allow_exec);
1545+
requested_addr, si->used_aligned(), read_only, allow_exec, mtClassShared);
15561546
if (bitmap_base == NULL) {
15571547
log_error(cds)("failed to map relocation bitmap");
15581548
return NULL;

‎src/hotspot/share/memory/metaspaceShared.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2538,6 +2538,10 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma
25382538
assert(is_aligned(class_space_rs.base(), class_space_alignment), "Sanity");
25392539
assert(is_aligned(class_space_rs.size(), class_space_alignment), "Sanity");
25402540

2541+
// NMT: fix up the space tags
2542+
MemTracker::record_virtual_memory_type(archive_space_rs.base(), mtClassShared);
2543+
MemTracker::record_virtual_memory_type(class_space_rs.base(), mtClass);
2544+
25412545
return archive_space_rs.base();
25422546

25432547
#else

‎src/hotspot/share/memory/virtualspace.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class ReservedSpace {
7878
// This splits the space into two spaces, the first part of which will be returned.
7979
// If split==true, the resulting two spaces can be released independently from each other.
8080
// This may cause the original space to loose its content.
81+
// They also will be tracked individually by NMT and can be tagged with different flags.
82+
// Note that this may cause the original space to loose its content.
8183
// If split==false, the resulting space will be just a hotspot-internal representation
8284
// of a sub section of the underlying mapping.
8385
ReservedSpace first_part(size_t partition_size, size_t alignment, bool split = false);

‎src/hotspot/share/runtime/os.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1763,10 +1763,10 @@ void os::pretouch_memory(void* start, void* end, size_t page_size) {
17631763

17641764
char* os::map_memory(int fd, const char* file_name, size_t file_offset,
17651765
char *addr, size_t bytes, bool read_only,
1766-
bool allow_exec) {
1766+
bool allow_exec, MEMFLAGS flags) {
17671767
char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec);
17681768
if (result != NULL) {
1769-
MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
1769+
MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC, flags);
17701770
}
17711771
return result;
17721772
}

‎src/hotspot/share/runtime/os.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ class os: AllStatic {
326326
// Both base and split point must be aligned to allocation granularity; split point shall
327327
// be >0 and <size.
328328
// Splitting guarantees that the resulting two memory regions can be released independently
329-
// from each other using os::release_memory().
329+
// from each other using os::release_memory(). It also means NMT will track these regions
330+
// individually, allowing different tags to be set.
330331
static void split_reserved_memory(char *base, size_t size, size_t split);
331332

332333
static bool commit_memory(char* addr, size_t bytes, bool executable);
@@ -368,7 +369,7 @@ class os: AllStatic {
368369

369370
static char* map_memory(int fd, const char* file_name, size_t file_offset,
370371
char *addr, size_t bytes, bool read_only = false,
371-
bool allow_exec = false);
372+
bool allow_exec = false, MEMFLAGS flags = mtNone);
372373
static char* remap_memory(int fd, const char* file_name, size_t file_offset,
373374
char *addr, size_t bytes, bool read_only,
374375
bool allow_exec);

‎src/hotspot/share/services/memTracker.hpp

+17
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class MemTracker : AllStatic {
6868
MEMFLAGS flag = mtNone) { }
6969
static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size,
7070
const NativeCallStack& stack, MEMFLAGS flag = mtNone) { }
71+
static inline void record_virtual_memory_split_reserved(void* addr, size_t size, size_t split) { }
7172
static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { }
7273
static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { }
7374
static inline void record_thread_stack(void* addr, size_t size) { }
@@ -238,6 +239,22 @@ class MemTracker : AllStatic {
238239
}
239240
}
240241

242+
// Given an existing memory mapping registered with NMT and a splitting
243+
// address, split the mapping in two. The memory region is supposed to
244+
// be fully uncommitted.
245+
//
246+
// The two new memory regions will be both registered under stack and
247+
// memory flags of the original region.
248+
static inline void record_virtual_memory_split_reserved(void* addr, size_t size, size_t split) {
249+
if (tracking_level() < NMT_summary) return;
250+
if (addr != NULL) {
251+
ThreadCritical tc;
252+
// Recheck to avoid potential racing during NMT shutdown
253+
if (tracking_level() < NMT_summary) return;
254+
VirtualMemoryTracker::split_reserved_region((address)addr, size, split);
255+
}
256+
}
257+
241258
static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) {
242259
if (tracking_level() < NMT_summary) return;
243260
if (addr != NULL) {

‎src/hotspot/share/services/virtualMemoryTracker.cpp

+26-5
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,9 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
348348
reserved_rgn->set_call_stack(stack);
349349
reserved_rgn->set_flag(flag);
350350
return true;
351-
} else if (reserved_rgn->adjacent_to(base_addr, size)) {
352-
VirtualMemorySummary::record_reserved_memory(size, flag);
353-
reserved_rgn->expand_region(base_addr, size);
354-
reserved_rgn->set_call_stack(stack);
355-
return true;
356351
} else {
352+
assert(reserved_rgn->overlap_region(base_addr, size), "Must be");
353+
357354
// Overlapped reservation.
358355
// It can happen when the regions are thread stacks, as JNI
359356
// thread does not detach from VM before exits, and leads to
@@ -491,6 +488,30 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
491488
}
492489
}
493490

491+
// Given an existing memory mapping registered with NMT, split the mapping in
492+
// two. The newly created two mappings will be registered under the call
493+
// stack and the memory flags of the original section.
494+
bool VirtualMemoryTracker::split_reserved_region(address addr, size_t size, size_t split) {
495+
496+
ReservedMemoryRegion rgn(addr, size);
497+
ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
498+
assert(reserved_rgn->same_region(addr, size), "Must be identical region");
499+
assert(reserved_rgn != NULL, "No reserved region");
500+
assert(reserved_rgn->committed_size() == 0, "Splitting committed region?");
501+
502+
NativeCallStack original_stack = *reserved_rgn->call_stack();
503+
MEMFLAGS original_flags = reserved_rgn->flag();
504+
505+
_reserved_regions->remove(rgn);
506+
507+
// Now, create two new regions.
508+
add_reserved_region(addr, split, original_stack, original_flags);
509+
add_reserved_region(addr + split, size - split, original_stack, original_flags);
510+
511+
return true;
512+
}
513+
514+
494515
// Iterate the range, find committed region within its bound.
495516
class RegionIterator : public StackObj {
496517
private:

‎src/hotspot/share/services/virtualMemoryTracker.hpp

+24-40
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,8 @@ class VirtualMemoryRegion {
210210
inline bool overlap_region(address addr, size_t sz) const {
211211
assert(sz > 0, "Invalid size");
212212
assert(size() > 0, "Invalid size");
213-
VirtualMemoryRegion rgn(addr, sz);
214213
return contain_address(addr) ||
215-
contain_address(addr + sz - 1) ||
216-
rgn.contain_address(base()) ||
217-
rgn.contain_address(end() - 1);
214+
contain_address(addr + sz - 1);
218215
}
219216

220217
inline bool adjacent_to(address addr, size_t sz) const {
@@ -240,6 +237,24 @@ class VirtualMemoryRegion {
240237
set_size(size() + sz);
241238
}
242239

240+
// Returns 0 if regions overlap; 1 if this region follows rgn;
241+
// -1 if this region precedes rgn.
242+
inline int compare(const VirtualMemoryRegion& rgn) const {
243+
if (overlap_region(rgn.base(), rgn.size())) {
244+
return 0;
245+
} else if (base() >= rgn.end()) {
246+
return 1;
247+
} else {
248+
assert(rgn.base() >= end(), "Sanity");
249+
return -1;
250+
}
251+
}
252+
253+
// Returns true if regions overlap, false otherwise.
254+
inline bool equals(const VirtualMemoryRegion& rgn) const {
255+
return compare(rgn) == 0;
256+
}
257+
243258
protected:
244259
void set_base(address base) {
245260
assert(base != NULL, "Sanity check");
@@ -261,24 +276,6 @@ class CommittedMemoryRegion : public VirtualMemoryRegion {
261276
CommittedMemoryRegion(address addr, size_t size, const NativeCallStack& stack) :
262277
VirtualMemoryRegion(addr, size), _stack(stack) { }
263278

264-
inline int compare(const CommittedMemoryRegion& rgn) const {
265-
if (overlap_region(rgn.base(), rgn.size())) {
266-
return 0;
267-
} else {
268-
if (base() == rgn.base()) {
269-
return 0;
270-
} else if (base() > rgn.base()) {
271-
return 1;
272-
} else {
273-
return -1;
274-
}
275-
}
276-
}
277-
278-
inline bool equals(const CommittedMemoryRegion& rgn) const {
279-
return compare(rgn) == 0;
280-
}
281-
282279
inline void set_call_stack(const NativeCallStack& stack) { _stack = stack; }
283280
inline const NativeCallStack* call_stack() const { return &_stack; }
284281
};
@@ -316,24 +313,6 @@ class ReservedMemoryRegion : public VirtualMemoryRegion {
316313
void set_flag(MEMFLAGS flag);
317314
inline MEMFLAGS flag() const { return _flag; }
318315

319-
inline int compare(const ReservedMemoryRegion& rgn) const {
320-
if (overlap_region(rgn.base(), rgn.size())) {
321-
return 0;
322-
} else {
323-
if (base() == rgn.base()) {
324-
return 0;
325-
} else if (base() > rgn.base()) {
326-
return 1;
327-
} else {
328-
return -1;
329-
}
330-
}
331-
}
332-
333-
inline bool equals(const ReservedMemoryRegion& rgn) const {
334-
return compare(rgn) == 0;
335-
}
336-
337316
// uncommitted thread stack bottom, above guard pages if there is any.
338317
address thread_stack_uncommitted_bottom() const;
339318

@@ -405,6 +384,11 @@ class VirtualMemoryTracker : AllStatic {
405384
static bool remove_released_region (address base_addr, size_t size);
406385
static void set_reserved_region_type (address addr, MEMFLAGS flag);
407386

387+
// Given an existing memory mapping registered with NMT, split the mapping in
388+
// two. The newly created two mappings will be registered under the call
389+
// stack and the memory flags of the original section.
390+
static bool split_reserved_region(address addr, size_t size, size_t split);
391+
408392
// Walk virtual memory data structure for creating baseline, etc.
409393
static bool walk_virtual_memory(VirtualMemoryWalker* walker);
410394

0 commit comments

Comments
 (0)
Please sign in to comment.