Porting Jainja JVM
|
Hi, I am the author of the Jainja JVM 1 and saw on the forum that there was some interest in running Java on RISC OS. So I tried and got preliminary results. Things that work well:
Things not tested yet:
Difficulties:
|
|
Hello Guillaume, |
|
Welcome! That interest might be a “one person only” thing: me. I had a quick look at Jainja some time ago when looking for portable JVM options, but never had the free time necessary to get into the details. So many thanks that you are doing the grunt work. I think you already had a go a few years ago?
I would still be interested in having a look at test builds if you are prepared to share your work at this early point of develeopment. I guess you are using GCCSDK? Which GCC version?
UnixLib (“the POSIX library”) has code to automatically do that “create directories to simulate extensions” thing, but to be honest, I wouldn’t recommend that, because it introduces all kind of subtle problems all along the way. Just use “/” as an extension separator instead of the usual “.”, and “.” instead of the usual “\” or “/” as a directory separator and disable automatic extension conversion in UnixLib (IIRC, you can set a system variable externally for that). I think this will make it also easier in the long run when you start reading your class files from within jars. |
|
Thank you Alain and Steffen for your answers.
Yes but I haven’t managed to set up a practical development environment. I managed to compile but the executable crashed.
Yes: gcc version 4.7.4 (GCCSDK GCC 4.7.4 Release 6)
Sure, a temporary RISC OS package is available in the Downloads section of the project. Some progress: I was able to run complex GUIs using a SDL backend. But they don’t work like they should: the operating system is a bit frozen. |
|
After some research I realized I had the same problem with a relatively simple test application in C using SDL. I’m not sure I can fix this in libSDL. So I’ll focus on using Java from the command line for now. I’m still interested in getting feedback on using the test build on real hardware (I am currently developing/testing with RPCEmu) |
|
Hello Guillaume, when you say hardware, you mean riscos on a raspberry pi (5.28…) or Archimedes/RiscPC hardware ? |
|
As Jainja is an interpreter, you need a fairly fast processor, so I was thinking about a Raspberry Pi. For processors below 500 MHz, it’s best to use a JIT or compile Java code ahead of time. I think I could also provide the latter but Java threads won’t work. |
|
It’s looking good. I’ll post back tomorrow with my observations. In the meantime, there’s a NetSurf-friendly link below for anyone who wants to try it. A couple of things come to mind before I go: SCUMMvm and a few Python games (Store- supplier: JVS) use SDL 1.2. |
|
Here are the results, RPi4 (RISCOS daily build 22-Oct-23).
The window’s content is there, but the window itself has issues. I discovered that I can quit the TaskWindow to get control back. In Tetris, you can see the game, but again, the window has issues. And it’s a similar thing with the other examples. I see a Git repository for SDL, which I guess you may already know about. https://github.com/libsdl-org/SDL-1.2/blob/main/README.RISCOS https://www.riscosopen.org/forum/forums/11/topics/17302 The code contained in the preceding links works on my computer with no window issues- saying that it’s not exactly doing much. Good luck, and thank you. |
|
Are you able to build specific files with different optimisation levels to the rest of the code? That might help narrow down what’s going wrong.
UnixLib is capable of handling both name/ext and ext.name conventions automatically. Which extensions use which conventions is dictated by an environment variable, but the default behaviour is to use name/ext conventions. You can also turn off path conversion, but that’ll require handling everything yourself. Most of the Acorn-era Java stuff I’ve encountered uses name/ext conventions, so it would make sense for Jainja to do so as well.
It’s quite possible that it’s just too slow at the moment. The important thing to remember is that RISC OS uses cooperative multitasking, so you’ll need to make sure that you call SDL_PollEvents, SDL_Delay or a similar function regularly to make sure that the other tasks get a chance to run. Also, I wouldn’t recommend running GUI applications from a Task Window since that’s never worked very well for me. If you need some way of showing debug messages while the GUI is active, I’d recommend using Reporter instead. |
|
Thank you very much Andrew ! It seems to me that this performance is consistent with what one would expect. In this case, a x3 slowdown compared to an x86 processor at the same frequency.
Interesting, how do you do that?
I tried to inspect the RISC OS code in the SDL 1.2 repository but found no solution yet. |
|
This isn’t what I’m currently doing but it’s possible so I’ll try.
In pseudo-code, I do this: while(!exit) { wimp_poll(GET_EVENTS_EXCEPT_MOUSE_KEY_WINDOW); exit = vm_tick(); // Execute 1000 bytecodes per thread } When a GUI is started, vm_tick() also runs a dedicated (green) thread to poll GUI events every 50ms using SDL_PeepEvents.
If I redirect the output to null the task window doesn’t show so I assume the JVM is no longer attached to it (?) Thanks Cameron ! |
|
You’re welcome. I quit the Task window by assuming that despite the general lack of response from the system, a click on the close [x] icon might work, and it did. ;) Background reading: Further down the line, I wonder if this means you might be able to re-use some of the existing resource allocations |
|
From this comment from Cameron and Andrew’s link of a helloworld for SDL (known to work well), I did some tests and can reproduce the issue:
So I did the same thing for the JVM, and voila, the problem disappeared ! I guess Task Window is interfering with the logic in libSDL somehow. Thank you again for your comments which put me on the path. I don’t know if I would have been able to find the problem alone. Now I’m going to try to optimize all of that and make it easy to use the JVM. |
|
Very good progress, thank you Guillaume for investing your time into our niche platform. Seeing a Java-based GUI on a RISC OS desktop more than 25 years after Acorn’s “Riscafe Java 1.0.2” efforts goes far beyond my expectations. Very well done. As always, my free time for experimentation is currently very limited, but I promise to do some trials of the “things I always wanted to test if a JVM for RISC OS ever surfaces” kind ASAP. And of course running Jainja on a Windows/Linux JVM also remains on my TODO list. |
|
Here is some news. First of all I installed RISC OS on an RPI3 and I use VNC and OmniClient/Samba to have a faster development cycle. I tried to figure out why GCC’s optimization flags weren’t working. After numerous tests, I had some progress:
This optimized version (but limited by the absence of a garbage collector) is approximately 3x faster. On the RPI3, an application with a simple AWT GUI takes about 2 seconds to start. In the package I will put both versions:
|
|
Good to hear more about the project, Guillaume. ;) I keep checking the Sourceforge download page for a new release. If you need a soundboard or more information about GCC, the GCC mailing list is at riscos.info. Thanks for the update. |
|
I figured out how to fix some GCC optimization flag issues. I put a new version (jainja_riscos_dev_20231120) on SourceForge. There are now 3 versions of the JVM. jainja
jainja-na
jainja-na-armv7
Limitations / bugs:
By editing the !Run file you can try some GUI examples. You could even try a Swing application, but as you probably know, it’s a huge library so don’t expect it to be very fast on an interpreter. |
|
256MB may sound a lot, but you can multiply by 10 if something like pyCharm is ever going to run on it! |
|
Guillaume, again thank you for your ongoing effort, it looks like you are making good progress.
I have quite a few home-grown Swing applications that would even make sense running on RISC OS, so this will surely be interesting to see if I can get acceptable speed out of them. Back in the mid-2000s, I did quite a bit of Look’n’Feel benchmarking for a large Swing application, and the differences between the L&F implementations were staggering. I guess in an environment like Jainja, differences would be even more noticable. |
|
Yes, I think so too. That’s why I’ve been evaluating different ways to optimize this for several months. Now I think there are two ways to do it:
Currently I’m looking at scenario 2. |
|
My gut feeling is that the interpreter itself will not be the bottleneck, but the graphics operations. Probably not helped by the SDL layer in this case. ISTR that Synth allowed for custom painters, maybe this could be an interesting optimization knob. But it is certainly an immense complexity you are dealing with here, and good profiling is always a challenge. |