Because code is loaded in and out of memory all the time, some programs start some are terminated, and this happens the OS flushes the CPU cache.
If the JIT compiler does not know, it will store the old code in JIT cache, wrong code will be executed and every thing will crash.
You might be able to work around it by patching the OS, but then its a OS emulator not a hardware emulator.
Workbench 2.04 was first version of the OS that supported CPU cache, so its lowest OS version supported by JIT.
Flushing the cache on a branch or trying to work around the issue will result in JIT cache being flushed too often and so the code generator is executed too often for JIT compiler to be effective.
Decrypting routines used too prevent piracy and preventing hackers to understand track-loader, self modifying code, compressed executable is also a big issue, its was not uncommon to use this tricks on Amiga500, and whit out knowing when code is changed, it be a disaster.
Edited by LiveForIt on 2013/10/4 0:00:25 Edited by LiveForIt on 2013/10/4 0:06:47 Edited by LiveForIt on 2013/10/4 0:08:00
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
But that is not the point, the point is that cache is a software hardware thing, programmers should use the CacheClearU() or CacheClearE() routines, but this did not exist in kickstart1.3.
Older kickstart do not have the routines, so you can can clear the cache, besides there are no games for Amiga500 that know that they needed to call CacheClearU() or CacheClearE() routines, and this is the main problem, the games where never designed to run on new CPU models, anyway forward compatibility is impossible to archive, because you do not know what is coming, backward compatibility is how ever easier, and so newer CPU can disable CPU cache for backward compatibility .
And because JIT depends on Cache to work, its impossible to get to work this way, unless you spend hours patching the software, but way do that when you can run whdload version that is already patched.
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
Self modifying code may be a pain in the you-know-where for a JIT/recompiler, but you still need to handle it to some extent when emulating a CPU with a cache. It's quite simple to design your code in such a way that the cache is automatically flushed as need, without using any of the cache control opcodes. (Silly example for the 68020: Store 256 bytes of NOPs somewhere and jump through them to flush the cache.) There is also a lot of older software, designed for the A500, which runs just fine on an A1200 with the cache enabled.
By implementing some simple cash coherency, only forward modifications within a compiled block will fail to work. This is the approach used by FPSE for example, it simply ignores the special register setup and writes which are normally used to flush the cache, and instead handles the flushing itself as needed, i.e. when a compiled block is modified.
It's quite simple to design your code in such a way that the cache is automatically flushed as need, without using any of the cache control opcodes. (Silly example for the 68020: Store 256 bytes of NOPs somewhere and jump through them to flush the cache.)
You mean whit the intent to write a program or games that will work whit and whit out CPU cache, of course no old program will have bunch of NOPs in it to handle this.
You will need to inject it into the code, or maybe you were thinking about the consequence of this kind of trick, I can see how that might be problem if the JIT compiler did not handled it. Quote:
designed for the A500, which runs just fine on an A1200 with the cache enabled.
Is not CPU cache default off, until its enabled by setpatch, I think I remember reading something like that.
So booting a Amiga500 floppy game on A1200 should run the program code whit out CPU cache, unless the game enables it?
Anyway I remember there where some options for more compatible setting in the 3.0 Kickstart rom, don't remember what it was for. Quote:
This is the approach used by FPSE for example, it simply ignores the special register setup and writes which are normally used to flush the cache
You mean by identifying code signatures specific instructions streams? Yes if you can identify the decryption routines and cruncher routines, it might make more things work, but that must be huge task. Quote:
when a compiled block is modified.
Well then you need to check if address written to is a code block, I guess you can write protect code blocks whit the MMU to trigger a interrupt when this happens, but is there not a problem whit Memory block boundaries.
Or else you will need to compare the addresses whit memory blocks, that might be slow and give big penalty for the write operations.
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
Yes, exactly, if you code something for a specific CPU, you can sometimes take advantage of the caches being automatically flushed due to, for example, running a large piece of unrolled code. That will save you the hassle of actually doing the flushing programatically. It might even be faster, depending on how the actual cache flush has to be performed.
I have always assumed that the CPU cache is on by default since there's an option in the early startup menu to disable it. But perhaps that option only affects SetPatch somehow, I really don't know.
Yes, FPSE will, for each write, check if that write does modify a compiled block or not. That might seem very slow, but it is only a single table lookup.