8245203: ZGC: Don't track size in ZPhysicalMemoryBacking
Reviewed-by: eosterlund, stefank
This commit is contained in:
parent
82e3640eb1
commit
4d8189b265
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user