I’ve been getting my stuff ready for IcedTea this week. I’ve been bootstrapping it with my ecj-bootstrapped b17/b22 hybrid, and so far it’s gone far more smoothly than I expected. The build system changes between b17 and b22 were far less pervasive than I’d thought, and the fact that my hybrid build seems to run ant without a hitch is gobsmacking. But debugging build scripts is slow and tedious — Hotspot bugs are far more fun to fix!

Some more todos for the list:

Slow signature handler
When Hotspot calls a native method it generates a signature handler that takes the arguments from the Java stack and puts them where the native ABI expects them. Signatures with 13 or fewer arguments can be represented as a 64-bit int, but longer signatures won’t fit. These get handled by the slow signature handler, which I haven’t written. This is what’s preventing the important enterprise application Slime Volleyball from running.
call_VM
Calls from the interpreter into the VM should use a call_VM macro. I’ve gotten away without this so far because a) I only have two or three calls, and b) most of what call_VM does on other platforms is not necessary on PPC. But I think I’ll need to write it when I start thinking about relocations and JITs.
JNI_FastGetField
There is some stuff to accelerate JNI field accesses that I haven’t written. It’s disabled in debug builds which is why I hadn’t noticed it until now.

My first builds ran to completion yesterday. It’s slow: the 32-bit one took nearly four hours and the 64-bit one a little over six — and this is on a quad 2.5GHz G5! I don’t have exclusive use of the machine though so I suppose other stuff may have been running in the meantime.

The next step is IcedTea integration. My tree is currently an odd hybrid of b17 with b22’s hotspot/src dropped in, and with all the build system changes between b17 and b23 I’ll basically be starting the port from scratch. This is possibly a good thing, because I want to switch from using ARCH_DATA_MODEL to using setarch, but it’s a pain nontheless. I plan to wait until the IcedTea guys have upgraded to b23 and sync my tree on that, remake all the build system patches and then import everything into IcedTea.

I have plenty to do in the meantime. I’ve been doing an audit of dodgy code while builds were running yesterday, basically looking for Unimplemented()s where they shouldn’t be and of course the ubiquitous XXX_EVIL_EVIL_EVIL. This is the state of my to do list:

Contended locks
The bit that handles locking and unlocking for synchronized native methods cannot cope when the lock is contended.
Relocations
The assembler doesn’t support relocations; if the garbage collector moves generated code then absolute addresses that reference other generated code will become invalid. I’m not sure if this matters currently.
Atomic copies
Copy::conjoint_jlongs_atomic() is not atomic on 32-bit. The other atomic copies are questionable too, but that one definitely doesn’t do what it says on the tin.
Stack args
The part of the signature handler that passes arguments to native methods on the stack is untested on 64-bit.
Unimplemented stuff
A brief and inexhaustive list: stack overflow checks, stack banging (whatever that is), JVMTI, JDI, profiling, prefetch, a JIT.

I now have Hello World executing to completion, 303,371 instructions on 32-bit and 307,209 on 64. There’s a lot missing, and a lot I plain don’t understand. And it’s very, very slow. I have a copy of javac running on 64-bit as I write. And running. And running. I attached gdb briefly and it was nearing two billion instructions. On 64-bit, that is. 32-bit is crashing in the garbage collector after a mere 300 million bytecodes or so. Debugging GC crashes is something I was dreading.

$ control/build/linux-ppc64/bin/java Hello
Hello world
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=/os_linux_ppc.hpp:28

  error: Unimplemented(): aztec/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.hpp:28

Only on 64-bit so far…

My first exception!

Error occurred during initialization of VM
java.lang.ExceptionInInitializerError
        at java.security.SecureClassLoader.<clinit>(SecureClassLoader.java:55)
        at sun.misc.Launcher.<init>(Launcher.java:71)
        at sun.misc.Launcher.<clinit>(Launcher.java:59)
        at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1322)
        at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1304)
Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.String
        at sun.security.util.Debug.<clinit>(Debug.java:45)
        at java.security.SecureClassLoader.<clinit>(SecureClassLoader.java:55)
        at sun.misc.Launcher.<init>(Launcher.java:71)
        at sun.misc.Launcher.<clinit>(Launcher.java:59)
        at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1322)
        at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1304)

I just spent the best part of a day trying to figure out why something was happening differently on 32- and 64-bit PPC. It turned out that what was happening was that one was decoding the string "OpenJDK  VM" while the other was decoding "OpenJDK 64-Bit  VM". I should feel pleased — things are working as they should — but it’s given me a headache.

Anyway, the point of this entry is that while I was in there I checked out that double-space. It was trying to insert "Server" or "Client", but of course mine has neither. It occurred to me that having undocumented variants of OpenJDK out there with weird identifiers could be slightly disturbing, so if you’re Googling this in the future trying to figure out what an "OpenJDK Aztec VM" or an "OpenJDK 64-Bit Aztec VM" is then this is the documentation: you’re using my stuff.

Because I keep getting this wrong, here is where the pointers in an interpreterState should point. This is a PPC32 frame with a four-word stack with one item pushed onto it and no monitors:

…680 Back chain
…684 LR save word
…688 Padding
…68c
…690 Slop
…694 _stack_limit
…698  
…69c Stack
…6a0 _stack
…6a4  
…6a8 Interpreter state _stack_base, _monitor_base
.
.
.
…6ec

This is the same frame with a monitor allocated:

…680 Back chain
…684 LR save word
…688 Slop
…68c _stack_limit
…690  
…694 Stack
…698 _stack
…69c  
…6a0 Monitor _stack_base
…6a4
…6a8 Interpreter state _monitor_base
.
.
.
…6ec