[uae] Direct or indirect - that is the question (was Re: MacOSX Intel supports JIT?)

  • From: Richard Drummond <evilrich@xxxxxxxxxxxxxx>
  • To: uae@xxxxxxxxxxxxx
  • Date: Thu, 22 Mar 2007 23:54:47 -0400

Hi Andrew

On Thursday 22 March 2007 09:54, Andrew 'Truck' Holland wrote:
> Try twiddling the various JIT items - indirect, direct, before picasso -
> I've found that on different hardware these perform differently.  In my
> case, I turn all 3 to 'before picasso' on both a macbook and a macbook pro,
> and the crash goes away.

You really want to set these to '1' or 'indirect'. Setting them to '2' or, if 
you are emulating a P96 gfx card, '3' may work also, but you are running the 
risk that a misbehaving 68k program will cause E-UAE simply to die and you to 
lose data.

Here's the story....

In the interpretive emulator, 68k memory is always accessed indirectly. When a 
68k opcode makes a memory access, the interpreter has a table which it looks 
up to find out what bank of memory is at that address, and so what routine to 
call to handle that access. Easy, safe, but slow.

The JIT can do similarly. This is what happens when all these 'comp_trust*=' 
options are set to '1' or 'indirect'.

However, the JIT can also do some tricks. When 'comp_trust*=' is set to '0' 
or 'direct', then for certain types of memory access that the JIT knows is 
real memory - not memory-mapped I/O space, for instance - it tries to by-pass 
the normal indirect memory access method. In the best case - in Linux/x86 
and, incidentally, in WinUAE - it knows that all 68k memory is mapped into 
host memory with a fixed offset of its 68k address. E.g., on Linux chip 
memory is at 0x50000000 + 0 = 0x50000000, slow memory is at 0x50000000 + 
0xC00000 = 0x50C00000, etc., etc. Thus accessing 68k memory using the 68k 
address merely requires the offset to be subtracted (in the Linux case, you 
guessed it, 0x50000000). Even when memory isn't mapped at a fixed offset, 
there are some tricks which let the JIT do a similar type of thing. As you 
can probably guess, this 'direct' scheme of memory access is much, much 
faster.

It does, however, have a problem. What happens when the 68k code accesses an 
address for which E-UAE has no memory mapped to? This type of thing may 
happen when a 68k program has bugs, but it also happens during boot-up when 
Kickstart and then P96 try and figure out what memory is available to them. 
They write to memory to try and find out if memory is there, and so determine 
how much memory is available. This is bad news for the 'direct' memory scheme 
of things.

This is why the 'comp_trust*=' options can be set to '2', meaning 'indirect 
for Kickstart', or '3', meaning 'direct after Picasso'. The former means that 
accesses done by Kickstart will always be indirect; the latter means 'memory 
access will be indirect until the first Picasso screen is opened', i.e., 
until after P96 has done it's memory probe thing.

So how can 'direct' memory access work full-time on Linux/x86 and in WinUAE, 
you ask? Well, in that case a segfault handler is installed to catch and 
handle such wacky, illegal memory accesses. The reason why this this doesn't 
work on OS X/Intel is that E-UAE hasn't yet been told how to handle segfaults 
on OS X.

This brings me back to my original point. While selecting 'indirect for 
Kickstart' or 'direct after Picasso' may work most of the time for OS 
X/Intel, since E-UAE doesn't yet know how to handle illegal memory accesses 
by the JIT on this platform, any program that tries to access 68k memory that 
isn't there - whether due to programmer error, or whatever - could cause 
E-UAE to segfault and die. That's why choosing 'indirect' is a safer, if 
slower, option.

Hope that explains things a little....

You're probably asking now why E-UAE lets you pick 'direct' memory access, 
etc., if that isn't safely supported by the host platform. Yeah. Good 
question. The Gtk+ UI actually doesn't let you. I just never fixed this in 
the main program.

Comments, questions?

Cheers,
Rich

Other related posts: