fuchsia: Implement VirtualMemory class
This follows the POSIX-y implementations, using mx_ system calls in place of mmap, et al. Some references: https://fuchsia.googlesource.com/magenta/+/HEAD/docs/objects/vm_address_region.md https://fuchsia.googlesource.com/magenta/+/HEAD/docs/syscalls/vmo_create.md https://fuchsia.googlesource.com/magenta/+/HEAD/docs/syscalls/vmar_map.md https://fuchsia.googlesource.com/magenta/+/HEAD/docs/syscalls/vmar_unmap.md https://fuchsia.googlesource.com/magenta/+/HEAD/docs/syscalls/vmar_protect.md Bug: chromium:731217 Change-Id: I7a33c2cc2b41736e395bd3431b88e6b9621b7ca5 Reviewed-on: https://chromium-review.googlesource.com/619687 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Scott Graham <scottmg@chromium.org> Cr-Commit-Position: refs/heads/master@{#47438}
This commit is contained in:
parent
1518b1e349
commit
736d7696a5
@ -2,7 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <magenta/process.h>
|
||||
#include <magenta/syscalls.h>
|
||||
|
||||
#include "src/base/macros.h"
|
||||
#include "src/base/platform/platform-posix-time.h"
|
||||
@ -18,79 +19,144 @@ TimezoneCache* OS::CreateTimezoneCache() {
|
||||
|
||||
void* OS::Allocate(const size_t requested, size_t* allocated,
|
||||
OS::MemoryPermission access, void* hint) {
|
||||
const size_t msize = RoundUp(requested, AllocateAlignment());
|
||||
int prot = GetProtectionFromMemoryPermission(access);
|
||||
void* mbase = mmap(hint, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (mbase == MAP_FAILED) return NULL;
|
||||
*allocated = msize;
|
||||
return mbase;
|
||||
CHECK(false); // TODO(scottmg): Port, https://crbug.com/731217.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
CHECK(false); // TODO(scottmg): Port, https://crbug.com/731217.
|
||||
return std::vector<SharedLibraryAddress>();
|
||||
}
|
||||
|
||||
void OS::SignalCodeMovingGC() {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
CHECK(false); // TODO(scottmg): Port, https://crbug.com/731217.
|
||||
}
|
||||
|
||||
VirtualMemory::VirtualMemory() : address_(NULL), size_(0) {}
|
||||
VirtualMemory::VirtualMemory() : address_(nullptr), size_(0) {}
|
||||
|
||||
VirtualMemory::VirtualMemory(size_t size, void* hint)
|
||||
: address_(ReserveRegion(size, hint)), size_(size) {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
}
|
||||
: address_(ReserveRegion(size, hint)), size_(size) {}
|
||||
|
||||
VirtualMemory::VirtualMemory(size_t size, size_t alignment, void* hint)
|
||||
: address_(NULL), size_(0) {}
|
||||
: address_(nullptr), size_(0) {
|
||||
DCHECK((alignment % OS::AllocateAlignment()) == 0);
|
||||
hint = AlignedAddress(hint, alignment);
|
||||
size_t request_size =
|
||||
RoundUp(size + alignment, static_cast<intptr_t>(OS::AllocateAlignment()));
|
||||
|
||||
VirtualMemory::~VirtualMemory() {}
|
||||
mx_handle_t vmo;
|
||||
if (mx_vmo_create(request_size, 0, &vmo) != MX_OK) return;
|
||||
static const char kVirtualMemoryName[] = "v8-virtualmem";
|
||||
mx_object_set_property(vmo, MX_PROP_NAME, kVirtualMemoryName,
|
||||
strlen(kVirtualMemoryName));
|
||||
uintptr_t reservation;
|
||||
mx_status_t status = mx_vmar_map(mx_vmar_root_self(), 0, vmo, 0, request_size,
|
||||
0 /*no permissions*/, &reservation);
|
||||
// Either the vmo is now referenced by the vmar, or we failed and are bailing,
|
||||
// so close the vmo either way.
|
||||
mx_handle_close(vmo);
|
||||
if (status != MX_OK) return;
|
||||
|
||||
void VirtualMemory::Reset() {}
|
||||
uint8_t* base = reinterpret_cast<uint8_t*>(reservation);
|
||||
uint8_t* aligned_base = RoundUp(base, alignment);
|
||||
DCHECK_LE(base, aligned_base);
|
||||
|
||||
bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
|
||||
return false;
|
||||
// Unmap extra memory reserved before and after the desired block.
|
||||
if (aligned_base != base) {
|
||||
size_t prefix_size = static_cast<size_t>(aligned_base - base);
|
||||
mx_vmar_unmap(mx_vmar_root_self(), reinterpret_cast<uintptr_t>(base),
|
||||
prefix_size);
|
||||
request_size -= prefix_size;
|
||||
}
|
||||
|
||||
size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
|
||||
DCHECK_LE(aligned_size, request_size);
|
||||
|
||||
if (aligned_size != request_size) {
|
||||
size_t suffix_size = request_size - aligned_size;
|
||||
mx_vmar_unmap(mx_vmar_root_self(),
|
||||
reinterpret_cast<uintptr_t>(aligned_base + aligned_size),
|
||||
suffix_size);
|
||||
request_size -= suffix_size;
|
||||
}
|
||||
|
||||
DCHECK(aligned_size == request_size);
|
||||
|
||||
address_ = static_cast<void*>(aligned_base);
|
||||
size_ = aligned_size;
|
||||
}
|
||||
|
||||
bool VirtualMemory::Uncommit(void* address, size_t size) { return false; }
|
||||
VirtualMemory::~VirtualMemory() {
|
||||
if (IsReserved()) {
|
||||
bool result = ReleaseRegion(address(), size());
|
||||
DCHECK(result);
|
||||
USE(result);
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtualMemory::Guard(void* address) { return false; }
|
||||
void VirtualMemory::Reset() {
|
||||
address_ = nullptr;
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
|
||||
CHECK(InVM(address, size));
|
||||
return CommitRegion(address, size, is_executable);
|
||||
}
|
||||
|
||||
bool VirtualMemory::Uncommit(void* address, size_t size) {
|
||||
return UncommitRegion(address, size);
|
||||
}
|
||||
|
||||
bool VirtualMemory::Guard(void* address) {
|
||||
return mx_vmar_protect(mx_vmar_root_self(),
|
||||
reinterpret_cast<uintptr_t>(address),
|
||||
OS::CommitPageSize(), 0 /*no permissions*/) == MX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void* VirtualMemory::ReserveRegion(size_t size, void* hint) {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
return NULL;
|
||||
mx_handle_t vmo;
|
||||
if (mx_vmo_create(size, 0, &vmo) != MX_OK) return nullptr;
|
||||
uintptr_t result;
|
||||
mx_status_t status = mx_vmar_map(mx_vmar_root_self(), 0, vmo, 0, size,
|
||||
0 /*no permissions*/, &result);
|
||||
mx_handle_close(vmo);
|
||||
if (status != MX_OK) return nullptr;
|
||||
return reinterpret_cast<void*>(result);
|
||||
}
|
||||
|
||||
// static
|
||||
bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
return false;
|
||||
uint32_t prot = MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE |
|
||||
(is_executable ? MX_VM_FLAG_PERM_EXECUTE : 0);
|
||||
return mx_vmar_protect(mx_vmar_root_self(), reinterpret_cast<uintptr_t>(base),
|
||||
size, prot) == MX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
bool VirtualMemory::UncommitRegion(void* base, size_t size) {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
return false;
|
||||
return mx_vmar_protect(mx_vmar_root_self(), reinterpret_cast<uintptr_t>(base),
|
||||
size, 0 /*no permissions*/) == MX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
bool VirtualMemory::ReleasePartialRegion(void* base, size_t size,
|
||||
void* free_start, size_t free_size) {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
return false;
|
||||
return mx_vmar_unmap(mx_vmar_root_self(),
|
||||
reinterpret_cast<uintptr_t>(free_start),
|
||||
free_size) == MX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
return false;
|
||||
return mx_vmar_unmap(mx_vmar_root_self(), reinterpret_cast<uintptr_t>(base),
|
||||
size) == MX_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
bool VirtualMemory::HasLazyCommits() {
|
||||
CHECK(false); // TODO(fuchsia): Port, https://crbug.com/731217.
|
||||
// TODO(scottmg): Port, https://crbug.com/731217.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user