mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-08 09:09:46 +00:00
Improve ppu_thread::stack_push
Save actual stack memory allocation size locally. (not in PS3 memory)
This commit is contained in:
parent
23468a2d07
commit
b6fccee6a4
3 changed files with 39 additions and 19 deletions
|
@ -1292,26 +1292,31 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
||||||
at_ret();
|
at_ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ppu_thread::stack_push(u32 size, u32 align_v)
|
std::pair<vm::addr_t, u32> ppu_thread::stack_push(u32 size, u32 align_v)
|
||||||
{
|
{
|
||||||
if (auto cpu = get_current_cpu_thread<ppu_thread>())
|
if (auto cpu = get_current_cpu_thread<ppu_thread>())
|
||||||
{
|
{
|
||||||
ppu_thread& context = static_cast<ppu_thread&>(*cpu);
|
ppu_thread& context = static_cast<ppu_thread&>(*cpu);
|
||||||
|
|
||||||
const u32 old_pos = vm::cast(context.gpr[1]);
|
const u32 old_pos = vm::cast(context.gpr[1]);
|
||||||
context.gpr[1] -= utils::align(size + 4, 8); // room minimal possible size
|
context.gpr[1] -= size; // room minimal possible size
|
||||||
context.gpr[1] &= ~(u64{align_v} - 1); // fix stack alignment
|
context.gpr[1] &= ~(u64{align_v} - 1); // fix stack alignment
|
||||||
|
|
||||||
if (old_pos >= context.stack_addr && old_pos < context.stack_addr + context.stack_size && context.gpr[1] < context.stack_addr)
|
auto is_stack = [&](u64 addr)
|
||||||
|
{
|
||||||
|
return addr >= context.stack_addr && addr < context.stack_addr + context.stack_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: This check does not care about custom stack memory
|
||||||
|
if (is_stack(old_pos) != is_stack(context.gpr[1]))
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Stack overflow (size=0x%x, align=0x%x, SP=0x%llx, stack=*0x%x)", size, align_v, old_pos, context.stack_addr);
|
fmt::throw_exception("Stack overflow (size=0x%x, align=0x%x, SP=0x%llx, stack=*0x%x)", size, align_v, old_pos, context.stack_addr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const u32 addr = static_cast<u32>(context.gpr[1]);
|
const u32 addr = static_cast<u32>(context.gpr[1]);
|
||||||
vm::_ref<nse_t<u32>>(addr + size) = old_pos;
|
|
||||||
std::memset(vm::base(addr), 0, size);
|
std::memset(vm::base(addr), 0, size);
|
||||||
return addr;
|
return {vm::cast(addr), old_pos - addr};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1330,7 +1335,7 @@ void ppu_thread::stack_pop_verbose(u32 addr, u32 size) noexcept
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.gpr[1] = vm::_ref<nse_t<u32>>(static_cast<u32>(context.gpr[1]) + size);
|
context.gpr[1] += size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ public:
|
||||||
void exec_task();
|
void exec_task();
|
||||||
void fast_call(u32 addr, u32 rtoc);
|
void fast_call(u32 addr, u32 rtoc);
|
||||||
|
|
||||||
static u32 stack_push(u32 size, u32 align_v);
|
static std::pair<vm::addr_t, u32> stack_push(u32 size, u32 align_v);
|
||||||
static void stack_pop_verbose(u32 addr, u32 size) noexcept;
|
static void stack_pop_verbose(u32 addr, u32 size) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,23 +9,23 @@ namespace vm
|
||||||
template <memory_location_t Location = vm::main>
|
template <memory_location_t Location = vm::main>
|
||||||
struct page_allocator
|
struct page_allocator
|
||||||
{
|
{
|
||||||
static inline vm::addr_t alloc(u32 size, u32 align)
|
static inline std::pair<vm::addr_t, u32> alloc(u32 size, u32 align)
|
||||||
{
|
{
|
||||||
return vm::cast(vm::alloc(size, Location, std::max<u32>(align, 0x10000)));
|
return {vm::cast(vm::alloc(size, Location, std::max<u32>(align, 0x10000))), size};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dealloc(u32 addr, u32 /*size*/ = 0) noexcept
|
static inline void dealloc(u32 addr, u32 size) noexcept
|
||||||
{
|
{
|
||||||
ensure(vm::dealloc(addr, Location));
|
ensure(vm::dealloc(addr, Location) >= size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct stack_allocator
|
struct stack_allocator
|
||||||
{
|
{
|
||||||
static inline vm::addr_t alloc(u32 size, u32 align)
|
static inline std::pair<vm::addr_t, u32> alloc(u32 size, u32 align)
|
||||||
{
|
{
|
||||||
return vm::cast(T::stack_push(size, align));
|
return T::stack_push(size, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dealloc(u32 addr, u32 size) noexcept
|
static inline void dealloc(u32 addr, u32 size) noexcept
|
||||||
|
@ -40,6 +40,14 @@ namespace vm
|
||||||
{
|
{
|
||||||
using pointer = _ptr_base<T, const u32>;
|
using pointer = _ptr_base<T, const u32>;
|
||||||
|
|
||||||
|
const u32 m_mem_size;
|
||||||
|
|
||||||
|
_var_base(std::pair<vm::addr_t, u32> alloc_info)
|
||||||
|
: pointer(alloc_info.first)
|
||||||
|
, m_mem_size(alloc_info.second)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Unmoveable object
|
// Unmoveable object
|
||||||
_var_base(const _var_base&) = delete;
|
_var_base(const _var_base&) = delete;
|
||||||
|
@ -49,7 +57,7 @@ namespace vm
|
||||||
using enable_bitcopy = std::false_type; // Disable bitcopy inheritence
|
using enable_bitcopy = std::false_type; // Disable bitcopy inheritence
|
||||||
|
|
||||||
_var_base()
|
_var_base()
|
||||||
: pointer(A::alloc(sizeof(T), alignof(T)))
|
: _var_base(A::alloc(sizeof(T), alignof(T)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +71,7 @@ namespace vm
|
||||||
{
|
{
|
||||||
if (pointer::addr())
|
if (pointer::addr())
|
||||||
{
|
{
|
||||||
A::dealloc(pointer::addr(), sizeof(T));
|
A::dealloc(pointer::addr(), m_mem_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -74,7 +82,15 @@ namespace vm
|
||||||
{
|
{
|
||||||
using pointer = _ptr_base<T, const u32>;
|
using pointer = _ptr_base<T, const u32>;
|
||||||
|
|
||||||
u32 m_size;
|
const u32 m_mem_size;
|
||||||
|
const u32 m_size;
|
||||||
|
|
||||||
|
_var_base(u32 count, std::pair<vm::addr_t, u32> alloc_info)
|
||||||
|
: pointer(alloc_info.first)
|
||||||
|
, m_mem_size(alloc_info.second)
|
||||||
|
, m_size(u32{sizeof(T)} * count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_var_base(const _var_base&) = delete;
|
_var_base(const _var_base&) = delete;
|
||||||
|
@ -84,8 +100,7 @@ namespace vm
|
||||||
using enable_bitcopy = std::false_type; // Disable bitcopy inheritence
|
using enable_bitcopy = std::false_type; // Disable bitcopy inheritence
|
||||||
|
|
||||||
_var_base(u32 count)
|
_var_base(u32 count)
|
||||||
: pointer(A::alloc(u32{sizeof(T)} * count, alignof(T)))
|
: _var_base(count, A::alloc(u32{sizeof(T)} * count, alignof(T)))
|
||||||
, m_size(u32{sizeof(T)} * count)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +116,7 @@ namespace vm
|
||||||
{
|
{
|
||||||
if (pointer::addr())
|
if (pointer::addr())
|
||||||
{
|
{
|
||||||
A::dealloc(pointer::addr(), m_size);
|
A::dealloc(pointer::addr(), m_mem_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue