Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8245203: ZGC: Don't track size in ZPhysicalMemoryBacking
Reviewed-by: eosterlund, stefank
  • Loading branch information
pliden committed Jun 9, 2020
1 parent 82e3640 commit 4d8189b265c6050017ba7208d2b14d8b7a7e5e67
@@ -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;
}
}

// 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;
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);
}

// 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 @@ class ZPhysicalMemoryBacking {
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 @@ class ZPhysicalMemoryBacking {
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 @@ class ZPhysicalMemoryBacking {
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 @@ class ZPhysicalMemoryManager {
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;

0 comments on commit 4d8189b

Please sign in to comment.