Merge pull request #4936 from lioncash/page
page_table: Allow page tables to be moved
This commit is contained in:
commit
92344da20c
|
@ -8,7 +8,7 @@ namespace Common {
|
||||||
|
|
||||||
PageTable::PageTable() = default;
|
PageTable::PageTable() = default;
|
||||||
|
|
||||||
PageTable::~PageTable() = default;
|
PageTable::~PageTable() noexcept = default;
|
||||||
|
|
||||||
void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
|
void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
|
||||||
bool has_attribute) {
|
bool has_attribute) {
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <tuple>
|
||||||
|
|
||||||
#include <boost/icl/interval_map.hpp>
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/memory_hook.h"
|
#include "common/memory_hook.h"
|
||||||
|
@ -51,13 +49,21 @@ struct SpecialRegion {
|
||||||
*/
|
*/
|
||||||
struct PageTable {
|
struct PageTable {
|
||||||
PageTable();
|
PageTable();
|
||||||
~PageTable();
|
~PageTable() noexcept;
|
||||||
|
|
||||||
|
PageTable(const PageTable&) = delete;
|
||||||
|
PageTable& operator=(const PageTable&) = delete;
|
||||||
|
|
||||||
|
PageTable(PageTable&&) noexcept = default;
|
||||||
|
PageTable& operator=(PageTable&&) noexcept = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the page table to be able to accomodate enough pages within
|
* Resizes the page table to be able to accomodate enough pages within
|
||||||
* a given address space.
|
* a given address space.
|
||||||
*
|
*
|
||||||
* @param address_space_width_in_bits The address size width in bits.
|
* @param address_space_width_in_bits The address size width in bits.
|
||||||
|
* @param page_size_in_bits The page size in bits.
|
||||||
|
* @param has_attribute Whether or not this page has any backing attributes.
|
||||||
*/
|
*/
|
||||||
void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
|
void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
|
||||||
bool has_attribute);
|
bool has_attribute);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
void* AllocateMemoryPages(std::size_t size) {
|
void* AllocateMemoryPages(std::size_t size) noexcept {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void* base{VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE)};
|
void* base{VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE)};
|
||||||
#else
|
#else
|
||||||
|
@ -29,7 +29,7 @@ void* AllocateMemoryPages(std::size_t size) {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) {
|
void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) noexcept {
|
||||||
if (!base) {
|
if (!base) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,25 +4,44 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
void* AllocateMemoryPages(std::size_t size);
|
void* AllocateMemoryPages(std::size_t size) noexcept;
|
||||||
void FreeMemoryPages(void* base, std::size_t size);
|
void FreeMemoryPages(void* base, std::size_t size) noexcept;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class VirtualBuffer final : NonCopyable {
|
class VirtualBuffer final {
|
||||||
public:
|
public:
|
||||||
|
static_assert(
|
||||||
|
std::is_trivially_constructible_v<T>,
|
||||||
|
"T must be trivially constructible, as non-trivial constructors will not be executed "
|
||||||
|
"with the current allocator");
|
||||||
|
|
||||||
constexpr VirtualBuffer() = default;
|
constexpr VirtualBuffer() = default;
|
||||||
explicit VirtualBuffer(std::size_t count) : alloc_size{count * sizeof(T)} {
|
explicit VirtualBuffer(std::size_t count) : alloc_size{count * sizeof(T)} {
|
||||||
base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
|
base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
~VirtualBuffer() {
|
~VirtualBuffer() noexcept {
|
||||||
FreeMemoryPages(base_ptr, alloc_size);
|
FreeMemoryPages(base_ptr, alloc_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VirtualBuffer(const VirtualBuffer&) = delete;
|
||||||
|
VirtualBuffer& operator=(const VirtualBuffer&) = delete;
|
||||||
|
|
||||||
|
VirtualBuffer(VirtualBuffer&& other) noexcept
|
||||||
|
: alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr),
|
||||||
|
nullptr} {}
|
||||||
|
|
||||||
|
VirtualBuffer& operator=(VirtualBuffer&& other) noexcept {
|
||||||
|
alloc_size = std::exchange(other.alloc_size, 0);
|
||||||
|
base_ptr = std::exchange(other.base_ptr, nullptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void resize(std::size_t count) {
|
void resize(std::size_t count) {
|
||||||
FreeMemoryPages(base_ptr, alloc_size);
|
FreeMemoryPages(base_ptr, alloc_size);
|
||||||
|
|
||||||
|
|
Reference in New Issue