/[pcsx2_0.9.7]/trunk/pcsx2/x86/sVU_zerorec.cpp
ViewVC logotype

Diff of /trunk/pcsx2/x86/sVU_zerorec.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/pcsx2/x86/sVU_zerorec.cpp	2010/12/23 11:48:33	279
+++ trunk/pcsx2/x86/sVU_zerorec.cpp	2010/12/23 12:02:12	280
@@ -35,9 +35,9 @@
 
 #include "R5900.h"
 #include "iR5900.h"
+#include "System/RecTypes.h"
 
 #include "sVU_zerorec.h"
-#include "SamplProf.h"
 #include "NakedAsm.h"
 #include "AppConfig.h"
 
@@ -72,7 +72,7 @@
 
 #define SUPERVU_CHECKCONDITION 0 // has to be 0!!
 
-#define VU_EXESIZE 0x00800000
+static const uint sVU_EXESIZE = _8mb;
 
 #define _Imm11_ 	(s32)( (vucode & 0x400) ? (0xfffffc00 | (vucode & 0x3ff)) : (vucode & 0x3ff) )
 #define _UImm11_	(s32)(vucode & 0x7ff)
@@ -90,7 +90,9 @@
 static u32 s_vuInfo; // info passed into rec insts
 
 static const u32 s_MemSize[2] = {VU0_MEMSIZE, VU1_MEMSIZE};
-static u8* s_recVUMem = NULL, *s_recVUPtr = NULL;
+//static u8* s_recVUMem = NULL, *s_recVUPtr = NULL;
+static RecompiledCodeReserve* s_recVUMem[2] = { NULL, NULL };
+static u8* s_recVUPtr[2] = { NULL, NULL };
 
 // tables which are defined at the bottom of this massive file.
 extern void (*recVU_UPPER_OPCODE[64])(VURegs* VU, s32 info);
@@ -315,9 +317,11 @@
 
 static list<VuFunctionHeader*> s_listVUHeaders[2];
 static list<VuFunctionHeader*>* s_plistCachedHeaders[2] = {NULL, NULL};
-static VuFunctionHeader** recVUHeaders[2] = {NULL, NULL};
-static VuBlockHeader* recVUBlocks[2] = {NULL, NULL};
-static u8* recVUStack = NULL, *recVUStackPtr = NULL;
+static VuFunctionHeader** recVUHeaders[2]	= { NULL, NULL };
+static VuBlockHeader* recVUBlocks[2]		= { NULL, NULL };
+static u8* recVUStack[2]					= { NULL, NULL };
+static u8* recVUStackPtr[2]					= { NULL, NULL };
+
 static vector<_x86regs> s_vecRegArray(128);
 
 static VURegs* VU = NULL;
