mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-01 22:30:08 +01:00
124 lines
2.4 KiB
C++
124 lines
2.4 KiB
C++
#pragma once
|
|
|
|
class CPUThread;
|
|
|
|
namespace vm
|
|
{
|
|
template<typename T> class page_alloc_t
|
|
{
|
|
u32 m_addr;
|
|
|
|
void dealloc()
|
|
{
|
|
if (m_addr)
|
|
{
|
|
vm::dealloc_verbose_nothrow(m_addr);
|
|
}
|
|
}
|
|
|
|
public:
|
|
page_alloc_t()
|
|
: m_addr(0)
|
|
{
|
|
}
|
|
|
|
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)))
|
|
{
|
|
}
|
|
|
|
page_alloc_t(const page_alloc_t&) = delete;
|
|
|
|
page_alloc_t(page_alloc_t&& other)
|
|
: m_addr(other.m_addr)
|
|
{
|
|
other.m_addr = 0;
|
|
}
|
|
|
|
~page_alloc_t()
|
|
{
|
|
this->dealloc();
|
|
}
|
|
|
|
page_alloc_t& operator =(const page_alloc_t&) = delete;
|
|
|
|
page_alloc_t& operator =(page_alloc_t&& other)
|
|
{
|
|
std::swap(m_addr, other.m_addr);
|
|
|
|
return *this;
|
|
}
|
|
|
|
u32 get_addr() const
|
|
{
|
|
return m_addr;
|
|
}
|
|
};
|
|
|
|
template<typename T> class stack_alloc_t
|
|
{
|
|
u32 m_addr;
|
|
u32 m_old_pos; // TODO: use the stack to save it?
|
|
|
|
CPUThread& m_thread;
|
|
|
|
public:
|
|
stack_alloc_t() = delete;
|
|
|
|
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)
|
|
{
|
|
}
|
|
|
|
~stack_alloc_t() noexcept(false) // allow exceptions
|
|
{
|
|
if (!std::uncaught_exception()) // don't call during stack unwinding (it's pointless anyway)
|
|
{
|
|
vm::stack_pop(m_thread, m_addr, m_old_pos);
|
|
}
|
|
}
|
|
|
|
stack_alloc_t(const stack_alloc_t&) = delete;
|
|
|
|
stack_alloc_t(stack_alloc_t&&) = delete;
|
|
|
|
stack_alloc_t& operator =(const stack_alloc_t&) = delete;
|
|
|
|
stack_alloc_t& operator =(stack_alloc_t&&) = delete;
|
|
|
|
u32 get_addr() const
|
|
{
|
|
return m_addr;
|
|
}
|
|
};
|
|
|
|
template<typename T, template<typename> class A> class _var_base final : public _ptr_base<T>, private A<T>
|
|
{
|
|
using _ptr_base<T>::m_addr;
|
|
|
|
using allocation = A<T>;
|
|
|
|
public:
|
|
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();
|
|
}
|
|
};
|
|
|
|
template<typename T, template<typename> class A = vm::stack_alloc_t> using varl = _var_base<to_le_t<T>, A>;
|
|
|
|
template<typename T, template<typename> class A = vm::stack_alloc_t> using varb = _var_base<to_be_t<T>, A>;
|
|
|
|
namespace ps3
|
|
{
|
|
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varb<T, A>;
|
|
}
|
|
|
|
namespace psv
|
|
{
|
|
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varl<T, A>;
|
|
}
|
|
}
|