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);
|
return (res == KERN_SUCCESS) ? ZErrno(0) : ZErrno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
|
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
|
||||||
_base(0),
|
_base(0),
|
||||||
_size(0),
|
|
||||||
_initialized(false) {
|
_initialized(false) {
|
||||||
|
|
||||||
// Reserve address space for backing memory
|
// Reserve address space for backing memory
|
||||||
_base = (uintptr_t)os::reserve_memory(MaxHeapSize);
|
_base = (uintptr_t)os::reserve_memory(max_capacity);
|
||||||
if (_base == 0) {
|
if (_base == 0) {
|
||||||
// Failed
|
// Failed
|
||||||
log_error_pd(gc)("Failed to reserve address space for backing memory");
|
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
|
// Does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZPhysicalMemoryBacking::size() const {
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) {
|
bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) {
|
||||||
assert(is_aligned(offset, os::vm_page_size()), "Invalid offset");
|
assert(is_aligned(offset, os::vm_page_size()), "Invalid offset");
|
||||||
assert(is_aligned(length, os::vm_page_size()), "Invalid length");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t end = offset + length;
|
|
||||||
if (end > _size) {
|
|
||||||
// Record new size
|
|
||||||
_size = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -27,20 +27,17 @@
|
|||||||
class ZPhysicalMemoryBacking {
|
class ZPhysicalMemoryBacking {
|
||||||
private:
|
private:
|
||||||
uintptr_t _base;
|
uintptr_t _base;
|
||||||
size_t _size;
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
|
|
||||||
bool commit_inner(size_t offset, size_t length);
|
bool commit_inner(size_t offset, size_t length);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZPhysicalMemoryBacking();
|
ZPhysicalMemoryBacking(size_t max_capacity);
|
||||||
|
|
||||||
bool is_initialized() const;
|
bool is_initialized() const;
|
||||||
|
|
||||||
void warn_commit_limits(size_t max) const;
|
void warn_commit_limits(size_t max) const;
|
||||||
|
|
||||||
size_t size() const;
|
|
||||||
|
|
||||||
size_t commit(size_t offset, size_t length);
|
size_t commit(size_t offset, size_t length);
|
||||||
size_t uncommit(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 int z_fallocate_hugetlbfs_attempts = 3;
|
||||||
static bool z_fallocate_supported = true;
|
static bool z_fallocate_supported = true;
|
||||||
|
|
||||||
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
|
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
|
||||||
_fd(-1),
|
_fd(-1),
|
||||||
_size(0),
|
|
||||||
_filesystem(0),
|
_filesystem(0),
|
||||||
_block_size(0),
|
_block_size(0),
|
||||||
_available(0),
|
_available(0),
|
||||||
@ -127,6 +126,15 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
|
|||||||
return;
|
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
|
// Get filesystem statistics
|
||||||
struct statfs buf;
|
struct statfs buf;
|
||||||
if (fstatfs(_fd, &buf) == -1) {
|
if (fstatfs(_fd, &buf) == -1) {
|
||||||
@ -362,10 +370,6 @@ void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
|
|||||||
warn_max_map_count(max);
|
warn_max_map_count(max);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZPhysicalMemoryBacking::size() const {
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZPhysicalMemoryBacking::is_tmpfs() const {
|
bool ZPhysicalMemoryBacking::is_tmpfs() const {
|
||||||
return _filesystem == TMPFS_MAGIC;
|
return _filesystem == TMPFS_MAGIC;
|
||||||
}
|
}
|
||||||
@ -380,18 +384,6 @@ bool ZPhysicalMemoryBacking::tmpfs_supports_transparent_huge_pages() const {
|
|||||||
return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
|
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 {
|
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
|
// On hugetlbfs, mapping a file segment will fail immediately, without
|
||||||
// the need to touch the mapped pages first, if there aren't enough huge
|
// 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
|
// 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
|
// mmap/munmap (for hugetlbfs and tmpfs with transparent huge pages) or pwrite
|
||||||
// (for tmpfs without transparent huge pages and other filesystem types).
|
// (for tmpfs without transparent huge pages and other filesystem types).
|
||||||
|
if (ZLargePages::is_explicit()) {
|
||||||
const size_t end = offset + length;
|
return fallocate_compat_mmap_hugetlbfs(offset, length, false /* touch */);
|
||||||
if (end > _size) {
|
} else if (ZLargePages::is_transparent()) {
|
||||||
// Increase file size
|
return fallocate_compat_mmap_tmpfs(offset, length);
|
||||||
const ZErrno err = fallocate_compat_ftruncate(end);
|
} else {
|
||||||
if (err) {
|
return fallocate_compat_pwrite(offset, length);
|
||||||
// Failed
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
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;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t end = offset + length;
|
|
||||||
if (end > _size) {
|
|
||||||
// Record new file size
|
|
||||||
_size = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,6 @@ private:
|
|||||||
bool is_hugetlbfs() const;
|
bool is_hugetlbfs() const;
|
||||||
bool tmpfs_supports_transparent_huge_pages() 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_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_mmap_tmpfs(size_t offset, size_t length) const;
|
||||||
ZErrno fallocate_compat_pwrite(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);
|
size_t commit_default(size_t offset, size_t length);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZPhysicalMemoryBacking();
|
ZPhysicalMemoryBacking(size_t max_capacity);
|
||||||
|
|
||||||
bool is_initialized() const;
|
bool is_initialized() const;
|
||||||
|
|
||||||
void warn_commit_limits(size_t max) const;
|
void warn_commit_limits(size_t max) const;
|
||||||
|
|
||||||
size_t size() const;
|
|
||||||
|
|
||||||
size_t commit(size_t offset, size_t length);
|
size_t commit(size_t offset, size_t length);
|
||||||
size_t uncommit(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
|
// committing and uncommitting, each ZGranuleSize'd chunk is mapped to
|
||||||
// a separate paging file mapping.
|
// a separate paging file mapping.
|
||||||
|
|
||||||
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
|
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
|
||||||
_handles(MaxHeapSize),
|
_handles(max_capacity) {}
|
||||||
_size(0) {}
|
|
||||||
|
|
||||||
bool ZPhysicalMemoryBacking::is_initialized() const {
|
bool ZPhysicalMemoryBacking::is_initialized() const {
|
||||||
return true;
|
return true;
|
||||||
@ -47,10 +46,6 @@ void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
|
|||||||
// Does nothing
|
// Does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZPhysicalMemoryBacking::size() const {
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE ZPhysicalMemoryBacking::get_handle(uintptr_t offset) const {
|
HANDLE ZPhysicalMemoryBacking::get_handle(uintptr_t offset) const {
|
||||||
HANDLE const handle = _handles.get(offset);
|
HANDLE const handle = _handles.get(offset);
|
||||||
assert(handle != 0, "Should be set");
|
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)",
|
log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
|
||||||
offset / M, (offset + length) / M, length / M);
|
offset / M, (offset + length) / M, length / M);
|
||||||
|
|
||||||
const size_t committed = commit_from_paging_file(offset, length);
|
return commit_from_paging_file(offset, length);
|
||||||
|
|
||||||
const size_t end = offset + committed;
|
|
||||||
if (end > _size) {
|
|
||||||
// Update size
|
|
||||||
_size = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
return committed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZPhysicalMemoryBacking::uncommit(size_t offset, size_t length) {
|
size_t ZPhysicalMemoryBacking::uncommit(size_t offset, size_t length) {
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
class ZPhysicalMemoryBacking {
|
class ZPhysicalMemoryBacking {
|
||||||
private:
|
private:
|
||||||
ZGranuleMap<HANDLE> _handles;
|
ZGranuleMap<HANDLE> _handles;
|
||||||
size_t _size;
|
|
||||||
|
|
||||||
HANDLE get_handle(uintptr_t offset) const;
|
HANDLE get_handle(uintptr_t offset) const;
|
||||||
void put_handle(uintptr_t offset, HANDLE handle);
|
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);
|
size_t uncommit_from_paging_file(size_t offset, size_t size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZPhysicalMemoryBacking();
|
ZPhysicalMemoryBacking(size_t max_capacity);
|
||||||
|
|
||||||
bool is_initialized() const;
|
bool is_initialized() const;
|
||||||
|
|
||||||
void warn_commit_limits(size_t max) const;
|
void warn_commit_limits(size_t max) const;
|
||||||
|
|
||||||
size_t size() const;
|
|
||||||
|
|
||||||
size_t commit(size_t offset, size_t length);
|
size_t commit(size_t offset, size_t length);
|
||||||
size_t uncommit(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) :
|
size_t max_reserve) :
|
||||||
_lock(),
|
_lock(),
|
||||||
_virtual(max_capacity),
|
_virtual(max_capacity),
|
||||||
_physical(),
|
_physical(max_capacity),
|
||||||
_cache(),
|
_cache(),
|
||||||
_min_capacity(min_capacity),
|
_min_capacity(min_capacity),
|
||||||
_max_capacity(max_capacity),
|
_max_capacity(max_capacity),
|
||||||
|
@ -135,6 +135,12 @@ ZPhysicalMemory ZPhysicalMemory::split(size_t size) {
|
|||||||
return pmem;
|
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 {
|
bool ZPhysicalMemoryManager::is_initialized() const {
|
||||||
return _backing.is_initialized();
|
return _backing.is_initialized();
|
||||||
}
|
}
|
||||||
@ -145,7 +151,6 @@ void ZPhysicalMemoryManager::warn_commit_limits(size_t max) const {
|
|||||||
|
|
||||||
bool ZPhysicalMemoryManager::supports_uncommit() {
|
bool ZPhysicalMemoryManager::supports_uncommit() {
|
||||||
assert(!is_init_completed(), "Invalid state");
|
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
|
// Test if uncommit is supported by uncommitting and then re-committing a granule
|
||||||
return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
|
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;
|
return committed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,8 @@ private:
|
|||||||
void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
|
void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ZPhysicalMemoryManager(size_t max_capacity);
|
||||||
|
|
||||||
bool is_initialized() const;
|
bool is_initialized() const;
|
||||||
|
|
||||||
void warn_commit_limits(size_t max) const;
|
void warn_commit_limits(size_t max) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user