@@ -343,47 +347,23 @@
 // allocate VU resources
 static void SuperVUAlloc(int vuindex)
 {
-	// The old -1 crap has been depreciated on this function.  Please
-	// specify either 0 or 1, thanks.
-	pxAssert(vuindex >= 0);
-
-	// upper 4 bits must be zero!
-	if (s_recVUMem == NULL)
-	{
-		// upper 4 bits must be zero!
-		// Changed "first try base" to 0xf1e0000, since 0x0c000000 liked to fail a lot. (cottonvibes)
-		s_recVUMem = SysMmapEx(0xf1e0000, VU_EXESIZE, 0x10000000, "SuperVUAlloc");
-
-		// Try again at some other random memory location... whatever. >_<
-		if( s_recVUMem == NULL )
-			s_recVUMem = SysMmapEx(0xc2b0000, VU_EXESIZE, 0x10000000, "SuperVUAlloc");
-
-		if (s_recVUMem == NULL)
-		{
-			throw Exception::VirtualMemoryMapConflict()
-				.SetDiagMsg(wxsFormat( L"SuperVU failed to allocate virtual memory below 256MB." ))
-				.SetUserMsg(pxE( ".Error:superVU:VirtualMemoryAlloc",
-					L"Out of Memory (sorta): The SuperVU recompiler was unable to reserve the specific memory "
-					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, VU_EXESIZE);
+	if (s_recVUMem[vuindex]) return;
 
-		if (recVUStack == NULL) recVUStack = new u8[SUPERVU_STACKSIZE * 4];
-	}
+	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));
 
-	if (vuindex >= 0)
+	// upper 4 bits must be zero!
+	if (!s_recVUMem[vuindex]->IsOk())
 	{
-		pxAssert(s_recVUMem != NULL);
-
-		if (recVUHeaders[vuindex] == NULL)
-			recVUHeaders[vuindex] = new VuFunctionHeader* [s_MemSize[vuindex] / 8];
-		if (recVUBlocks[vuindex] == NULL)
-			recVUBlocks[vuindex] = new VuBlockHeader[s_MemSize[vuindex] / 8];
-		if (s_plistCachedHeaders[vuindex] == NULL)
-			s_plistCachedHeaders[vuindex] = new list<VuFunctionHeader*>[s_MemSize[vuindex] / 8];
+		safe_delete(s_recVUMem[vuindex]);
+		throw Exception::VirtualMemoryMapConflict( s_recVUMem[vuindex]->GetName() )
+			.SetDiagMsg(pxsFmt( L"SuperVU failed to allocate virtual memory below 256MB." ))
+			.SetUserMsg(pxE( "!Notice:superVU:VirtualMemoryAlloc",
+				L"Out of Memory (sorta): The SuperVU recompiler was unable to reserve the specific memory "
+				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. :)"
+			));
 	}
 }
 
