diff --git a/common/include/Utilities/PageFaultSource.h b/common/include/Utilities/PageFaultSource.h
index 07ea665d06..41fd4c0924 100644
--- a/common/include/Utilities/PageFaultSource.h
+++ b/common/include/Utilities/PageFaultSource.h
@@ -127,10 +127,9 @@ class VirtualMemoryReserve
{
DeclareNoncopyableObject( VirtualMemoryReserve );
-public:
- wxString Name;
-
protected:
+ wxString m_name;
+
// Default size of the reserve, in bytes. Can be specified when the object is contructed.
// Is used as the reserve size when Reserve() is called, unless an override is specified
// in the Reserve parameters.
@@ -149,7 +148,7 @@ protected:
uptr m_pages_commited;
public:
- VirtualMemoryReserve( const wxString& name, size_t size = 0 );
+ VirtualMemoryReserve( const wxString& name=wxEmptyString, size_t size = 0 );
virtual ~VirtualMemoryReserve() throw()
{
Release();
@@ -167,7 +166,7 @@ public:
virtual bool Commit();
bool IsOk() const { return m_baseptr != NULL; }
- wxString GetName() const { return Name; }
+ wxString GetName() const { return m_name; }
uptr GetReserveSizeInBytes() const { return m_pages_reserved * __pagesize; }
uptr GetReserveSizeInPages() const { return m_pages_reserved; }
@@ -179,6 +178,7 @@ public:
u8* GetPtrEnd() { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); }
const u8* GetPtrEnd() const { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); }
+ VirtualMemoryReserve& SetName( const wxString& newname );
VirtualMemoryReserve& SetBaseAddr( uptr newaddr );
VirtualMemoryReserve& SetPageAccessOnCommit( const PageProtectionMode& mode );
diff --git a/common/src/Utilities/FastFormatString.cpp b/common/src/Utilities/FastFormatString.cpp
index 175a8ae27c..b08e14bdbd 100644
--- a/common/src/Utilities/FastFormatString.cpp
+++ b/common/src/Utilities/FastFormatString.cpp
@@ -174,7 +174,7 @@ static __ri void format_that_ascii_mess( CharBufferType& buffer, uint writepos,
len += writepos;
if (len < size) break;
- buffer.Alloc( len + 128 );
+ buffer.Resize( len + 128 );
};
// performing an assertion or log of a truncated string is unsafe, so let's not; even
@@ -205,7 +205,7 @@ static __ri uint format_that_unicode_mess( CharBufferType& buffer, uint writepos
len += writepos;
if (len < size) return len;
- buffer.Alloc( (len + 128) * sizeof(wxChar) );
+ buffer.Resize( (len + 128) * sizeof(wxChar) );
};
// performing an assertion or log of a truncated string is unsafe, so let's not; even
diff --git a/common/src/Utilities/VirtualMemory.cpp b/common/src/Utilities/VirtualMemory.cpp
index 1812ade3a7..69369ec3e9 100644
--- a/common/src/Utilities/VirtualMemory.cpp
+++ b/common/src/Utilities/VirtualMemory.cpp
@@ -71,7 +71,7 @@ void SrcType_PageFault::_DispatchRaw( ListenerIterator iter, const ListenerItera
// VirtualMemoryReserve (implementations)
// --------------------------------------------------------------------------------------
VirtualMemoryReserve::VirtualMemoryReserve( const wxString& name, size_t size )
- : Name( name )
+ : m_name( name )
{
m_defsize = size;
@@ -81,6 +81,12 @@ VirtualMemoryReserve::VirtualMemoryReserve( const wxString& name, size_t size )
m_prot_mode = PageAccess_None();
}
+VirtualMemoryReserve& VirtualMemoryReserve::SetName( const wxString& newname )
+{
+ m_name = newname;
+ return *this;
+}
+
VirtualMemoryReserve& VirtualMemoryReserve::SetBaseAddr( uptr newaddr )
{
if (!pxAssertDev(!m_pages_reserved, "Invalid object state: you must release the virtual memory reserve prior to changing its base address!")) return *this;
@@ -124,7 +130,7 @@ void* VirtualMemoryReserve::Reserve( size_t size, uptr base, uptr upper_bounds )
if (!m_baseptr || (upper_bounds != 0 && (((uptr)m_baseptr + reserved_bytes) > upper_bounds)))
{
DevCon.Warning( L"%s: host memory @ 0x%08x -> 0x%08x is unavailable; attempting to map elsewhere...",
- Name.c_str(), base, base + size );
+ m_name.c_str(), base, base + size );
SafeSysMunmap(m_baseptr, reserved_bytes);
@@ -143,9 +149,16 @@ void* VirtualMemoryReserve::Reserve( size_t size, uptr base, uptr upper_bounds )
}
if (!m_baseptr) return NULL;
-
- DevCon.WriteLn( Color_Blue, L"%-32s @ 0x%08X -> 0x%08X [%umb]", Name.c_str(),
- m_baseptr, (uptr)m_baseptr+reserved_bytes, reserved_bytes / _1mb);
+
+ FastFormatUnicode mbkb;
+ uint mbytes = reserved_bytes / _1mb;
+ if (mbytes)
+ mbkb.Write( "[%umb]", mbytes );
+ else
+ mbkb.Write( "[%ukb]", reserved_bytes / 1024 );
+
+ DevCon.WriteLn( Color_Gray, L"%-32s @ 0x%08p -> 0x%08p %s", m_name.c_str(),
+ m_baseptr, (uptr)m_baseptr+reserved_bytes, mbkb.c_str());
return m_baseptr;
}
@@ -193,17 +206,17 @@ bool VirtualMemoryReserve::TryResize( uint newsize )
uint toReservePages = newPages - m_pages_reserved;
uint toReserveBytes = toReservePages * __pagesize;
- DevCon.WriteLn( L"%-32s is being expanded by %u pages.", Name.c_str(), toReservePages);
+ DevCon.WriteLn( L"%-32s is being expanded by %u pages.", m_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);
+ Console.Indent().Warning("(attempted to map memory @ 0x%08p -> 0x%08p", m_baseptr, (uptr)m_baseptr+toReserveBytes);
}
- DevCon.WriteLn( Color_Blue, L"%-32s @ 0x%08X -> 0x%08X [%umb]", Name.c_str(),
+ DevCon.WriteLn( Color_Gray, L"%-32s @ 0x%08p -> 0x%08p [%umb]", m_name.c_str(),
m_baseptr, (uptr)m_baseptr+toReserveBytes, toReserveBytes / _1mb);
}
else if (newPages < m_pages_reserved)
@@ -213,11 +226,11 @@ bool VirtualMemoryReserve::TryResize( uint newsize )
uint toRemovePages = m_pages_reserved - newPages;
uint toRemoveBytes = toRemovePages * __pagesize;
- DevCon.WriteLn( L"%-32s is being shrunk by %u pages.", Name.c_str(), toRemovePages);
+ DevCon.WriteLn( L"%-32s is being shrunk by %u pages.", m_name.c_str(), toRemovePages);
HostSys::MmapResetPtr(GetPtrEnd(), toRemoveBytes);
- DevCon.WriteLn( Color_Blue, L"%-32s @ 0x%08X -> 0x%08X [%umb]", Name.c_str(),
+ DevCon.WriteLn( Color_Gray, L"%-32s @ 0x%08p -> 0x%08p [%umb]", m_name.c_str(),
m_baseptr, (uptr)m_baseptr+toRemoveBytes, toRemoveBytes / _1mb);
}
@@ -244,7 +257,7 @@ void BaseVmReserveListener::CommitBlocks( uptr page, uint blocks )
// physical ram or virtual memory.
if (!HostSys::MmapCommitPtr(blockptr, blocksbytes, m_prot_mode))
{
- throw Exception::OutOfMemory(Name)
+ throw Exception::OutOfMemory(m_name)
.SetDiagMsg(pxsFmt("An additional %u blocks @ 0x%08x were requested, but could not be committed!", blocks, blockptr));
}
diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt
index 82957bf97c..cdbbc3342a 100644
--- a/pcsx2/CMakeLists.txt
+++ b/pcsx2/CMakeLists.txt
@@ -541,7 +541,6 @@ set(pcsx2x86Headers
x86/microVU_Tables.inl
x86/microVU_Upper.inl
x86/newVif.h
- x86/newVif_BlockBuffer.h
x86/newVif_HashBucket.h
x86/newVif_UnpackSSE.h
x86/sVU_Compare.h
diff --git a/pcsx2/Linux/pcsx2.cbp b/pcsx2/Linux/pcsx2.cbp
index d3855a71c4..8722a0c032 100644
--- a/pcsx2/Linux/pcsx2.cbp
+++ b/pcsx2/Linux/pcsx2.cbp
@@ -646,7 +646,6 @@
-
diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp
index 400fb27738..eb3dd07a3a 100644
--- a/pcsx2/System.cpp
+++ b/pcsx2/System.cpp
@@ -17,6 +17,7 @@
#include "Common.h"
#include "IopCommon.h"
#include "VUmicro.h"
+#include "newVif.h"
#include "SamplProf.h"
@@ -30,9 +31,6 @@
#include "Utilities/MemsetFast.inl"
-extern void closeNewVif(int idx);
-extern void resetNewVif(int idx);
-
// --------------------------------------------------------------------------------------
// RecompiledCodeReserve (implementations)
// --------------------------------------------------------------------------------------
@@ -108,6 +106,23 @@ void RecompiledCodeReserve::OnCommittedBlock( void* block )
}
}
+// 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
+{
+ if (IsOk()) return;
+
+ throw Exception::OutOfMemory(m_name)
+ .SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
+ .SetUserMsg( pxE( ".Error:Recompiler:VirtualMemoryAlloc",
+ L"This recompiler was unable to reserve contiguous memory required for internal caches. "
+ L"This error can be caused by low virtual memory resources, such as a small or disabled swapfile, "
+ L"or by another program that is hogging a lot of memory. You can also try reducing the default "
+ L"cache sizes for all PCSX2 recompilers, found under Host Settings."
+ ));
+}
+
+
void SysOutOfMemory_EmergencyResponse(uptr blocksize)
{
// An out of memory error occurred. All we can try to do in response is reset the various
@@ -346,11 +361,15 @@ void SysMainMemory::ReserveAll()
{
pxInstallSignalHandler();
- DevCon.WriteLn( "PS2vm: Mapping host memory for all virtual systems..." );
+ DevCon.WriteLn( Color_StrongBlue, "Mapping host memory for virtual systems..." );
+ ConsoleIndentScope indent(1);
m_ee.Reserve();
m_iop.Reserve();
m_vu.Reserve();
+
+ reserveNewVif(0);
+ reserveNewVif(1);
}
void SysMainMemory::CommitAll()
@@ -358,7 +377,8 @@ void SysMainMemory::CommitAll()
vtlb_Core_Alloc();
if (m_ee.IsCommitted() && m_iop.IsCommitted() && m_vu.IsCommitted()) return;
- DevCon.WriteLn( "PS2vm: Allocating host memory for all virtual systems..." );
+ DevCon.WriteLn( Color_StrongBlue, "Allocating host memory for virtual systems..." );
+ ConsoleIndentScope indent(1);
m_ee.Commit();
m_iop.Commit();
@@ -370,23 +390,30 @@ void SysMainMemory::ResetAll()
{
CommitAll();
- DevCon.WriteLn( "PS2vm: Resetting host memory for all virtual systems..." );
+ DevCon.WriteLn( Color_StrongBlue, "Resetting host memory for virtual systems..." );
+ ConsoleIndentScope indent(1);
m_ee.Reset();
m_iop.Reset();
m_vu.Reset();
+
+ // Note: newVif is reset as part of other VIF structures.
}
void SysMainMemory::DecommitAll()
{
if (!m_ee.IsCommitted() && !m_iop.IsCommitted() && !m_vu.IsCommitted()) return;
- Console.WriteLn( "PS2vm: Decommitting host memory for all virtual systems..." );
+ Console.WriteLn( Color_Blue, "Decommitting host memory for virtual systems..." );
+ ConsoleIndentScope indent(1);
m_ee.Decommit();
m_iop.Decommit();
m_vu.Decommit();
+ closeNewVif(0);
+ closeNewVif(1);
+
vtlb_Core_Free();
}
@@ -394,10 +421,14 @@ void SysMainMemory::ReleaseAll()
{
DecommitAll();
- Console.WriteLn( "PS2vm: Releasing host memory maps for all virtual systems..." );
+ Console.WriteLn( Color_Blue, "Releasing host memory maps for virtual systems..." );
+ ConsoleIndentScope indent(1);
vtlb_Core_Free(); // Just to be sure... (calling order could result in it getting missed during Decommit).
+ releaseNewVif(0);
+ releaseNewVif(1);
+
m_ee.Decommit();
m_iop.Decommit();
m_vu.Decommit();
@@ -411,7 +442,8 @@ void SysMainMemory::ReleaseAll()
// --------------------------------------------------------------------------------------
SysCpuProviderPack::SysCpuProviderPack()
{
- Console.WriteLn( "Reserving memory for recompilers..." );
+ Console.WriteLn( Color_StrongBlue, "Reserving memory for recompilers..." );
+ ConsoleIndentScope indent(1);
CpuProviders = new CpuInitializerSet();
@@ -453,9 +485,6 @@ void SysCpuProviderPack::CleanupMess() throw()
{
try
{
- closeNewVif(0);
- closeNewVif(1);
-
psxRec.Shutdown();
recCpu.Shutdown();
}
@@ -574,5 +603,5 @@ wxString SysGetDiscID()
// region and revision).
}
- return wxsFormat( L"%8.8x", ElfCRC );
+ return pxsFmt( L"%08x", ElfCRC );
}
diff --git a/pcsx2/System.h b/pcsx2/System.h
index dd34f0f117..43159f08d3 100644
--- a/pcsx2/System.h
+++ b/pcsx2/System.h
@@ -61,11 +61,18 @@ namespace HostMemoryMap
// IOP recompiler code cache area (16 or 32mb)
static const uptr IOPrec = 0x34000000;
+ // newVif0 recompiler code cache area (16mb)
+ static const uptr VIF0rec = 0x36000000;
+
+ // newVif1 recompiler code cache area (32mb)
+ static const uptr VIF1rec = 0x38000000;
+
// microVU1 recompiler code cache area (32 or 64mb)
- static const uptr mVU0rec = 0x38000000;
+ static const uptr mVU0rec = 0x3C000000;
// microVU0 recompiler code cache area (64mb)
static const uptr mVU1rec = 0x40000000;
+
}
// --------------------------------------------------------------------------------------
diff --git a/pcsx2/System/RecTypes.h b/pcsx2/System/RecTypes.h
index 1fec845da1..2c26e3702c 100644
--- a/pcsx2/System/RecTypes.h
+++ b/pcsx2/System/RecTypes.h
@@ -37,7 +37,7 @@ protected:
bool m_profiler_registered;
public:
- RecompiledCodeReserve( const wxString& name, uint defCommit = 0 );
+ RecompiledCodeReserve( const wxString& name=wxEmptyString, uint defCommit = 0 );
virtual ~RecompiledCodeReserve() throw();
virtual void* Reserve( size_t size, uptr base=0, uptr upper_bounds=0 );
@@ -48,6 +48,8 @@ public:
{
return SetProfilerName( fromUTF8(shortname) );
}
+
+ void ThrowIfNotOk() const;
operator void*() { return m_baseptr; }
operator const void*() const { return m_baseptr; }
diff --git a/pcsx2/gui/AppAssert.cpp b/pcsx2/gui/AppAssert.cpp
index c6b754b92e..d729c1a5b0 100644
--- a/pcsx2/gui/AppAssert.cpp
+++ b/pcsx2/gui/AppAssert.cpp
@@ -22,10 +22,10 @@
class StackDump : public wxStackWalker
{
protected:
- wxString m_stackTrace;
- wxString m_srcFuncName;
- bool m_ignoreDone;
- int m_skipped;
+ FastFormatUnicode m_stackTrace;
+ wxString m_srcFuncName;
+ bool m_ignoreDone;
+ int m_skipped;
public:
StackDump( const FnChar_t* src_function_name )
@@ -37,17 +37,12 @@ public:
m_skipped = 0;
}
- const wxString& GetStackTrace() const { return m_stackTrace; }
+ const wxChar* GetStackTrace() const { return m_stackTrace.c_str(); }
protected:
virtual void OnStackFrame(const wxStackFrame& frame)
{
- wxString name( frame.GetName() );
- if( name.IsEmpty() )
- {
- name = wxsFormat( L"%p ", frame.GetAddress() );
- }
- /*else if( m_srcFuncName.IsEmpty() || m_srcFuncName == name )
+ /*if( m_srcFuncName.IsEmpty() || m_srcFuncName == name )
{
// FIXME: This logic isn't reliable yet.
// It's possible for our debug information to not match the function names returned by
@@ -71,27 +66,25 @@ protected:
return;
}*/
- //wxString briefName;
- wxString essenName;
+ m_stackTrace.Write(pxsFmt( L"[%02d]", frame.GetLevel()-m_skipped));
+
+ if (!frame.GetName().IsEmpty())
+ m_stackTrace.Write(pxsFmt( L" %-44s", frame.GetName().c_str() ));
+ else
+ m_stackTrace.Write(pxsFmt( L" 0x%-42p", frame.GetAddress() ));
if( frame.HasSourceLocation() )
{
wxFileName wxfn(frame.GetFileName());
- //briefName.Printf( L"(%s:%d)", wxfn.GetFullName().c_str(), frame.GetLine() );
wxfn.SetVolume( wxEmptyString );
- //int count = wxfn.GetDirCount();
for( int i=0; i<2; ++i )
wxfn.RemoveDir(0);
- essenName.Printf( L"%s:%d", wxfn.GetFullPath().c_str(), frame.GetLine() );
+ m_stackTrace.Write( L" %s:%d", wxfn.GetFullPath().c_str(), frame.GetLine() );
}
-
- m_stackTrace += pxsFmt( L"[%02d] %-44s %s\n",
- frame.GetLevel()-m_skipped,
- name.c_str(),
- essenName.c_str()
- );
+
+ m_stackTrace.Write(L"\n");
}
};
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index f648745cb0..129822dfc8 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -839,10 +839,6 @@
RelativePath="..\..\x86\newVif.h"
>
-
-
diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp
index 795f671f28..941125e3d8 100644
--- a/pcsx2/x86/iR3000A.cpp
+++ b/pcsx2/x86/iR3000A.cpp
@@ -757,8 +757,6 @@ static const uint m_recBlockAllocSize =
static void recReserveCache()
{
- extern wxString GetMsg_RecVmFailed();
-
if (!recMem) recMem = new RecompiledCodeReserve(L"R3000A Recompiler Cache", _1mb * 2);
recMem->SetProfilerName("IOPrec");
@@ -771,12 +769,7 @@ static void recReserveCache()
m_ConfiguredCacheReserve /= 2;
}
- if (!recMem->IsOk())
- {
- throw Exception::VirtualMemoryMapConflict(recMem->GetName())
- .SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
- .SetUserMsg(GetMsg_RecVmFailed());
- }
+ recMem->ThrowIfNotOk();
}
static void recReserve()
diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp
index 874b452765..2be0fafd9c 100644
--- a/pcsx2/x86/ix86-32/iR5900-32.cpp
+++ b/pcsx2/x86/ix86-32/iR5900-32.cpp
@@ -578,18 +578,6 @@ static void recThrowHardwareDeficiency( const wxChar* extFail )
.SetUserMsg(pxsFmt(_("%s Extensions not found. The R5900-32 recompiler requires a host CPU with MMX, SSE, and SSE2 extensions."), 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()
-{
- return pxE( ".Error:Recompiler:VirtualMemoryAlloc",
- L"This recompiler was unable to reserve contiguous memory required for internal caches. "
- L"This error can be caused by low virtual memory resources, such as a small or disabled swapfile, "
- L"or by another program that is hogging a lot of memory. You can also try 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);
@@ -604,12 +592,7 @@ static void recReserveCache()
m_ConfiguredCacheReserve /= 2;
}
- if (!recMem->IsOk())
- {
- throw Exception::VirtualMemoryMapConflict(recMem->GetName())
- .SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
- .SetUserMsg(GetMsg_RecVmFailed());
- }
+ recMem->ThrowIfNotOk();
}
static void recReserve()
diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp
index b01d1cb904..a1bbaf3872 100644
--- a/pcsx2/x86/microVU.cpp
+++ b/pcsx2/x86/microVU.cpp
@@ -94,8 +94,7 @@ void microVU::reserveCache()
(u8*)cache_reserve->Reserve( cacheSize * _1mb, HostMemoryMap::mVU1rec ) :
(u8*)cache_reserve->Reserve( cacheSize * _1mb, HostMemoryMap::mVU0rec );
- if(!cache_reserve->IsOk())
- throw Exception::VirtualMemoryMapConflict().SetDiagMsg(pxsFmt( L"Micro VU%u Recompiler Cache", index ));
+ cache_reserve->ThrowIfNotOk();
}
// Only run this once per VU! ;)
diff --git a/pcsx2/x86/newVif.h b/pcsx2/x86/newVif.h
index 7f63bb6b91..d61456b395 100644
--- a/pcsx2/x86/newVif.h
+++ b/pcsx2/x86/newVif.h
@@ -19,6 +19,8 @@
#include "VU.h"
#include "x86emitter/x86emitter.h"
+#include "RecTypes.h"
+
using namespace x86Emitter;
#define aMax(x, y) std::max(x,y)
@@ -28,13 +30,14 @@ using namespace x86Emitter;
typedef u32 (__fastcall *nVifCall)(void*, const void*);
typedef void (__fastcall *nVifrecCall)(uptr dest, uptr src);
-#include "newVif_BlockBuffer.h"
#include "newVif_HashBucket.h"
extern void mVUmergeRegs(const xRegisterSSE& dest, const xRegisterSSE& src, int xyzw, bool modXYZW = 0);
extern void _nVifUnpack (int idx, const u8* data, uint mode, bool isFill);
+extern void dVifReserve (int idx);
extern void dVifReset (int idx);
extern void dVifClose (int idx);
+extern void dVifRelease (int idx);
extern void VifUnpackSSE_Init();
_vifT extern void dVifUnpack (const u8* data, bool isFill);
@@ -76,23 +79,25 @@ struct nVifStruct {
u32 bSize; // Size of 'buffer'
u32 bPtr;
- u32 idx; // VIF0 or VIF1
- u8* recPtr; // Cur Pos to recompile to
- u8* recEnd; // 'Safe' End of Rec Cache
- BlockBuffer* vifCache; // Block Buffer
+ uint recReserveSizeMB; // reserve size, in megabytes.
+ RecompiledCodeReserve* recReserve;
+ u8* recWritePtr; // current write pos into the reserve
+
HashBucket<_tParams>* vifBlocks; // Vif Blocks
int numBlocks; // # of Blocks Recompiled
-
- nVifStruct()
- {
- vifCache = NULL;
- vifBlocks = NULL;
- numBlocks = 0;
- recPtr = NULL;
- recEnd = NULL;
- }
+
+ // VIF0 or VIF1 - provided for debugging helpfulness only, and is generally unused.
+ // (templates are used for most or all VIF indexing)
+ u32 idx;
+
+ nVifStruct();
};
+extern void reserveNewVif(int idx);
+extern void closeNewVif(int idx);
+extern void resetNewVif(int idx);
+extern void releaseNewVif(int idx);
+
extern __aligned16 nVifStruct nVif[2];
extern __aligned16 nVifCall nVifUpk[(2*2*16)*4]; // ([USN][Masking][Unpack Type]) [curCycle]
extern __aligned16 u32 nVifMask[3][4][4]; // [MaskNumber][CycleNumber][Vector]
diff --git a/pcsx2/x86/newVif_BlockBuffer.h b/pcsx2/x86/newVif_BlockBuffer.h
deleted file mode 100644
index 532c613819..0000000000
--- a/pcsx2/x86/newVif_BlockBuffer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#pragma once
-
-// Allocates a Chunk of memory using SysMmapEx...
-// This memory can be used to write recompiled code to.
-// Its got basic resizing/growing ability too, but probably
-// won't be too useful since growing the block buffer will
-// invalidate any pointers pointing to the old block buffer.
-// (so remember to invalidate those block pointers :D)
-// It also deallocates itself on 'delete', so you can
-// just use 'new' and 'delete' for initialization and
-// deletion/cleanup respectfully...
-class BlockBuffer {
-protected:
- u32 mSize; // Cur Size (in bytes)
- u32 mSizeT; // Total Size (in bytes)
- u32 mGrowBy; // amount to grow by when buffer fills (in bytes)
- u8* mData; // Data Ptr (allocated via SysMmap)
-
- void alloc(int size) {
- mData = SysMmapEx(0, size, 0, "nVif_BlockBuffer");
- if (!mData) throw Exception::OutOfMemory(L"nVif recompiled code buffer (nVif_BlockBuffer)");
- clear();
- }
- void dealloc(u8* &dPtr, int size) {
- SafeSysMunmap( dPtr, size );
- }
-
-public:
- virtual ~BlockBuffer() throw() {
- dealloc(mData, mSizeT);
- }
-
- BlockBuffer(u32 tSize, u32 growby=_1mb*2) {
- mSizeT = tSize;
- mGrowBy = growby;
- mSize = 0;
- alloc(mSizeT);
- }
-
- void append(void *addr, u32 size) {
- if ((mSize + size) > mSizeT) grow(mSizeT + mGrowBy);
- memcpy_fast(&mData[mSize], addr, size);
- mSize += size;
- }
-
- // Increases the allocation size. Warning: Unlike 'realloc' this function will
- // CLEAR all contents of the buffer. This is because copying contents of recompiled
- // caches is mostly useless since it invalidates any pointers into the block.
- // (code relocation techniques are possible, but are difficult, potentially slow,
- // and easily bug prone. Not recommended at this time). --air
- void grow(u32 newSize) {
- pxAssume( newSize > mSizeT );
- u8* temp = mData;
- alloc(newSize);
- dealloc(temp, mSizeT);
- clear();
- mSizeT = newSize;
- }
-
- // clears the entire buffer to recompiler fill (0xcc), and sets mSize to 0.
- // (indicating none of the buffer is allocated).
- void clear() {
- if( mSize == 0 ) return; // no clears needed if nothing's been written/modified
- mSize = 0;
- memset(mData, 0xcc, mSizeT);
- }
-
- u32 getCurSize() { return mSize; }
- u32 getAllocSize() { return mSizeT; }
- u8* getBlock() { return mData; }
-};
diff --git a/pcsx2/x86/newVif_Dynarec.cpp b/pcsx2/x86/newVif_Dynarec.cpp
index 8325341da5..d5656b2292 100644
--- a/pcsx2/x86/newVif_Dynarec.cpp
+++ b/pcsx2/x86/newVif_Dynarec.cpp
@@ -22,34 +22,37 @@
static __aligned16 nVifBlock _vBlock = {0};
-void dVifReset(int idx) {
- // If the VIF cache is greater than 12mb, then it's due for a complete reset back
- // down to a reasonable starting point of 4mb.
- if( nVif[idx].vifCache && (nVif[idx].vifCache->getAllocSize() > _1mb*12) )
- safe_delete(nVif[idx].vifCache);
+void dVifReserve(int idx)
+{
+ if (!nVif[idx].recReserve)
+ nVif[idx].recReserve = new RecompiledCodeReserve(pxsFmt(L"VIF%u Unpack Recompiler Cache", idx));
- if( !nVif[idx].vifCache )
- nVif[idx].vifCache = new BlockBuffer(_1mb*4);
- else
- nVif[idx].vifCache->clear();
+ nVif[idx].recReserve->Reserve( nVif[idx].recReserveSizeMB * _1mb, idx ? HostMemoryMap::VIF1rec : HostMemoryMap::VIF0rec );
+}
+
+void dVifReset(int idx) {
if( !nVif[idx].vifBlocks )
nVif[idx].vifBlocks = new HashBucket<_tParams>();
else
nVif[idx].vifBlocks->clear();
- nVif[idx].numBlocks = 0;
-
- nVif[idx].recPtr = nVif[idx].vifCache->getBlock();
- nVif[idx].recEnd = &nVif[idx].recPtr[nVif[idx].vifCache->getAllocSize()-(_1mb/4)]; // .25mb Safe Zone
+ nVif[idx].recReserve->Reset();
+ nVif[idx].numBlocks = 0;
+ nVif[idx].recWritePtr = nVif[idx].recReserve->GetPtr();
}
void dVifClose(int idx) {
nVif[idx].numBlocks = 0;
- safe_delete(nVif[idx].vifCache);
+ nVif[idx].recReserve->Reset();
+
safe_delete(nVif[idx].vifBlocks);
}
+void dVifRelease(int idx) {
+ safe_delete(nVif[idx].recReserve);
+}
+
VifUnpackSSE_Dynarec::VifUnpackSSE_Dynarec(const nVifStruct& vif_, const nVifBlock& vifBlock_)
: v(vif_)
, vB(vifBlock_)
@@ -223,11 +226,10 @@ _vifT static __fi u8* dVifsetVUptr(uint cl, uint wl, bool isFill) {
// [TODO] : Finish implementing support for VIF's growable recBlocks buffer. Currently
// it clears the buffer only.
static __fi void dVifRecLimit(int idx) {
- if (nVif[idx].recPtr > nVif[idx].recEnd) {
- DevCon.WriteLn("nVif Rec - Out of Rec Cache! [%x > %x]", nVif[idx].recPtr, nVif[idx].recEnd);
- nVif[idx].vifBlocks->clear();
- nVif[idx].recPtr = nVif[idx].vifCache->getBlock();
- nVif[idx].recEnd = &nVif[idx].recPtr[nVif[idx].vifCache->getAllocSize()-(_1mb/4)]; // .25mb Safe Zone
+ if (nVif[idx].recWritePtr > (nVif[idx].recReserve->GetPtrEnd() - _256kb)) {
+ DevCon.WriteLn("nVif Recompiler Cache Reset! [0x%08x > 0x%08x]", nVif[idx].recWritePtr, nVif[idx].recReserve->GetPtrEnd());
+ nVif[idx].recReserve->Reset();
+ nVif[idx].recWritePtr = nVif[idx].recReserve->GetPtr();
}
}
@@ -277,11 +279,11 @@ _vifT __fi void dVifUnpack(const u8* data, bool isFill) {
if (dVifExecuteUnpack(data, isFill)) return;
- xSetPtr(v.recPtr);
+ xSetPtr(v.recWritePtr);
_vBlock.startPtr = (uptr)xGetAlignedCallTarget();
v.vifBlocks->add(_vBlock);
VifUnpackSSE_Dynarec( v, _vBlock ).CompileRoutine();
- nVif[idx].recPtr = xGetPtr();
+ nVif[idx].recWritePtr = xGetPtr();
// [TODO] : Ideally we should test recompile buffer limits prior to each instruction,
// which would be safer and more memory efficient than using an 0.25 meg recEnd marker.
diff --git a/pcsx2/x86/newVif_Unpack.cpp b/pcsx2/x86/newVif_Unpack.cpp
index 0c692292c9..02808d152f 100644
--- a/pcsx2/x86/newVif_Unpack.cpp
+++ b/pcsx2/x86/newVif_Unpack.cpp
@@ -70,6 +70,19 @@ static const __aligned16 Fnptr_VifUnpackLoop UnpackLoopTable[2][2][2] = {
};
// ----------------------------------------------------------------------------
+nVifStruct::nVifStruct()
+{
+ vifBlocks = NULL;
+ numBlocks = 0;
+
+ recReserveSizeMB = 8;
+}
+
+void reserveNewVif(int idx)
+{
+ if (newVifDynaRec) dVifReserve(idx);
+}
+
void resetNewVif(int idx)
{
// Safety Reset : Reassign all VIF structure info, just in case the VU1 pointers have
@@ -86,6 +99,10 @@ void closeNewVif(int idx) {
if (newVifDynaRec) dVifClose(idx);
}
+void releaseNewVif(int idx) {
+ if (newVifDynaRec) dVifRelease(idx);
+}
+
static __fi u8* getVUptr(uint idx, int offset) {
return (u8*)(vuRegs[idx].Mem + ( offset & (idx ? 0x3ff0 : 0xff0) ));
}