Page 1 of 2

A big Problem with VirtualAlloc and PocketPC 2003!

PostPosted: Aug 6, 2003 @ 9:06am
by schtruck
I'm curently Fighting With PocketPC 2003 and VirtualAlloc/protect.
I use them within the Dynamic Recompiler for FpseCE (upcomming Playstation Emulator).
First i Allocate a 2MB Buffer. This buffer is use to Store Recompiled Block.
I Declare this buffer with VirtualAlloc, then when i need to write a new block, i unprotect it with VirtualProtect, and at the end of this writing block i protect it.
On PocketPC 2002 that work very well, on PocketPC 2003, to make it working i need to add the NOCACHE flag when i protect it :( a Big slowdown is resulting....
Here are my routine:

UINT8 *win_code_alloc(int size)
{
LPCVOID lpAddress=VirtualAlloc(NULL,size,MEM_RESERVE,PAGE_EXECUTE_READWRITE);
return (UINT8 *)VirtualAlloc(lpAddress,size,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
}

void win_code_free(UINT8 *buf)
{
VirtualFree(buf,0,MEM_RELEASE);
}

void win_code_protect(UINT8 * lpPage,int dwSize){

DWORD dwOldProtect;

VirtualProtect (lpPage,dwSize,PAGE_EXECUTE_READ,&dwOldProtect);
}

void win_code_unprotect(UINT8 * lpPage,int dwSize){

DWORD dwOldProtect;

VirtualProtect (lpPage,dwSize,PAGE_EXECUTE_READWRITE,&dwOldProtect);
}


For now with my News PocketPC (ASUS A620 PPC2003), i can only use the Dynamic Interpreter , it's extremely Fast!! all game are already very playable, Ridge Racer run at 30 fps, Quake2 17-20 fps, Wipeout 30fps, Destruction Derby 30-40 fps etc.... I can't Imagine when my recompiler will run on PPC2003!! that will let me the possibility to add sound :) :) :)

thanks your any help!!

schtruck.

PostPosted: Aug 6, 2003 @ 12:22pm
by refractor

PostPosted: Aug 6, 2003 @ 1:38pm
by schtruck

PostPosted: Aug 6, 2003 @ 6:19pm
by rcp
i don't understand why you need to protect your re-compiled code. Are you trying to catch self-modifying code?

Cheers,

rcp

PostPosted: Aug 7, 2003 @ 6:52am
by Guest

PostPosted: Aug 7, 2003 @ 8:00am
by rcp

PostPosted: Aug 7, 2003 @ 12:02pm
by Sergey Chaban
In fact VirtualProtect is not even necessary, I've implemented 3 different JIT compilers for ARM (Small, Mophun, and ARM backend for Mono) and in all cases code buffer is allocated with a simple malloc/VirtualProtect pattern without any problems, but memory returned by malloc is already executable and VirtualProtect is only needed to play safe (malloced codebuffer works fine under CE 3.0 and 4.x).
Also, RR at 30 FPS and Q2 faster than native port sounds too good to be true 8)

PostPosted: Aug 7, 2003 @ 8:37pm
by schtruck

PostPosted: Aug 8, 2003 @ 3:48am
by Dan East

PostPosted: Aug 8, 2003 @ 9:01am
by refractor
Flushing caches...

On an ARM system, look to the "coprocessor" (MCR) commands.

On the StrongARM, you want coprocessor 7 for the cache control stuff (no idea about the XScale - should be the same but knowing Intel..).

mcr 15, 0, r0, c7, c5, 0 ; // flush the I cache
mcr 15, 0, r0, c7, c10, 4; // flush the write buffer

ISTR the data flush being horribly slow, so to flush the data just read a (contiguous in virtual) cache-sized block of data from RAM. Something like:

;r0 = address of your buffer
;r1 = number of 32-byte lines to flush

.flush
ldr r2,[r0],#32 // 32 is a cache line size
subs r1,r1,#1
bne flush

You can also flush single entries - it's all in the StrongARM developer manual at page 59.

Oh, and Microsoft ported the Q2 engine to their CLR:
http://msdn.microsoft.com/visualc/quake/default.aspx

PostPosted: Aug 8, 2003 @ 1:39pm
by Sergey Chaban

PostPosted: Aug 8, 2003 @ 3:02pm
by refractor

PostPosted: Aug 8, 2003 @ 3:49pm
by Kzinti

PostPosted: Aug 8, 2003 @ 9:45pm
by schtruck

PostPosted: Aug 8, 2003 @ 10:27pm
by refractor
How about putting the "reg structure" in a protected page, and picking up the exceptions when it's written to? That way at least you can find what's trashing it.