8245203: ZGC: Don't track size in ZPhysicalMemoryBacking

Reviewed-by: eosterlund, stefank
This commit is contained in:
Per Lidén 2020-06-09 11:01:09 +02:00
parent 82e3640eb1
commit 4d8189b265
9 changed files with 33 additions and 113 deletions

View File

@ -73,13 +73,12 @@ static ZErrno mremap(uintptr_t from_addr, uintptr_t to_addr, size_t size) {
return (res == KERN_SUCCESS) ? ZErrno(0) : ZErrno(EINVAL);
}
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
_base(0),
_size(0),
_initialized(false) {
// Reserve address space for backing memory
_base = (uintptr_t)os::reserve_memory(MaxHeapSize);
_base = (uintptr_t)os::reserve_memory(max_capacity);
if (_base == 0) {
// Failed
log_error_pd(gc)("Failed to reserve address space for backing memory");
@ -98,10 +97,6 @@ void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
// Does nothing
}
size_t ZPhysicalMemoryBacking::size() const {
return _size;
}
bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) {
assert(is_aligned(offset, os::vm_page_size()), "Invalid offset");
assert(is_aligned(length, os::vm_page_size()), "Invalid length");
@ -117,12 +112,6 @@ bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) {
return false;
}
const size_t end = offset + length;
if (end > _size) {
// Record new size
_size = end;
}
// Success
return true;
}

View File

