diff --git a/common/include/Utilities/PageFaultSource.h b/common/include/Utilities/PageFaultSource.h index 631e839a68..212d804462 100644 --- a/common/include/Utilities/PageFaultSource.h +++ b/common/include/Utilities/PageFaultSource.h @@ -215,63 +215,6 @@ protected: virtual void ReprotectCommittedBlocks(const PageProtectionMode &newmode); }; -// -------------------------------------------------------------------------------------- -// BaseVmReserveListener -// -------------------------------------------------------------------------------------- -class BaseVmReserveListener : public VirtualMemoryReserve -{ - DeclareNoncopyableObject(BaseVmReserveListener); - - typedef VirtualMemoryReserve _parent; - -protected: - EventListenerHelper_PageFault m_pagefault_listener; - - // Incremental size by which the buffer grows (in pages) - uptr m_blocksize; - -public: - BaseVmReserveListener(const wxString &name, size_t size = 0); - virtual ~BaseVmReserveListener() throw() {} - - 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; } - - using _parent::operator[]; - - void OnPageFaultEvent(const PageFaultInfo &info, bool &handled); - - virtual uptr SetBlockSize(uptr bytes) - { - m_blocksize = (bytes + __pagesize - 1) / __pagesize; - return m_blocksize * __pagesize; - } - - virtual void Reset() - { - _parent::Reset(); - } - -protected: - // This function is called from OnPageFaultEvent after the address has been translated - // and confirmed to apply to this reserved area in question. OnPageFaultEvent contains - // a try/catch exception handler, which ensures "reasonable" error response behavior if - // this function throws exceptions. - // - // Important: This method is called from the context of an exception/signal handler. On - // Windows this isn't a big deal (most operations are ok). On Linux, however, logging - // and other facilities are probably not a good idea. - virtual void DoCommitAndProtect(uptr offset) = 0; - - // This function is called for every committed block. - virtual void OnCommittedBlock(void *block) = 0; - - virtual void CommitBlocks(uptr page, uint blocks); -}; - #ifdef __POSIX__ #define PCSX2_PAGEFAULT_PROTECT diff --git a/common/src/Utilities/VirtualMemory.cpp b/common/src/Utilities/VirtualMemory.cpp index 44f47f2137..946ca6e9ca 100644 --- a/common/src/Utilities/VirtualMemory.cpp +++ b/common/src/Utilities/VirtualMemory.cpp @@ -257,80 +257,6 @@ bool VirtualMemoryReserve::TryResize(uint newsize) return true; } -// -------------------------------------------------------------------------------------- -// BaseVmReserveListener (implementations) -// -------------------------------------------------------------------------------------- - -BaseVmReserveListener::BaseVmReserveListener(const wxString &name, size_t size) - : VirtualMemoryReserve(name, size) - , m_pagefault_listener(this) -{ - m_blocksize = __pagesize; -} - -void BaseVmReserveListener::CommitBlocks(uptr page, uint blocks) -{ - const uptr blocksbytes = blocks * m_blocksize * __pagesize; - void *blockptr = (u8 *)m_baseptr + (page * __pagesize); - - // Depending on the operating system, this call could fail if the system is low on either - // physical ram or virtual memory. - if (!HostSys::MmapCommitPtr(blockptr, blocksbytes, m_prot_mode)) { - throw Exception::OutOfMemory(m_name) - .SetDiagMsg(pxsFmt("An additional %u blocks @ 0x%08x were requested, but could not be committed!", blocks, blockptr)); - } - - u8 *init = (u8 *)blockptr; - u8 *endpos = init + blocksbytes; - for (; init < endpos; init += m_blocksize * __pagesize) - OnCommittedBlock(init); - - m_pages_commited += m_blocksize * blocks; -} - -void BaseVmReserveListener::OnPageFaultEvent(const PageFaultInfo &info, bool &handled) -{ - sptr offset = (info.addr - (uptr)m_baseptr) / __pagesize; - if ((offset < 0) || ((uptr)offset >= m_pages_reserved)) - return; - - if (!m_allow_writes) { - pxFailRel(pxsFmt( - L"Memory Protection Fault @ %ls (%s)\n" - L"Modification of this reserve has been disabled (m_allow_writes == false).", - pxsPtr(info.addr), WX_STR(m_name))); - return; - } - -// Linux Note! the SIGNAL handler is very limited in what it can do, and not only can't -// we let the C++ exception try to unwind the stack, we may not be able to log it either. -// (but we might as well try -- kernel/posix rules says not to do it, but Linux kernel -// implementations seem to support it). -// Note also that logging the exception and/or issuing an assertion dialog are always -// possible if the thread handling the signal is not the main thread. - -// In windows we can let exceptions bubble out of the page fault handler. SEH will more -// or less handle them in a semi-expected way, and might even avoid a GPF long enough -// for the system to log the error or something. - -#ifndef __WXMSW__ - try { -#endif - DoCommitAndProtect(offset); - handled = true; - -#ifndef __WXMSW__ - } catch (Exception::BaseException &ex) { - handled = false; - if (!wxThread::IsMain()) { - pxFailRel(ex.FormatDiagnosticMessage()); - } else { - pxTrap(); - } - } -#endif -} - // -------------------------------------------------------------------------------------- // PageProtectionMode (implementations) // -------------------------------------------------------------------------------------- diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index a988f0a63f..7fdc857100 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -36,11 +36,9 @@ // Parameters: // name - a nice long name that accurately describes the contents of this reserve. RecompiledCodeReserve::RecompiledCodeReserve( const wxString& name, uint defCommit ) - : BaseVmReserveListener( name ) + : VirtualMemoryReserve( name, defCommit ) { - m_blocksize = (1024 * 128) / __pagesize; m_prot_mode = PageAccess_Any(); - m_def_commit = defCommit / __pagesize; } RecompiledCodeReserve::~RecompiledCodeReserve() throw() @@ -59,19 +57,13 @@ void RecompiledCodeReserve::_termProfiler() { } -uint RecompiledCodeReserve::_calcDefaultCommitInBlocks() const -{ - return (m_def_commit + m_blocksize - 1) / m_blocksize; -} - void* RecompiledCodeReserve::Reserve( size_t size, uptr base, uptr upper_bounds ) { if (!_parent::Reserve(size, base, upper_bounds)) return NULL; - _registerProfiler(); - // Pre-Allocate the first block (to reduce the number of segmentation fault - // in debugger) - DoCommitAndProtect(0); + Commit(); + + _registerProfiler(); return m_baseptr; } @@ -80,11 +72,24 @@ void RecompiledCodeReserve::Reset() { _parent::Reset(); - // Pre-Allocate the first block (to reduce the number of segmentation fault - // in debugger) - DoCommitAndProtect(0); + Commit(); } +bool RecompiledCodeReserve::Commit() +{ + bool status = _parent::Commit(); + + if (IsDevBuild && m_baseptr) + { + // Clear the recompiled code block to 0xcc (INT3) -- this helps disasm tools show + // the assembly dump more cleanly. We don't clear the block on Release builds since + // it can add a noticeable amount of overhead to large block recompilations. + + memset(m_baseptr, 0xCC, m_pages_commited * __pagesize); + } + + return status; +} // 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 @@ -96,23 +101,6 @@ RecompiledCodeReserve& RecompiledCodeReserve::SetProfilerName( const wxString& s return *this; } -void RecompiledCodeReserve::DoCommitAndProtect( uptr page ) -{ - CommitBlocks(page, (m_pages_commited || !m_def_commit) ? 1 : _calcDefaultCommitInBlocks() ); -} - -void RecompiledCodeReserve::OnCommittedBlock( void* block ) -{ - if (IsDevBuild) - { - // Clear the recompiled code block to 0xcc (INT3) -- this helps disasm tools show - // the assembly dump more cleanly. We don't clear the block on Release builds since - // it can add a noticeable amount of overhead to large block recompilations. - - memset(block, 0xCC, m_blocksize * __pagesize); - } -} - // 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. void RecompiledCodeReserve::ThrowIfNotOk() const diff --git a/pcsx2/System/RecTypes.h b/pcsx2/System/RecTypes.h index 91de2a6f73..906f282dc5 100644 --- a/pcsx2/System/RecTypes.h +++ b/pcsx2/System/RecTypes.h @@ -23,16 +23,11 @@ // A recompiled code reserve is a simple sequential-growth block of memory which is auto- // cleared to INT 3 (0xcc) as needed. // -class RecompiledCodeReserve : public BaseVmReserveListener +class RecompiledCodeReserve : public VirtualMemoryReserve { - typedef BaseVmReserveListener _parent; + typedef VirtualMemoryReserve _parent; protected: - // Specifies the number of blocks that should be committed automatically when the - // reserve is created. Typically this chunk is larger than the block size, and - // should be based on whatever typical overhead is needed for basic block use. - uint m_def_commit; - wxString m_profiler_name; public: @@ -40,15 +35,15 @@ public: virtual ~RecompiledCodeReserve() throw(); virtual void* Reserve( size_t size, uptr base=0, uptr upper_bounds=0 ); - virtual void OnCommittedBlock( void* block ); virtual void Reset(); + virtual bool Commit(); virtual RecompiledCodeReserve& SetProfilerName( const wxString& shortname ); virtual RecompiledCodeReserve& SetProfilerName( const char* shortname ) { return SetProfilerName( fromUTF8(shortname) ); } - + void ThrowIfNotOk() const; operator void*() { return m_baseptr; } @@ -59,10 +54,7 @@ public: protected: void ResetProcessReserves() const; - void DoCommitAndProtect( uptr page ); void _registerProfiler(); void _termProfiler(); - - uint _calcDefaultCommitInBlocks() const; }; diff --git a/pcsx2/x86/newVif_UnpackSSE.cpp b/pcsx2/x86/newVif_UnpackSSE.cpp index 179e87cc3a..e463443d0e 100644 --- a/pcsx2/x86/newVif_UnpackSSE.cpp +++ b/pcsx2/x86/newVif_UnpackSSE.cpp @@ -420,7 +420,6 @@ void VifUnpackSSE_Init() nVifUpkExec = new RecompiledCodeReserve(L"VIF SSE-optimized Unpacking Functions", _64kb); nVifUpkExec->SetProfilerName("iVIF-SSE"); - nVifUpkExec->SetBlockSize( 1 ); nVifUpkExec->Reserve( _64kb ); nVifUpkExec->ThrowIfNotOk();