Skip to content
Permalink
Browse files

8237199: ZGC: Rename ZBackingFile to ZPhysicalMemoryBacking

Reviewed-by: stefank, eosterlund, smonteith
  • Loading branch information
pliden committed Jan 17, 2020
1 parent c6dc330 commit 74f0ef505094761c0eb16a7f3fe09b62d335369d
@@ -22,11 +22,11 @@
*/

#include "precompiled.hpp"
#include "gc/z/zBackingFile_bsd.hpp"
#include "gc/z/zErrno.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zLargePages.inline.hpp"
#include "gc/z/zPhysicalMemory.inline.hpp"
#include "gc/z/zPhysicalMemoryBacking_bsd.hpp"
#include "logging/log.hpp"
#include "runtime/globals.hpp"
#include "runtime/os.hpp"
@@ -38,6 +38,10 @@
#include <sys/mman.h>
#include <sys/types.h>

// The backing is represented by a reserved virtual address space, in which
// we commit and uncommit physical memory. Multi-mapping the different heap
// views is done by simply remapping the backing memory using mach_vm_remap().

static int vm_flags_superpage() {
if (!ZLargePages::is_explicit()) {
return 0;
@@ -68,36 +72,36 @@ static ZErrno mremap(uintptr_t from_addr, uintptr_t to_addr, size_t size) {
return (res == KERN_SUCCESS) ? ZErrno(0) : ZErrno(EINVAL);
}

ZBackingFile::ZBackingFile() :
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
_base(0),
_size(0),
_initialized(false) {

// Reserve address space for virtual backing file
// Reserve address space for backing memory
_base = (uintptr_t)os::reserve_memory(MaxHeapSize);
if (_base == 0) {
// Failed
log_error(gc)("Failed to reserve address space for virtual backing file");
log_error(gc)("Failed to reserve address space for backing memory");
return;
}

// Successfully initialized
_initialized = true;
}

bool ZBackingFile::is_initialized() const {
bool ZPhysicalMemoryBacking::is_initialized() const {
return _initialized;
}

void ZBackingFile::warn_commit_limits(size_t max) const {
void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
// Does nothing
}

size_t ZBackingFile::size() const {
size_t ZPhysicalMemoryBacking::size() const {
return _size;
}

bool ZBackingFile::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(length, os::vm_page_size()), "Invalid length");

@@ -114,15 +118,15 @@ bool ZBackingFile::commit_inner(size_t offset, size_t length) {

const size_t end = offset + length;
if (end > _size) {
// Record new virtual file size
// Record new size
_size = end;
}

// Success
return true;
}

size_t ZBackingFile::commit(size_t offset, size_t length) {
size_t ZPhysicalMemoryBacking::commit(size_t offset, size_t length) {
// Try to commit the whole region
if (commit_inner(offset, length)) {
// Success
@@ -150,7 +154,7 @@ size_t ZBackingFile::commit(size_t offset, size_t length) {
}
}

size_t ZBackingFile::uncommit(size_t offset, size_t length) {
size_t ZPhysicalMemoryBacking::uncommit(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");

@@ -168,14 +172,14 @@ size_t ZBackingFile::uncommit(size_t offset, size_t length) {
return length;
}

void ZBackingFile::map(uintptr_t addr, size_t size, uintptr_t offset) const {
void ZPhysicalMemoryBacking::map(uintptr_t addr, size_t size, uintptr_t offset) const {
const ZErrno err = mremap(_base + offset, addr, size);
if (err) {
fatal("Failed to remap memory (%s)", err.to_string());
}
}

void ZBackingFile::unmap(uintptr_t addr, size_t size) const {
void ZPhysicalMemoryBacking::unmap(uintptr_t addr, size_t size) const {
// Note that we must keep the address space reservation intact and just detach
// the backing memory. For this reason we map a new anonymous, non-accessible
// and non-reserved page over the mapping instead of actually unmapping.
@@ -21,20 +21,10 @@
* questions.
*/

#ifndef OS_BSD_GC_Z_ZBACKINGFILE_BSD_HPP
#define OS_BSD_GC_Z_ZBACKINGFILE_BSD_HPP
#ifndef OS_BSD_GC_Z_ZPHYSICALMEMORYBACKING_BSD_HPP
#define OS_BSD_GC_Z_ZPHYSICALMEMORYBACKING_BSD_HPP

#include "memory/allocation.hpp"

class ZPhysicalMemory;

// On macOS, we use a virtual backing file. It is represented by a reserved virtual
// address space, in which we commit physical memory using the mach_vm_map() API.
// The multi-mapping API simply remaps these addresses using mach_vm_remap() into
// the different heap views. This works as-if there was a backing file, it's just
// that the file is represented with memory mappings instead.

class ZBackingFile {
class ZPhysicalMemoryBacking {
private:
uintptr_t _base;
size_t _size;
@@ -43,7 +33,7 @@ class ZBackingFile {
bool commit_inner(size_t offset, size_t length);

public:
ZBackingFile();
ZPhysicalMemoryBacking();

bool is_initialized() const;

@@ -58,4 +48,4 @@ class ZBackingFile {
void unmap(uintptr_t addr, size_t size) const;
};

#endif // OS_BSD_GC_Z_ZBACKINGFILE_BSD_HPP
#endif // OS_BSD_GC_Z_ZPHYSICALMEMORYBACKING_BSD_HPP
@@ -23,11 +23,11 @@

#include "precompiled.hpp"
#include "gc/z/zArray.inline.hpp"
#include "gc/z/zBackingFile_linux.hpp"
#include "gc/z/zBackingPath_linux.hpp"
#include "gc/z/zErrno.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zLargePages.inline.hpp"
#include "gc/z/zPhysicalMemoryBacking_linux.hpp"
#include "gc/z/zSyscall_linux.hpp"
#include "logging/log.hpp"
#include "runtime/init.hpp"
@@ -109,7 +109,7 @@ static const char* z_preferred_hugetlbfs_mountpoints[] = {
static int z_fallocate_hugetlbfs_attempts = 3;
static bool z_fallocate_supported = true;

ZBackingFile::ZBackingFile() :
ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
_fd(-1),
_size(0),
_filesystem(0),
@@ -178,7 +178,7 @@ ZBackingFile::ZBackingFile() :
_initialized = true;
}

int ZBackingFile::create_mem_fd(const char* name) const {
int ZPhysicalMemoryBacking::create_mem_fd(const char* name) const {
// Create file name
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : "");
@@ -198,7 +198,7 @@ int ZBackingFile::create_mem_fd(const char* name) const {
return fd;
}

int ZBackingFile::create_file_fd(const char* name) const {
int ZPhysicalMemoryBacking::create_file_fd(const char* name) const {
const char* const filesystem = ZLargePages::is_explicit()
? ZFILESYSTEM_HUGETLBFS
: ZFILESYSTEM_TMPFS;
@@ -260,7 +260,7 @@ int ZBackingFile::create_file_fd(const char* name) const {
return fd;
}

int ZBackingFile::create_fd(const char* name) const {
int ZPhysicalMemoryBacking::create_fd(const char* name) const {
if (ZPath == NULL) {
// If the path is not explicitly specified, then we first try to create a memfd file
// instead of looking for a tmpfd/hugetlbfs mount point. Note that memfd_create() might
@@ -278,11 +278,11 @@ int ZBackingFile::create_fd(const char* name) const {
return create_file_fd(name);
}

bool ZBackingFile::is_initialized() const {
bool ZPhysicalMemoryBacking::is_initialized() const {
return _initialized;
}

void ZBackingFile::warn_available_space(size_t max) const {
void ZPhysicalMemoryBacking::warn_available_space(size_t max) const {
// Note that the available space on a tmpfs or a hugetlbfs filesystem
// will be zero if no size limit was specified when it was mounted.
if (_available == 0) {
@@ -307,7 +307,7 @@ void ZBackingFile::warn_available_space(size_t max) const {
}
}

void ZBackingFile::warn_max_map_count(size_t max) const {
void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
FILE* const file = fopen(filename, "r");
if (file == NULL) {
@@ -342,33 +342,33 @@ void ZBackingFile::warn_max_map_count(size_t max) const {
}
}

void ZBackingFile::warn_commit_limits(size_t max) const {
void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
// Warn if available space is too low
warn_available_space(max);

// Warn if max map count is too low
warn_max_map_count(max);
}

size_t ZBackingFile::size() const {
size_t ZPhysicalMemoryBacking::size() const {
return _size;
}

bool ZBackingFile::is_tmpfs() const {
bool ZPhysicalMemoryBacking::is_tmpfs() const {
return _filesystem == TMPFS_MAGIC;
}

bool ZBackingFile::is_hugetlbfs() const {
bool ZPhysicalMemoryBacking::is_hugetlbfs() const {
return _filesystem == HUGETLBFS_MAGIC;
}

bool ZBackingFile::tmpfs_supports_transparent_huge_pages() const {
bool ZPhysicalMemoryBacking::tmpfs_supports_transparent_huge_pages() const {
// If the shmem_enabled file exists and is readable then we
// know the kernel supports transparent huge pages for tmpfs.
return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
}

ZErrno ZBackingFile::fallocate_compat_ftruncate(size_t size) const {
ZErrno ZPhysicalMemoryBacking::fallocate_compat_ftruncate(size_t size) const {
while (ftruncate(_fd, size) == -1) {
if (errno != EINTR) {
// Failed
@@ -380,7 +380,7 @@ ZErrno ZBackingFile::fallocate_compat_ftruncate(size_t size) const {
return 0;
}

ZErrno ZBackingFile::fallocate_compat_mmap(size_t offset, size_t length, bool touch) const {
ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap(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
// pages available to back the mapping.
@@ -410,7 +410,7 @@ ZErrno ZBackingFile::fallocate_compat_mmap(size_t offset, size_t length, bool to
return 0;
}

ZErrno ZBackingFile::fallocate_compat_pwrite(size_t offset, size_t length) const {
ZErrno ZPhysicalMemoryBacking::fallocate_compat_pwrite(size_t offset, size_t length) const {
uint8_t data = 0;

// Allocate backing memory by writing to each block
@@ -425,7 +425,7 @@ ZErrno ZBackingFile::fallocate_compat_pwrite(size_t offset, size_t length) const
return 0;
}

ZErrno ZBackingFile::fallocate_fill_hole_compat(size_t offset, size_t length) {
ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_compat(size_t offset, size_t length) {
// fallocate(2) is only supported by tmpfs since Linux 3.5, and by hugetlbfs
// since Linux 4.3. When fallocate(2) is not supported we emulate it using
// ftruncate/pwrite (for tmpfs) or ftruncate/mmap/munmap (for hugetlbfs).
@@ -462,7 +462,7 @@ ZErrno ZBackingFile::fallocate_fill_hole_compat(size_t offset, size_t length) {
return 0;
}

ZErrno ZBackingFile::fallocate_fill_hole_syscall(size_t offset, size_t length) {
ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_syscall(size_t offset, size_t length) {
const int mode = 0; // Allocate
const int res = ZSyscall::fallocate(_fd, mode, offset, length);
if (res == -1) {
@@ -480,7 +480,7 @@ ZErrno ZBackingFile::fallocate_fill_hole_syscall(size_t offset, size_t length) {
return 0;
}

ZErrno ZBackingFile::fallocate_fill_hole(size_t offset, size_t length) {
ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole(size_t offset, size_t length) {
// Using compat mode is more efficient when allocating space on hugetlbfs.
// Note that allocating huge pages this way will only reserve them, and not
// associate them with segments of the file. We must guarantee that we at
@@ -505,7 +505,7 @@ ZErrno ZBackingFile::fallocate_fill_hole(size_t offset, size_t length) {
return fallocate_fill_hole_compat(offset, length);
}

ZErrno ZBackingFile::fallocate_punch_hole(size_t offset, size_t length) {
ZErrno ZPhysicalMemoryBacking::fallocate_punch_hole(size_t offset, size_t length) {
if (is_hugetlbfs()) {
// We can only punch hole in pages that have been touched. Non-touched
// pages are only reserved, and not associated with any specific file
@@ -528,7 +528,7 @@ ZErrno ZBackingFile::fallocate_punch_hole(size_t offset, size_t length) {
return 0;
}

ZErrno ZBackingFile::split_and_fallocate(bool punch_hole, size_t offset, size_t length) {
ZErrno ZPhysicalMemoryBacking::split_and_fallocate(bool punch_hole, size_t offset, size_t length) {
// Try first half
const size_t offset0 = offset;
const size_t length0 = align_up(length / 2, _block_size);
@@ -549,7 +549,7 @@ ZErrno ZBackingFile::split_and_fallocate(bool punch_hole, size_t offset, size_t
return 0;
}

ZErrno ZBackingFile::fallocate(bool punch_hole, size_t offset, size_t length) {
ZErrno ZPhysicalMemoryBacking::fallocate(bool punch_hole, size_t offset, size_t length) {
assert(is_aligned(offset, _block_size), "Invalid offset");
assert(is_aligned(length, _block_size), "Invalid length");

@@ -565,7 +565,7 @@ ZErrno ZBackingFile::fallocate(bool punch_hole, size_t offset, size_t length) {
return err;
}

bool ZBackingFile::commit_inner(size_t offset, size_t length) {
bool ZPhysicalMemoryBacking::commit_inner(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);

@@ -596,7 +596,7 @@ bool ZBackingFile::commit_inner(size_t offset, size_t length) {
return true;
}

size_t ZBackingFile::commit(size_t offset, size_t length) {
size_t ZPhysicalMemoryBacking::commit(size_t offset, size_t length) {
// Try to commit the whole region
if (commit_inner(offset, length)) {
// Success
@@ -624,7 +624,7 @@ size_t ZBackingFile::commit(size_t offset, size_t length) {
}
}

size_t ZBackingFile::uncommit(size_t offset, size_t length) {
size_t ZPhysicalMemoryBacking::uncommit(size_t offset, size_t length) {
log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
offset / M, (offset + length) / M, length / M);

@@ -637,15 +637,15 @@ size_t ZBackingFile::uncommit(size_t offset, size_t length) {
return length;
}

void ZBackingFile::map(uintptr_t addr, size_t size, uintptr_t offset) const {
void ZPhysicalMemoryBacking::map(uintptr_t addr, size_t size, uintptr_t offset) const {
const void* const res = mmap((void*)addr, size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _fd, offset);
if (res == MAP_FAILED) {
ZErrno err;
fatal("Failed to map memory (%s)", err.to_string());
}
}

void ZBackingFile::unmap(uintptr_t addr, size_t size) const {
void ZPhysicalMemoryBacking::unmap(uintptr_t addr, size_t size) const {
// Note that we must keep the address space reservation intact and just detach
// the backing memory. For this reason we map a new anonymous, non-accessible
// and non-reserved page over the mapping instead of actually unmapping.

0 comments on commit 74f0ef5

Please sign in to comment.