@@ -416,72 +396,64 @@
 // destroy VU resources
 void SuperVUDestroy(int vuindex)
 {
-	list<VuFunctionHeader*>::iterator it;
+	pxAssumeDev(vuindex >= 0 && vuindex <= 2, "Invalid VU index parameter!");
 
-	if (vuindex < 0)
-	{
-		SuperVUDestroy(0);
-		SuperVUDestroy(1);
-		ProfilerTerminateSource("VURec");
-		SafeSysMunmap(s_recVUMem, VU_EXESIZE);
-		safe_delete_array(recVUStack);
-	}
-	else
-	{
-		safe_delete_array(recVUHeaders[vuindex]);
-		safe_delete_array(recVUBlocks[vuindex]);
+	safe_delete_array(recVUHeaders[vuindex]);
+	safe_delete_array(recVUBlocks[vuindex]);
 
-		if (s_plistCachedHeaders[vuindex] != NULL)
+	if (s_plistCachedHeaders[vuindex] != NULL)
+	{
+		for (u32 j = 0; j < s_MemSize[vuindex] / 8; ++j)
 		{
-			for (u32 j = 0; j < s_MemSize[vuindex] / 8; ++j)
-			{
-				DestroyCachedHeaders(vuindex, j);
-			}
-			safe_delete_array(s_plistCachedHeaders[vuindex]);
+			DestroyCachedHeaders(vuindex, j);
 		}
-		DestroyVUHeaders(vuindex);
+		safe_delete_array(s_plistCachedHeaders[vuindex]);
 	}
+	DestroyVUHeaders(vuindex);
+
+	safe_delete(s_recVUMem[vuindex]);
+	safe_delete_array(recVUStack[vuindex]);
 }
 
 // reset VU
 void SuperVUReset(int vuindex)
 {
+	pxAssumeDev(vuindex >= 0 && vuindex <= 2, "Invalid VU index parameter!");
+
 #ifdef PCSX2_DEBUG
 	s_vucount = 0;
 #endif
 
-	if (s_recVUMem == NULL)
-		return;
+	DevCon.WriteLn("SuperVU%d: Resetting function and block lists.", vuindex);
 
-	//pxAssume( s_recVUMem != NULL );
+	if (recVUHeaders[vuindex] == NULL)
+		recVUHeaders[vuindex] = new VuFunctionHeader* [s_MemSize[vuindex] / 8];
+	if (recVUBlocks[vuindex] == NULL)
+		recVUBlocks[vuindex] = new VuBlockHeader[s_MemSize[vuindex] / 8];
+	if (s_plistCachedHeaders[vuindex] == NULL)
+		s_plistCachedHeaders[vuindex] = new std::list<VuFunctionHeader*>[s_MemSize[vuindex] / 8];
 
-	if (vuindex < 0)
-	{
-		DbgCon.WriteLn("SuperVU: Resetting recompiler memory and structures.");
+	if (recVUHeaders[vuindex]) memset(recVUHeaders[vuindex], 0, sizeof(VuFunctionHeader*) * (s_MemSize[vuindex] / 8));
+	if (recVUBlocks[vuindex]) memset(recVUBlocks[vuindex], 0, sizeof(VuBlockHeader) * (s_MemSize[vuindex] / 8));
 
-		// Does this cause problems on VU recompiler resets?  It could, if the VU works like
-		// the EE used to, and actually tries to re-enter the recBlock after issuing a clear. (air)
-
-		//memset_8<0xcd, VU_EXESIZE>(s_recVUMem);
-		memzero_ptr<SUPERVU_STACKSIZE>(recVUStack);
-
-		s_recVUPtr = s_recVUMem;
-	}
-	else
+	if (s_plistCachedHeaders[vuindex] != NULL)
 	{
-		DbgCon.WriteLn("SuperVU [VU%d]: Resetting the recs and junk", vuindex);
-		if (recVUHeaders[vuindex]) memset(recVUHeaders[vuindex], 0, sizeof(VuFunctionHeader*) * (s_MemSize[vuindex] / 8));
-		if (recVUBlocks[vuindex]) memset(recVUBlocks[vuindex], 0, sizeof(VuBlockHeader) * (s_MemSize[vuindex] / 8));
-
-		if (s_plistCachedHeaders[vuindex] != NULL)
+		for (u32 j = 0; j < s_MemSize[vuindex] / 8; ++j)
 		{
-			for (u32 j = 0; j < s_MemSize[vuindex] / 8; ++j)
-			{
-				DestroyCachedHeaders(vuindex, j);
-			}
+			DestroyCachedHeaders(vuindex, j);
 		}
-		DestroyVUHeaders(vuindex);
 	}
+	DestroyVUHeaders(vuindex);
+
+	if (!s_recVUMem[vuindex] || !s_recVUMem[vuindex]->IsOk()) return;
+
+	DevCon.WriteLn("SuperVU%u: Resetting recompiler cache.", vuindex);
+
+	if (!recVUStack[vuindex]) recVUStack[vuindex] = new u8[SUPERVU_STACKSIZE * 4];
+	memzero_ptr<SUPERVU_STACKSIZE>(recVUStack[vuindex]);
+
+	s_recVUMem[vuindex]->Reset();
+	s_recVUPtr[vuindex] = *s_recVUMem[vuindex];
 }
 
 // clear the block and any joining blocks
@@ -847,16 +819,15 @@
 static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex)
 {
 	pxAssert(vuindex < 2);
-	pxAssert(s_recVUPtr != NULL);
+	pxAssert(s_recVUPtr[vuindex] != NULL);
 	//Console.WriteLn("svu%c rec: %x", '0'+vuindex, startpc);
 
 	// if recPtr reached the mem limit reset whole mem
-	if (((uptr)s_recVUPtr - (uptr)s_recVUMem) >= VU_EXESIZE - 0x40000)
+	if ((s_recVUPtr[vuindex] < s_recVUMem[vuindex]->GetPtr()) || (s_recVUPtr[vuindex] >= s_recVUMem[vuindex]->GetPtrEnd() - _256kb))
 	{
-		//Console.WriteLn("SuperVU reset mem");
+		Console.WriteLn("SuperVU%u: Recompiler cache reset...", vuindex);
 		SuperVUReset(0);
 		SuperVUReset(1);
-		SuperVUReset(-1);
 		if (s_TotalVUCycles > 0)
 		{
 			// already executing, so return NULL
@@ -912,12 +883,12 @@
 #endif
 
 	// code generation
-	x86SetPtr(s_recVUPtr);
+	xSetPtr(s_recVUPtr[vuindex]);
 	branch = 0;
 
 	SuperVURecompile();
 
-	s_recVUPtr = x86Ptr;
+	s_recVUPtr[vuindex] = xGetPtr();
 
 	// set the function's range
 	VuFunctionHeader::RANGE r;
@@ -947,7 +918,7 @@
 	}
 	s_listBlocks.clear();
 
-	pxAssert(s_recVUPtr < s_recVUMem + VU_EXESIZE);
+	pxAssertDev(s_recVUPtr[vuindex] < s_recVUMem[vuindex]->GetPtrEnd(), "SuperVU recompiler cache exceeded! (possible memory corruption)");
 
 	return s_pFnHeader;
 }
@@ -2697,18 +2668,18 @@
 // executed only once per program
 static u32* SuperVUStaticAlloc(u32 size)
 {
-	pxAssert(recVUStackPtr + size <= recVUStack + SUPERVU_STACKSIZE);
+	pxAssert(recVUStackPtr[s_vu] + size <= recVUStack[s_vu] + SUPERVU_STACKSIZE);
 	// always zero
-	if (size == 4) *(u32*)recVUStackPtr = 0;
-	else memset(recVUStackPtr, 0, size);
-	recVUStackPtr += size;
-	return (u32*)(recVUStackPtr - size);
+	if (size == 4) *(u32*)recVUStackPtr[s_vu] = 0;
+	else memset(recVUStackPtr[s_vu], 0, size);
+	recVUStackPtr[s_vu] += size;
+	return (u32*)(recVUStackPtr[s_vu] - size);
 }
 
 static void SuperVURecompile()
 {
 	// save cpu state
-	recVUStackPtr = recVUStack;
+	recVUStackPtr[s_vu] = recVUStack[s_vu];
 
 	_initXMMregs();
 
@@ -4617,9 +4588,9 @@
 	IsInterpreter = false;
 }
 
-void recSuperVU0::Allocate()
+void recSuperVU0::Reserve()
 {
-	SuperVUAlloc( 0 );
+	SuperVUAlloc(0);
 }
 
 void recSuperVU0::Shutdown() throw()
@@ -4645,6 +4616,15 @@
 	SuperVUClear(Addr, Size, 0);
 }
 
+uint recSuperVU0::GetCacheReserve() const
+{
+	return sVU_EXESIZE / _1mb;
+}
+
+void recSuperVU0::SetCacheReserve( uint reserveInMegs ) const
+{
+	//microVU0.cacheSize = reserveInMegs * _1mb;
+}
 
 // --------------------------------------------------------------------------------------
 //  recSuperVU1 Interface
@@ -4655,9 +4635,9 @@
 	IsInterpreter = false;
 }
 
-void recSuperVU1::Allocate()
+void recSuperVU1::Reserve()
 {
-	SuperVUAlloc( 1 );
+	SuperVUAlloc(1);
 }
 
 void recSuperVU1::Shutdown() throw()
@@ -4670,6 +4650,16 @@
 	SuperVUReset( 1 );
 }
 
+uint recSuperVU1::GetCacheReserve() const
+{
+	return sVU_EXESIZE / _1mb;
+}
+
+void recSuperVU1::SetCacheReserve( uint reserveInMegs ) const
+{
+	//microVU0.cacheSize = reserveInMegs * _1mb;
+}
+
 #if 0
 	#include "sVU_Compare.h"
 #else

 

  ViewVC Help
Powered by ViewVC 1.1.22