@ -27,20 +27,17 @@
class ZPhysicalMemoryBacking {
private:
uintptr_t _base;
size_t _size;
bool _initialized;
bool commit_inner(size_t offset, size_t length);
public:
ZPhysicalMemoryBacking();
ZPhysicalMemoryBacking(size_t max_capacity);
bool is_initialized() const;
void warn_commit_limits(size_t max) const;
size_t size() const;
size_t commit(size_t offset, size_t length);
size_t uncommit(size_t offset, size_t length);

View File

@ -113,9 +113,8 @@ static const char* z_preferred_hugetlbfs_mountpoints[] = {
static int z_fallocate_hugetlbfs_attempts = 3;
static bool z_fallocate_supported = true;
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
_fd(-1),
_size(0),
_filesystem(0),
_block_size(0),
_available(0),
@ -127,6 +126,15 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
return;
}
// Truncate backing file
while (ftruncate(_fd, max_capacity) == -1) {
if (errno != EINTR) {
ZErrno err;
log_error_p(gc)("Failed to truncate backing file (%s)", err.to_string());
return;
}
}
// Get filesystem statistics
struct statfs buf;
if (fstatfs(_fd, &buf) == -1) {
@ -362,10 +370,6 @@ void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
warn_max_map_count(max);
}
size_t ZPhysicalMemoryBacking::size() const {
return _size;
}
bool ZPhysicalMemoryBacking::is_tmpfs() const {
return _filesystem == TMPFS_MAGIC;
}
@ -380,18 +384,6 @@ bool ZPhysicalMemoryBacking::tmpfs_supports_transparent_huge_pages() const {
return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
}
ZErrno ZPhysicalMemoryBacking::fallocate_compat_ftruncate(size_t size) const {
while (ftruncate(_fd, size) == -1) {
if (errno != EINTR) {
// Failed
return errno;
}
}
// Success
return 0;
}
ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_hugetlbfs(size_t offset, size_t length, bool touch) const {
// On hugetlbfs, mapping a file segment will fail immediately, without
// the need to touch the mapped pages first, if there aren't enough huge
@ -490,41 +482,13 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_compat(size_t offset, size_t
// since Linux 4.3. When fallocate(2) is not supported we emulate it using
// mmap/munmap (for hugetlbfs and tmpfs with transparent huge pages) or pwrite
// (for tmpfs without transparent huge pages and other filesystem types).
const size_t end = offset + length;
if (end > _size) {
// Increase file size
const ZErrno err = fallocate_compat_ftruncate(end);
if (err) {
// Failed
return err;
}
if (ZLargePages::is_explicit()) {
return fallocate_compat_mmap_hugetlbfs(offset, length, false /* touch */);
} else if (ZLargePages::is_transparent()) {
return fallocate_compat_mmap_tmpfs(offset, length);
} else {
return fallocate_compat_pwrite(offset, length);
}
// Allocate backing memory
const ZErrno err = ZLargePages::is_explicit()
? fallocate_compat_mmap_hugetlbfs(offset, length, false /* touch */)
: (ZLargePages::is_transparent()
? fallocate_compat_mmap_tmpfs(offset, length)
: fallocate_compat_pwrite(offset, length));
if (err) {
if (end > _size) {
// Restore file size
fallocate_compat_ftruncate(_size);
}
// Failed
return err;
}
if (end > _size) {
// Record new file size
_size = end;
}
// Success
return 0;
}
ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_syscall(size_t offset, size_t length) {
@ -535,12 +499,6 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_syscall(size_t offset, size_t
return errno;
}
const size_t end = offset + length;
if (end > _size) {
// Record new file size
_size = end;
}
// Success
return 0;
}

View File

@ -46,7 +46,6 @@ private:
bool is_hugetlbfs() const;
bool tmpfs_supports_transparent_huge_pages() const;
ZErrno fallocate_compat_ftruncate(size_t size) const;
ZErrno fallocate_compat_mmap_hugetlbfs(size_t offset, size_t length, bool touch) const;
ZErrno fallocate_compat_mmap_tmpfs(size_t offset, size_t length) const;
ZErrno fallocate_compat_pwrite(size_t offset, size_t length) const;
@ -62,14 +61,12 @@ private:
size_t commit_default(size_t offset, size_t length);
public:
ZPhysicalMemoryBacking();
ZPhysicalMemoryBacking(size_t max_capacity);
bool is_initialized() const;
void warn_commit_limits(size_t max) const;
size_t size() const;
size_t commit(size_t offset, size_t length);
size_t uncommit(size_t offset, size_t length);

View File

@ -35,9 +35,8 @@
// committing and uncommitting, each ZGranuleSize'd chunk is mapped to
// a separate paging file mapping.
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
_handles(MaxHeapSize),
_size(0) {}
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
_handles(max_capacity) {}
bool ZPhysicalMemoryBacking::is_initialized() const {
return true;
@ -47,10 +46,6 @@ void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
// Does nothing
}
size_t ZPhysicalMemoryBacking::size() const {
return _size;
}
HANDLE ZPhysicalMemoryBacking::get_handle(uintptr_t offset) const {
HANDLE const handle = _handles.get(offset);
assert(handle != 0, "Should be set");
@ -95,15 +90,7 @@ size_t ZPhysicalMemoryBacking::commit(size_t offset, size_t length) {
log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
offset / M, (offset + length) / M, length / M);
const size_t committed = commit_from_paging_file(offset, length);
const size_t end = offset + committed;
if (end > _size) {
// Update size
_size = end;
}
return committed;
return commit_from_paging_file(offset, length);
}
size_t ZPhysicalMemoryBacking::uncommit(size_t offset, size_t length) {

View File

@ -31,7 +31,6 @@
class ZPhysicalMemoryBacking {
private:
ZGranuleMap<HANDLE> _handles;
size_t _size;
HANDLE get_handle(uintptr_t offset) const;
void put_handle(uintptr_t offset, HANDLE handle);
@ -41,14 +40,12 @@ private:
size_t uncommit_from_paging_file(size_t offset, size_t size);
public:
ZPhysicalMemoryBacking();
ZPhysicalMemoryBacking(size_t max_capacity);
bool is_initialized() const;
void warn_commit_limits(size_t max) const;
size_t size() const;
size_t commit(size_t offset, size_t length);
size_t uncommit(size_t offset, size_t length);

View File

@ -106,7 +106,7 @@ ZPageAllocator::ZPageAllocator(ZWorkers* workers,
size_t max_reserve) :
_lock(),
_virtual(max_capacity),
_physical(),
_physical(max_capacity),
_cache(),
_min_capacity(min_capacity),
_max_capacity(max_capacity),

View File

@ -135,6 +135,12 @@ ZPhysicalMemory ZPhysicalMemory::split(size_t size) {
return pmem;
}
ZPhysicalMemoryManager::ZPhysicalMemoryManager(size_t max_capacity) :
_backing(max_capacity) {
// Register everything as uncommitted
_uncommitted.free(0, max_capacity);
}
bool ZPhysicalMemoryManager::is_initialized() const {
return _backing.is_initialized();
}
@ -145,7 +151,6 @@ void ZPhysicalMemoryManager::warn_commit_limits(size_t max) const {
bool ZPhysicalMemoryManager::supports_uncommit() {
assert(!is_init_completed(), "Invalid state");
assert(_backing.size() >= ZGranuleSize, "Invalid size");
// Test if uncommit is supported by uncommitting and then re-committing a granule
return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
@ -194,18 +199,6 @@ size_t ZPhysicalMemoryManager::commit(size_t size) {
}
}
// Expand backing memory
if (committed < size) {
const size_t remaining = size - committed;
const uintptr_t start = _backing.size();
const size_t expanded = _backing.commit(start, remaining);
if (expanded > 0) {
// Successful or partialy successful
_committed.free(start, expanded);
committed += expanded;
}
}
return committed;
}

View File

@ -78,6 +78,8 @@ private:
void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
public:
ZPhysicalMemoryManager(size_t max_capacity);
bool is_initialized() const;
void warn_commit_limits(size_t max) const;