MemArena: Clean up the code that does the mirroring

This commit is contained in:
Jasper St. Pierre 2014-10-28 04:44:59 -07:00
parent 6813473367
commit 079b881d20
2 changed files with 31 additions and 18 deletions

View file

@ -174,45 +174,56 @@ static bool Memory_TryBase(u8 *base, MemoryView *views, int num_views, u32 flags
{
// OK, we know where to find free space. Now grab it!
// We just mimic the popular BAT setup.
u32 position = 0;
u32 last_position = 0;
u32 shm_position = 0;
// Zero all the pointers to be sure.
for (int i = 0; i < num_views; i++)
{
views[i].mapped_ptr = nullptr;
if (!(views[i].flags & MV_MIRROR_PREVIOUS) && i > 0)
shm_position += views[i - 1].size;
views[i].shm_position = shm_position;
}
int i;
for (i = 0; i < num_views; i++)
{
SKIP(flags, views[i].flags);
MemoryView* view = &views[i];
void* view_base;
bool use_sw_mirror;
if (views[i].flags & MV_MIRROR_PREVIOUS)
position = last_position;
SKIP(flags, view->flags);
#if _ARCH_64
views[i].mapped_ptr = arena->CreateView(
position, views[i].size, base + views[i].virtual_address);
// On 64-bit, we map the same file position multiple times, so we
// don't need the software fallback for the mirrors.
view_base = base + view->virtual_address;
use_sw_mirror = false;
#else
if (views[i].flags & MV_MIRROR_PREVIOUS)
// On 32-bit, we don't have the actual address space to store all
// the mirrors, so we just map the fallbacks somewhere in our address
// space and use the software fallbacks for mirroring.
view_base = base + (view->virtual_address & 0x3FFFFFFF);
use_sw_mirror = true;
#endif
if (use_sw_mirror && (view->flags & MV_MIRROR_PREVIOUS))
{
// No need to create multiple identical views.
views[i].mapped_ptr = views[i - 1].mapped_ptr;
view->view_ptr = views[i - 1].view_ptr;
}
else
{
views[i].mapped_ptr = arena->CreateView(
position, views[i].size, base + (views[i].virtual_address & 0x3FFFFFFF));
view->mapped_ptr = arena->CreateView(view->shm_position, view->size, view_base);
view->view_ptr = view->mapped_ptr;
}
#endif
if (!views[i].mapped_ptr)
if (!view->view_ptr)
goto bail;
if (views[i].out_ptr)
*views[i].out_ptr = (u8*) views[i].mapped_ptr;
position += views[i].size;
if (view->out_ptr)
*(view->out_ptr) = (u8*) view->view_ptr;
}
return true;

View file

@ -48,6 +48,8 @@ struct MemoryView
u32 size;
u32 flags;
void* mapped_ptr;
void* view_ptr;
u32 shm_position;
};
// Uses a memory arena to set up an emulator-friendly memory map according to