rpcsx/rpcs3/Emu/Memory/vm_var.h

124 lines
2.4 KiB
C
Raw Normal View History

#pragma once
class CPUThread;
namespace vm
{
2015-08-13 15:28:42 +02:00
template<typename T> class page_alloc_t
{
u32 m_addr;
void dealloc()
{
if (m_addr)
{
vm::dealloc_verbose_nothrow(m_addr);
}
}
public:
2015-08-13 15:28:42 +02:00
page_alloc_t()
: m_addr(0)
{
}
2015-08-13 15:28:42 +02:00
page_alloc_t(vm::memory_location_t location, u32 count = 1)
: m_addr(vm::alloc(sizeof32(T) * count, location, std::max<u32>(alignof32(T), 4096)))
{
}
2015-08-13 15:28:42 +02:00
page_alloc_t(const page_alloc_t&) = delete;
2015-08-13 15:28:42 +02:00
page_alloc_t(page_alloc_t&& other)
: m_addr(other.m_addr)
{
2015-08-13 15:28:42 +02:00
other.m_addr = 0;
}
~page_alloc_t()
{
2015-08-13 15:28:42 +02:00
this->dealloc();
}
2015-08-13 15:28:42 +02:00
page_alloc_t& operator =(const page_alloc_t&) = delete;
2015-08-13 15:28:42 +02:00
page_alloc_t& operator =(page_alloc_t&& other)
{
2015-08-13 15:28:42 +02:00
std::swap(m_addr, other.m_addr);
2015-08-13 15:28:42 +02:00
return *this;
}
2015-08-13 15:28:42 +02:00
u32 get_addr() const
{
return m_addr;
}
};
2015-08-13 15:28:42 +02:00
template<typename T> class stack_alloc_t
{
u32 m_addr;
u32 m_old_pos; // TODO: use the stack to save it?
2015-08-13 15:28:42 +02:00
CPUThread& m_thread;
2015-08-13 15:28:42 +02:00
public:
stack_alloc_t() = delete;
2015-08-13 15:28:42 +02:00
stack_alloc_t(CPUThread& thread, u32 count = 1)
: m_addr(vm::stack_push(thread, sizeof32(T) * count, alignof32(T), m_old_pos))
, m_thread(thread)
{
}
2015-08-13 15:28:42 +02:00
~stack_alloc_t() noexcept(false) // allow exceptions
{
2015-08-13 15:28:42 +02:00
if (!std::uncaught_exception()) // don't call during stack unwinding (it's pointless anyway)
{
2015-08-13 15:28:42 +02:00
vm::stack_pop(m_thread, m_addr, m_old_pos);
}
}
2015-08-13 15:28:42 +02:00
stack_alloc_t(const stack_alloc_t&) = delete;
2015-08-13 15:28:42 +02:00
stack_alloc_t(stack_alloc_t&&) = delete;
2015-08-13 15:28:42 +02:00
stack_alloc_t& operator =(const stack_alloc_t&) = delete;
2015-08-13 15:28:42 +02:00
stack_alloc_t& operator =(stack_alloc_t&&) = delete;
2015-08-13 15:28:42 +02:00
u32 get_addr() const
{
return m_addr;
}
};
2015-08-13 15:28:42 +02:00
template<typename T, template<typename> class A> class _var_base final : public _ptr_base<T>, private A<T>
{
2015-08-13 15:28:42 +02:00
using _ptr_base<T>::m_addr;
2015-01-07 17:44:47 +01:00
using allocation = A<T>;
public:
2015-08-13 15:28:42 +02:00
template<typename... Args, typename = std::enable_if_t<std::is_constructible<A<T>, Args...>::value>> _var_base(Args&&... args)
: allocation(std::forward<Args>(args)...)
{
m_addr = allocation::get_addr();
}
2015-08-13 15:28:42 +02:00
};
2015-08-13 15:28:42 +02:00
template<typename T, template<typename> class A = vm::stack_alloc_t> using varl = _var_base<to_le_t<T>, A>;
2015-08-13 15:28:42 +02:00
template<typename T, template<typename> class A = vm::stack_alloc_t> using varb = _var_base<to_be_t<T>, A>;
2015-03-13 16:06:27 +01:00
2015-08-13 15:28:42 +02:00
namespace ps3
{
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varb<T, A>;
}
2015-08-13 15:28:42 +02:00
namespace psv
{
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varl<T, A>;
}
}