newHostVM:

* Moved profiler management to the RecompiledCodeReserve class.
 * Improved error handling some more.
 * Numerous minor cleanups.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/newHostVM@3991 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-11-03 14:18:30 +00:00
parent bd8127f75e
commit 5579350d22
18 changed files with 328 additions and 154 deletions

View File

@ -185,6 +185,7 @@ static const sptr _256kb = _128kb * 2;
static const s64 _1mb = 0x100000;
static const s64 _8mb = _1mb * 8;
static const s64 _16mb = _1mb * 16;
static const s64 _32mb = _1mb * 32;
static const s64 _64mb = _1mb * 64;
static const s64 _256mb = _1mb * 256;
static const s64 _1gb = _256mb * 4;

View File

@ -172,10 +172,11 @@ public:
m_read = m_write = m_exec = allow;
return *this;
}
bool CanRead() const { return m_read; }
bool CanWrite() const { return m_write; }
bool CanExecute() const { return m_exec && m_read; }
bool IsNone() const { return !m_read && !m_write; }
wxString ToString() const;
};
@ -218,8 +219,12 @@ static __fi PageProtectionMode PageAccess_Any()
namespace HostSys
{
void* MmapReserve(uptr base, size_t size);
void MmapCommit(void* base, size_t size);
void MmapReset(void* base, size_t size);
void MmapCommit(uptr base, size_t size, const PageProtectionMode& mode);
void MmapReset(uptr base, size_t size);
void* MmapReservePtr(void* base, size_t size);
void MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode);
void MmapResetPtr(void* base, size_t size);
// Maps a block of memory for use as a recompiled code buffer.
// Returns NULL on allocation failure.

View File

@ -35,7 +35,7 @@ static __ri void PageSizeAssertionTest( size_t size )
);
}
void* HostSys::MmapReserve(uptr base, size_t size)
void* HostSys::MmapReservePtr(void* base, size_t size)
{
PageSizeAssertionTest(size);
@ -43,17 +43,21 @@ void* HostSys::MmapReserve(uptr base, size_t size)
// or anonymous source, with PROT_NONE (no-access) permission. Since the mapping
// is completely inaccessible, the OS will simply reserve it and will not put it
// against the commit table.
return mmap((void*)base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
void HostSys::MmapCommit(void* base, size_t size)
void HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode)
{
// In linux, reserved memory is automatically committed when its permissions are
// changed to something other than PROT_NONE. Since PCSX2 code *must* do that itself
// prior to making use of memory anyway, this call should be a NOP.
// changed to something other than PROT_NONE. If the user is committing memory
// as PROT_NONE, then just ignore this call (memory will be committed automatically
// later when the user changes permissions to something useful via calls to MemProtect).
if (mode.IsNone()) return;
MemProtect( base, size, mode );
}
void HostSys::MmapReset(void* base, size_t size)
void HostSys::MmapResetPtr(void* base, size_t size)
{
// On linux the only way to reset the memory is to unmap and remap it as PROT_NONE.
// That forces linux to unload all committed pages and start from scratch.
@ -73,6 +77,21 @@ void HostSys::MmapReset(void* base, size_t size)
));
}
void* HostSys::MmapReserve(uptr base, size_t size)
{
return MmapReservePtr((void*)base, size);
}
void HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode)
{
MmapCommitPtr( (void*)base, size, mode );
}
void HostSys::MmapReset(uptr base, size_t size)
{
MmapResetPtr((void*)base, size);
}
void* HostSys::Mmap(uptr base, size_t size)
{
PageSizeAssertionTest(size);

View File

@ -85,7 +85,7 @@ void* BaseVirtualMemoryReserve::Reserve( uint size, uptr base, uptr upper_bounds
// Let's try again at an OS-picked memory area, and then hope it meets needed
// boundschecking criteria below.
SafeSysMunmap( m_baseptr, reserved_bytes );
m_baseptr = (void*)HostSys::MmapReserve( NULL, reserved_bytes );
m_baseptr = HostSys::MmapReserve( 0, reserved_bytes );
}
if ((upper_bounds != 0) && (((uptr)m_baseptr + reserved_bytes) > upper_bounds))
@ -100,20 +100,6 @@ void* BaseVirtualMemoryReserve::Reserve( uint size, uptr base, uptr upper_bounds
DevCon.WriteLn( Color_Blue, L"%-32s @ 0x%08X -> 0x%08X [%umb]", Name.c_str(),
m_baseptr, (uptr)m_baseptr+reserved_bytes, reserved_bytes / _1mb);
/*if (m_def_commit)
{
const uint camt = m_def_commit * __pagesize;
HostSys::MmapCommit(m_baseptr, camt);
HostSys::MemProtect(m_baseptr, camt, m_prot_mode);
u8* init = (u8*)m_baseptr;
u8* endpos = init + camt;
for( ; init<endpos; init += m_block_size*__pagesize )
OnCommittedBlock(init);
m_commited += m_def_commit * __pagesize;
}*/
return m_baseptr;
}
@ -123,7 +109,7 @@ void BaseVirtualMemoryReserve::Reset()
if (!m_commited) return;
HostSys::MemProtect(m_baseptr, m_commited*__pagesize, PageAccess_None());
HostSys::MmapReset(m_baseptr, m_commited*__pagesize);
HostSys::MmapResetPtr(m_baseptr, m_commited*__pagesize);
m_commited = 0;
}
@ -145,8 +131,7 @@ void BaseVirtualMemoryReserve::OnPageFaultEvent(const PageFaultInfo& info, bool&
// first block being committed! Commit the default requested
// amount if its different from the blocksize.
HostSys::MmapCommit(m_baseptr, camt);
HostSys::MemProtect(m_baseptr, camt, m_prot_mode);
HostSys::MmapCommitPtr(m_baseptr, camt, m_prot_mode);
u8* init = (u8*)m_baseptr;
u8* endpos = init + camt;
@ -163,8 +148,7 @@ void BaseVirtualMemoryReserve::OnPageFaultEvent(const PageFaultInfo& info, bool&
// Depending on the operating system, one or both of these could fail if the system
// is low on either physical ram or virtual memory.
HostSys::MmapCommit(bleh, m_block_size*__pagesize);
HostSys::MemProtect(bleh, m_block_size*__pagesize, m_prot_mode);
HostSys::MmapCommitPtr(bleh, m_block_size*__pagesize, m_prot_mode);
m_commited += m_block_size;
OnCommittedBlock(bleh);

View File

@ -17,27 +17,59 @@
#include "Utilities/RedtapeWindows.h"
#include <winnt.h>
void* HostSys::MmapReserve(uptr base, size_t size)
static DWORD ConvertToWinApi( const PageProtectionMode& mode )
{
return VirtualAlloc((void*)base, size, MEM_RESERVE, PAGE_NOACCESS);
DWORD winmode = PAGE_NOACCESS;
// Windows has some really bizarre memory protection enumeration that uses bitwise
// numbering (like flags) but is in fact not a flag value. *Someone* from the early
// microsoft days wasn't a very good coder, me thinks. --air
if (mode.CanExecute())
{
winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else if (mode.CanRead())
{
winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY;
}
return winmode;
}
void HostSys::MmapCommit(void* base, size_t size)
void* HostSys::MmapReservePtr(void* base, size_t size)
{
// Execution flag for this and the Reserve should match... ?
void* result = VirtualAlloc(base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
return VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
}
void HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode)
{
void* result = VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode));
pxAssumeDev(result, L"VirtualAlloc COMMIT failed: " + Exception::WinApiError().GetMsgFromWindows());
}
void HostSys::MmapReset(void* base, size_t size)
void HostSys::MmapResetPtr(void* base, size_t size)
{
// Execution flag is actually irrelevant for this operation, but whatever.
//void* result = VirtualAlloc((void*)base, size, MEM_RESET, PAGE_EXECUTE_READWRITE);
//pxAssumeDev(result, L"VirtualAlloc RESET failed: " + Exception::WinApiError().GetMsgFromWindows());
VirtualFree(base, size, MEM_DECOMMIT);
}
void* HostSys::MmapReserve(uptr base, size_t size)
{
return MmapReservePtr((void*)base, size);
}
void HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode)
{
MmapCommitPtr( (void*)base, size, mode );
}
void HostSys::MmapReset(uptr base, size_t size)
{
MmapResetPtr((void*)base, size);
}
void* HostSys::Mmap(uptr base, size_t size)
{
return VirtualAlloc((void*)base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
@ -57,24 +89,9 @@ void HostSys::MemProtect( void* baseaddr, size_t size, const PageProtectionMode&
L"\tPage Size: 0x%04x (%d), Block Size: 0x%04x (%d)",
__pagesize, __pagesize, size, size )
);
DWORD winmode = PAGE_NOACCESS;
// Windows has some really bizarre memory protection enumeration that uses bitwise
// numbering (like flags) but is in fact not a flag value. *Someone* from the early
// microsoft days wasn't a very good coder, me thinks. --air
if (mode.CanExecute())
{
winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else if (mode.CanRead())
{
winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY;
}
DWORD OldProtect; // enjoy my uselessness, yo!
if (!VirtualProtect( baseaddr, size, winmode, &OldProtect ))
if (!VirtualProtect( baseaddr, size, ConvertToWinApi(mode), &OldProtect ))
{
throw Exception::WinApiError().SetDiagMsg(
pxsFmt(L"VirtualProtect failed @ 0x%08X -> 0x%08X (mode=%s)",

View File

@ -437,6 +437,14 @@ static void intThrowException( const BaseException& ex )
ex.Rethrow();
}
static void intSetCacheReserve( uint reserveInMegs )
{
}
static uint intGetCacheReserve()
{
return 0;
}
R5900cpu intCpu =
{
@ -451,4 +459,7 @@ R5900cpu intCpu =
intThrowException,
intThrowException,
intClear,
intGetCacheReserve,
intSetCacheReserve,
};

View File

@ -184,11 +184,23 @@ static void intClear(u32 Addr, u32 Size) {
static void intShutdown() {
}
static void intSetCacheReserve( uint reserveInMegs )
{
}
static uint intGetCacheReserve()
{
return 0;
}
R3000Acpu psxInt = {
intReserve,
intReset,
intExecute,
intExecuteBlock,
intClear,
intShutdown
intShutdown,
intGetCacheReserve,
intSetCacheReserve
};

View File

@ -32,7 +32,6 @@
#include "CDVD/CDVD.h"
#include "Patch.h"
#include "GameDatabase.h"
#include "SamplProf.h"
using namespace R5900; // for R5900 disasm tools

View File

@ -30,6 +30,10 @@ void ProfilerRegisterSource(const char* Name, const void* buff, u32 sz);
void ProfilerRegisterSource(const char* Name, const void* function);
void ProfilerTerminateSource( const char* Name );
void ProfilerRegisterSource(const wxString& Name, const void* buff, u32 sz);
void ProfilerRegisterSource(const wxString& Name, const void* function);
void ProfilerTerminateSource( const wxString& Name );
#else
// Disables the profiler in Debug & Linux builds.

View File

@ -18,6 +18,8 @@
#include "IopCommon.h"
#include "VUmicro.h"
#include "SamplProf.h"
// Includes needed for cleanup, since we don't have a good system (yet) for
// cleaning up these things.
#include "GameDatabase.h"
@ -34,14 +36,104 @@ extern void resetNewVif(int idx);
// --------------------------------------------------------------------------------------
// RecompiledCodeReserve (implementations)
// --------------------------------------------------------------------------------------
// Constructor!
// Parameters:
// name - a nice long name that accurately describes the contents of this reserve.
RecompiledCodeReserve::RecompiledCodeReserve( const wxString& name, uint defCommit )
: BaseVirtualMemoryReserve( name )
{
m_block_size = (1024 * 128) / __pagesize;
m_prot_mode = PageAccess_Any();
m_def_commit = defCommit / __pagesize;
m_profiler_registered = false;
}
RecompiledCodeReserve::~RecompiledCodeReserve() throw()
{
_termProfiler();
}
void RecompiledCodeReserve::_registerProfiler()
{
if (m_profiler_name.IsEmpty() || !IsOk()) return;
ProfilerRegisterSource( m_profiler_name, m_baseptr, GetReserveSizeInBytes() );
m_profiler_registered = true;
}
void RecompiledCodeReserve::_termProfiler()
{
if (m_profiler_registered)
ProfilerTerminateSource( m_profiler_name );
}
void* RecompiledCodeReserve::Reserve( uint size, uptr base, uptr upper_bounds )
{
if (!__parent::Reserve(size, base, upper_bounds)) return NULL;
_registerProfiler();
return m_baseptr;
}
// If growing the array, or if shrinking the array to some point that's still *greater* than the
// committed memory range, then attempt a passive "on-the-fly" resize that maps/unmaps some portion
// of the reserve.
//
// If the above conditions are not met, or if the map/unmap fails, this method returns false.
// The caller will be responsible for manually resetting the reserve.
//
// Parameters:
// newsize - new size of the reserved buffer, in bytes.
bool RecompiledCodeReserve::TryResize( uint newsize )
{
uint newPages = (newsize + __pagesize - 1) / __pagesize;
if (newPages > m_reserved)
{
uint toReservePages = newPages - m_reserved;
uint toReserveBytes = toReservePages * __pagesize;
DevCon.WriteLn( L"%-32s is being expanded by %u pages.", Name.c_str(), toReservePages);
m_baseptr = (void*)HostSys::MmapReserve((uptr)GetPtrEnd(), toReserveBytes);
if (!m_baseptr)
{
Console.Warning("%-32s could not be passively resized due to virtual memory conflict!");
Console.Indent().Warning("(attempted to map memory @ 0x%08X -> 0x%08X", m_baseptr, (uptr)m_baseptr+toReserveBytes);
}
DevCon.WriteLn( Color_Blue, L"%-32s @ 0x%08X -> 0x%08X [%umb]", Name.c_str(),
m_baseptr, (uptr)m_baseptr+toReserveBytes, toReserveBytes / _1mb);
}
else if (newPages < m_reserved)
{
if (m_commited > newsize) return false;
uint toRemovePages = m_reserved - newPages;
uint toRemoveBytes = toRemovePages * __pagesize;
DevCon.WriteLn( L"%-32s is being shrunk by %u pages.", Name.c_str(), toRemovePages);
HostSys::MmapResetPtr(GetPtrEnd(), toRemoveBytes);
DevCon.WriteLn( Color_Blue, L"%-32s @ 0x%08X -> 0x%08X [%umb]", Name.c_str(),
m_baseptr, (uptr)m_baseptr+toRemoveBytes, toRemoveBytes / _1mb);
}
return true;
}
// Sets the abbreviated name used by the profiler. Name should be under 10 characters long.
// After a name has been set, a profiler source will be automatically registered and cleared
// in accordance with changes in the reserve area.
RecompiledCodeReserve& RecompiledCodeReserve::SetProfilerName( const wxString& shortname )
{
m_profiler_name = shortname;
_registerProfiler();
return *this;
}
void RecompiledCodeReserve::OnCommittedBlock( void* block )
{
@ -57,7 +149,7 @@ void RecompiledCodeReserve::OnCommittedBlock( void* block )
void RecompiledCodeReserve::ResetProcessReserves() const
{
//Cpu->SetCacheReserve( (Cpu->GetCacheReserve() * 3) / 2 );
Cpu->SetCacheReserve( (Cpu->GetCacheReserve() * 3) / 2 );
Cpu->Reset();
CpuVU0->SetCacheReserve( (CpuVU0->GetCacheReserve() * 3) / 2 );
@ -66,7 +158,7 @@ void RecompiledCodeReserve::ResetProcessReserves() const
CpuVU1->SetCacheReserve( (CpuVU1->GetCacheReserve() * 3) / 2 );
CpuVU1->Reset();
//psxCpu->SetCacheReserve( (psxCpu->GetCacheReserve() * 3) / 2 );
psxCpu->SetCacheReserve( (psxCpu->GetCacheReserve() * 3) / 2 );
psxCpu->Reset();
}
@ -93,8 +185,7 @@ void RecompiledCodeReserve::OnOutOfMemory( const Exception::OutOfMemory& ex, voi
ResetProcessReserves();
uint cusion = std::min<uint>( m_block_size, 4 );
HostSys::MmapCommit((u8*)blockptr, cusion * __pagesize);
HostSys::MemProtect((u8*)blockptr, cusion * __pagesize, m_prot_mode);
HostSys::MmapCommitPtr((u8*)blockptr, cusion * __pagesize, m_prot_mode);
handled = true;
}

View File

@ -27,20 +27,37 @@
//
class RecompiledCodeReserve : public BaseVirtualMemoryReserve
{
typedef BaseVirtualMemoryReserve __parent;
protected:
wxString m_profiler_name;
bool m_profiler_registered;
public:
RecompiledCodeReserve( const wxString& name, uint defCommit = 0 );
virtual ~RecompiledCodeReserve() throw();
virtual void* Reserve( uint size, uptr base=0, uptr upper_bounds=0 );
virtual void OnCommittedBlock( void* block );
virtual void OnOutOfMemory( const Exception::OutOfMemory& ex, void* blockptr, bool& handled );
virtual RecompiledCodeReserve& SetProfilerName( const wxString& shortname );
virtual RecompiledCodeReserve& SetProfilerName( const char* shortname )
{
return SetProfilerName( fromUTF8(shortname) );
}
virtual bool TryResize( uint newsize );
operator void*() { return m_baseptr; }
operator const void*() const { return m_baseptr; }
operator u8*() { return (u8*)m_baseptr; }
operator const u8*() const { return (u8*)m_baseptr; }
protected:
void ResetProcessReserves() const;
void _registerProfiler();
void _termProfiler();
};

View File

@ -286,40 +286,40 @@ void Pcsx2App::AllocateCoreStuffs()
if( BaseException* ex = m_CpuProviders->GetException_EE() )
{
scrollableTextArea->AppendText( L"* R5900 (EE)\n\t" + ex->FormatDiagnosticMessage() + L"\n\n" );
scrollableTextArea->AppendText( L"* R5900 (EE)\n\t" + ex->FormatDisplayMessage() + L"\n\n" );
recOps.EnableEE = false;
}
if( BaseException* ex = m_CpuProviders->GetException_IOP() )
{
scrollableTextArea->AppendText( L"* R3000A (IOP)\n\t" + ex->FormatDiagnosticMessage() + L"\n\n" );
scrollableTextArea->AppendText( L"* R3000A (IOP)\n\t" + ex->FormatDisplayMessage() + L"\n\n" );
recOps.EnableIOP = false;
}
if( BaseException* ex = m_CpuProviders->GetException_MicroVU0() )
{
scrollableTextArea->AppendText( L"* microVU0\n\t" + ex->FormatDiagnosticMessage() + L"\n\n" );
scrollableTextArea->AppendText( L"* microVU0\n\t" + ex->FormatDisplayMessage() + L"\n\n" );
recOps.UseMicroVU0 = false;
recOps.EnableVU0 = recOps.EnableVU0 && m_CpuProviders->IsRecAvailable_SuperVU0();
}
if( BaseException* ex = m_CpuProviders->GetException_MicroVU1() )
{
scrollableTextArea->AppendText( L"* microVU1\n\t" + ex->FormatDiagnosticMessage() + L"\n\n" );
scrollableTextArea->AppendText( L"* microVU1\n\t" + ex->FormatDisplayMessage() + L"\n\n" );
recOps.UseMicroVU1 = false;
recOps.EnableVU1 = recOps.EnableVU1 && m_CpuProviders->IsRecAvailable_SuperVU1();
}
if( BaseException* ex = m_CpuProviders->GetException_SuperVU0() )
{
scrollableTextArea->AppendText( L"* SuperVU0\n\t" + ex->FormatDiagnosticMessage() + L"\n\n" );
scrollableTextArea->AppendText( L"* SuperVU0\n\t" + ex->FormatDisplayMessage() + L"\n\n" );
recOps.UseMicroVU0 = m_CpuProviders->IsRecAvailable_MicroVU0();
recOps.EnableVU0 = recOps.EnableVU0 && recOps.UseMicroVU0;
}
if( BaseException* ex = m_CpuProviders->GetException_SuperVU1() )
{
scrollableTextArea->AppendText( L"* SuperVU1\n\t" + ex->FormatDiagnosticMessage() + L"\n\n" );
scrollableTextArea->AppendText( L"* SuperVU1\n\t" + ex->FormatDisplayMessage() + L"\n\n" );
recOps.UseMicroVU1 = m_CpuProviders->IsRecAvailable_MicroVU1();
recOps.EnableVU1 = recOps.EnableVU1 && recOps.UseMicroVU1;
}

View File

@ -119,40 +119,47 @@ static bool _registeredName( const wxString& name )
return false;
}
void ProfilerRegisterSource(const char* Name, const void* buff, u32 sz)
void ProfilerRegisterSource(const wxString& Name, const void* buff, u32 sz)
{
if( ProfRunning )
EnterCriticalSection( &ProfModulesLock );
wxString strName( fromUTF8(Name) );
if( !_registeredName( strName ) )
ProfModules.push_back( Module( strName, buff, sz ) );
if( !_registeredName( Name ) )
ProfModules.push_back( Module( Name, buff, sz ) );
if( ProfRunning )
LeaveCriticalSection( &ProfModulesLock );
}
void ProfilerRegisterSource(const wxString& Name, const void* function)
{
if( ProfRunning )
EnterCriticalSection( &ProfModulesLock );
if( !_registeredName( Name ) )
ProfModules.push_back( Module(Name,function) );
if( ProfRunning )
LeaveCriticalSection( &ProfModulesLock );
}
void ProfilerRegisterSource(const char* Name, const void* buff, u32 sz)
{
ProfilerRegisterSource( fromUTF8(Name), buff, sz );
}
void ProfilerRegisterSource(const char* Name, const void* function)
{
if( ProfRunning )
EnterCriticalSection( &ProfModulesLock );
wxString strName( fromUTF8(Name) );
if( !_registeredName( strName ) )
ProfModules.push_back( Module(strName,function) );
if( ProfRunning )
LeaveCriticalSection( &ProfModulesLock );
ProfilerRegisterSource( fromUTF8(Name), function );
}
void ProfilerTerminateSource( const char* Name )
void ProfilerTerminateSource( const wxString& Name )
{
wxString strName( fromUTF8(Name) );
for( vector<Module>::const_iterator
iter = ProfModules.begin(),
end = ProfModules.end(); iter<end; ++iter )
{
if( iter->name.compare( strName ) == 0 )
if( iter->name.compare( Name ) == 0 )
{
ProfModules.erase( iter );
break;
@ -160,6 +167,11 @@ void ProfilerTerminateSource( const char* Name )
}
}
void ProfilerTerminateSource( const char* Name )
{
ProfilerTerminateSource( fromUTF8(Name) );
}
static bool DispatchKnownModules( uint Eip )
{
bool retval = false;

View File

@ -33,7 +33,6 @@
#include "IopCommon.h"
#include "iCore.h"
#include "SamplProf.h"
#include "NakedAsm.h"
#include "AppConfig.h"
@ -750,19 +749,41 @@ void psxRecompileCodeConst3(R3000AFNPTR constcode, R3000AFNPTR_INFO constscode,
noconstcode(0);
}
static uptr m_ConfiguredCacheReserve = 32;
static u8* m_recBlockAlloc = NULL;
static const uint m_recBlockAllocSize =
(((Ps2MemSize::IopRam + Ps2MemSize::Rom + Ps2MemSize::Rom1) / 4) * sizeof(BASEBLOCK));
static void recReserveCache()
{
extern wxString GetMsg_RecVmFailed();
if (!recMem) recMem = new RecompiledCodeReserve(L"R3000A Recompiler Cache", _1mb * 2);
recMem->SetProfilerName("IOPrec");
while (!recMem->IsOk())
{
if (recMem->Reserve( m_ConfiguredCacheReserve * _1mb, HostMemoryMap::IOPrec ) != NULL) break;
// If it failed, then try again (if possible):
if (m_ConfiguredCacheReserve < 4) break;
m_ConfiguredCacheReserve /= 2;
}
if (!recMem->IsOk())
{
throw Exception::VirtualMemoryMapConflict(recMem->GetName())
.SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
.SetUserMsg(GetMsg_RecVmFailed());
}
}
static void recReserve()
{
if (!recMem)
{
recMem = new RecompiledCodeReserve(L"R3000A Recompiler Cache", _1mb * 2);
recMem->Reserve( _16mb, HostMemoryMap::IOPrec );
ProfilerRegisterSource( "IOP Rec", *recMem, recMem->GetReserveSizeInBytes() );
}
// IOP has no hardware requirements!
recReserveCache();
}
static void recAlloc()
@ -846,7 +867,6 @@ void recResetIOP()
static void recShutdown()
{
ProfilerTerminateSource( "IOPRec" );
safe_delete( recMem );
safe_aligned_free( m_recBlockAlloc );
@ -1399,13 +1419,12 @@ StartRecomp:
static void recSetCacheReserve( uint reserveInMegs )
{
//m_ConfiguredCacheReserve = reserveInMegs * _1mb;
m_ConfiguredCacheReserve = reserveInMegs;
}
static uint recGetCacheReserve()
{
return 0;
//return m_ConfiguredCacheReserve / _1mb;
return m_ConfiguredCacheReserve;
}
R3000Acpu psxRec = {

View File

@ -25,7 +25,6 @@
#include "System/RecTypes.h"
#include "vtlb.h"
#include "SamplProf.h"
#include "Dump.h"
#include "System/SysThreads.h"
@ -64,7 +63,7 @@ bool g_cpuFlushedPC, g_cpuFlushedCode, g_recompilingDelaySlot, g_maySignalExcept
static const int RECCONSTBUF_SIZE = 16384 * 2; // 64 bit consts in 32 bit units
static RecompiledCodeReserve* recMem = NULL;
static uptr m_ConfiguredCacheReserve = _64mb;
static uptr m_ConfiguredCacheReserve = 64;
static u32* recConstBuf = NULL; // 64-bit pseudo-immediates
static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here
@ -551,38 +550,35 @@ static void recThrowHardwareDeficiency( const wxChar* extFail )
// This error message is shared by R5900, R3000, and microVU recompilers. It is not used by the
// SuperVU recompiler, since it has its own customized message.
wxString GetMsg_RecVmFailed( const char* recName )
wxString GetMsg_RecVmFailed()
{
return pxE( ".Error:Recompiler:VirtualMemoryAlloc",
pxsFmt(
"The %s recompiler was unable to reserve contiguous memory required "
"for internal caches. This problem may be fixable by reducing the default "
"cache sizes for all PCSX2 recompilers, found under Host Settings.",
recName
)
L"This recompiler was unable to reserve contiguous memory required "
L"for internal caches. This problem may be fixable by reducing the default "
L"cache sizes for all PCSX2 recompilers, found under Host Settings."
);
}
static void recReserveCache()
{
if (!recMem) recMem = new RecompiledCodeReserve(L"R5900-32 Recompiler Cache", _1mb * 4);
recMem->SetProfilerName("EErec");
recMem->Reserve( m_ConfiguredCacheReserve, HostMemoryMap::EErec );
while (!recMem->IsOk() && (m_ConfiguredCacheReserve >= 16))
while (!recMem->IsOk())
{
if (recMem->Reserve( m_ConfiguredCacheReserve * _1mb, HostMemoryMap::EErec ) != NULL) break;
// If it failed, then try again (if possible):
if (m_ConfiguredCacheReserve < 16) break;
m_ConfiguredCacheReserve /= 2;
recMem->Reserve( m_ConfiguredCacheReserve * _1mb, HostMemoryMap::EErec );
}
if (!recMem->IsOk())
{
throw Exception::VirtualMemoryMapConflict(recMem->GetName())
.SetDiagMsg(pxsFmt( L"R5900-32 recompiled code cache could not be mapped." ))
.SetUserMsg(GetMsg_RecVmFailed("R5900-32"));
.SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
.SetUserMsg(GetMsg_RecVmFailed());
}
ProfilerRegisterSource( "EE Rec", *recMem, recMem->GetReserveSizeInBytes() );
}
static void recReserve()
@ -721,7 +717,6 @@ static void recResetRaw()
static void recShutdown()
{
ProfilerTerminateSource( "EERec" );
safe_delete( recMem );
recBlocks.Reset();
@ -1922,12 +1917,12 @@ static void recThrowException( const BaseException& ex )
static void recSetCacheReserve( uint reserveInMegs )
{
m_ConfiguredCacheReserve = reserveInMegs * _1mb;
m_ConfiguredCacheReserve = reserveInMegs;
}
static uint recGetCacheReserve()
{
return m_ConfiguredCacheReserve / _1mb;
return m_ConfiguredCacheReserve;
}
R5900cpu recCpu =

View File

@ -85,6 +85,19 @@ static __fi void mVUthrowHardwareDeficiency(const wxChar* extFail, int vuIndex)
.SetUserMsg(wxsFormat(_("%s Extensions not found. microVU requires a host CPU with MMX, SSE, and SSE2 extensions."), extFail ));
}
void microVU::reserveCache()
{
cache_reserve = new RecompiledCodeReserve( pxsFmt("Micro VU%u Recompiler Cache", index) );
cache_reserve->SetProfilerName( pxsFmt("mVU%urec", index) );
cache = index ?
(u8*)cache_reserve->Reserve( cacheSize, HostMemoryMap::mVU1rec ) :
(u8*)cache_reserve->Reserve( cacheSize, HostMemoryMap::mVU0rec );
if(!cache_reserve->IsOk())
throw Exception::VirtualMemoryMapConflict().SetDiagMsg(pxsFmt( L"Micro VU%u Recompiler Cache", index ));
}
// Only run this once per VU! ;)
void microVU::init(uint vuIndex) {
@ -105,16 +118,6 @@ void microVU::init(uint vuIndex) {
if (!dispCache) throw Exception::OutOfMemory( index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" );
memset(dispCache, 0xcc, mVUdispCacheSize);
cache_reserve = new RecompiledCodeReserve( pxsFmt("Micro VU%u Recompiler Cache", index) );
cache = index ?
(u8*)cache_reserve->Reserve( cacheSize, HostMemoryMap::mVU1rec ) :
(u8*)cache_reserve->Reserve( cacheSize, HostMemoryMap::mVU0rec );
if(!cache_reserve->IsOk())
throw Exception::VirtualMemoryMapConflict().SetDiagMsg(pxsFmt( L"Micro VU%u Recompiler Cache", index ));
ProfilerRegisterSource (index ? "mVU1 Rec" : "mVU0 Rec", cache, cacheSize);
regAlloc = new microRegAlloc(index);
}
@ -130,10 +133,6 @@ void microVU::reset() {
//memset(&prog, 0, sizeof(prog));
memset(&prog.lpState, 0, sizeof(prog.lpState));
if (IsDevBuild) { // Release builds shouldn't need this
memset(cache, 0xcc, cacheSize);
}
// Program Variables
prog.cleared = 1;
prog.isSame = -1;
@ -145,7 +144,7 @@ void microVU::reset() {
u8* z = cache;
prog.x86start = z;
prog.x86ptr = z;
prog.x86end = z + (cacheSize - mVUcacheSafeZone);
prog.x86end = z + ((cacheSize - mVUcacheSafeZone) * _1mb);
for (u32 i = 0; i < (progSize / 2); i++) {
if (!prog.prog[i])
@ -168,11 +167,7 @@ void microVU::reset() {
// Free Allocated Resources
void microVU::close() {
if (cache_reserve && cache_reserve->IsOk())
{
ProfilerTerminateSource (index ? "mVU1 Rec" : "mVU0 Rec");
safe_delete(cache_reserve);
}
safe_delete(cache_reserve);
SafeSysMunmap(dispCache, mVUdispCacheSize);
@ -367,18 +362,18 @@ void recMicroVU1::Clear(u32 addr, u32 size) {
uint recMicroVU0::GetCacheReserve() const
{
return microVU0.cacheSize / _1mb;
return microVU0.cacheSize;
}
uint recMicroVU1::GetCacheReserve() const
{
return microVU1.cacheSize / _1mb;
return microVU1.cacheSize;
}
void recMicroVU0::SetCacheReserve( uint reserveInMegs ) const
{
microVU0.cacheSize = reserveInMegs * _1mb;
microVU0.cacheSize = reserveInMegs;
}
void recMicroVU1::SetCacheReserve( uint reserveInMegs ) const
{
microVU1.cacheSize = reserveInMegs * _1mb;
microVU1.cacheSize = reserveInMegs;
}

View File

@ -28,7 +28,6 @@ using namespace x86Emitter;
#include "iR5900.h"
#include "R5900OpcodeTables.h"
#include "x86emitter/x86emitter.h"
#include "SamplProf.h"
#include "microVU_Misc.h"
#include "microVU_IR.h"
@ -150,11 +149,8 @@ struct microProgManager {
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
};
#define mVUdispCacheSize (__pagesize) // Dispatcher Cache Size
#define mVUcacheSize ((index) ? (_1mb * 17) : (_1mb * 7)) // Initial Size (Excluding Safe-Zone)
#define mVUcacheMaxSize ((mVU->index) ? (_1mb * 100) : (_1mb * 50)) // Max Size allowed to grow to
#define mVUcacheGrowBy ((mVU->index) ? (_1mb * 15) : (_1mb * 10)) // Grows by this amount
#define mVUcacheSafeZone ((index) ? (_1mb * 3) : (_1mb * 3)) // Safe-Zone for last program
static const uint mVUdispCacheSize = __pagesize; // Dispatcher Cache Size (in bytes)
static const uint mVUcacheSafeZone = 3; // Safe-Zone for program recompilation (in megabytes)
struct microVU {
@ -229,13 +225,14 @@ struct microVU {
microVU()
{
cacheSize = _1mb * 64;
cacheSize = 64;
cache = NULL;
dispCache = NULL;
startFunct = NULL;
exitFunct = NULL;
}
void reserveCache();
void init(uint vuIndex);
void reset();
void close();

View File

@ -38,7 +38,6 @@
#include "System/RecTypes.h"
#include "sVU_zerorec.h"
#include "SamplProf.h"
#include "NakedAsm.h"
#include "AppConfig.h"
@ -350,9 +349,10 @@ static void SuperVUAlloc(int vuindex)
{
if (s_recVUMem[vuindex]) return;
s_recVUMem[vuindex] = new RecompiledCodeReserve( L"SuperVU Recompiler Cache", 0 );
s_recVUMem[vuindex] = new RecompiledCodeReserve( pxsFmt("SuperVU%u Recompiler Cache", vuindex), 0 );
s_recVUMem[vuindex]->Reserve( sVU_EXESIZE, vuindex ? HostMemoryMap::sVU1rec : HostMemoryMap::sVU0rec, _256mb );
s_recVUMem[vuindex]->SetProfilerName(pxsFmt("sVU%urec",vuindex));
// upper 4 bits must be zero!
if (!s_recVUMem[vuindex]->IsOk())
{
@ -364,8 +364,6 @@ static void SuperVUAlloc(int vuindex)
L"ranges required, and will not be available for use. This is not a critical error, since "
L"the sVU rec is obsolete, and you should use microVU instead anyway. :)"
));
ProfilerRegisterSource("sVU Rec", *s_recVUMem[vuindex], sVU_EXESIZE);
}
}
@ -413,8 +411,6 @@ void SuperVUDestroy(int vuindex)
}
DestroyVUHeaders(vuindex);
ProfilerTerminateSource(vuindex ? "sVU1Rec" : "sVU0Rec");
safe_delete(s_recVUMem[vuindex]);
safe_delete_array(recVUStack[vuindex]);
}