A new month is now.
So there have been 554 commits this month. Let us see what I have done. I did
some refactoring of DynamicByteBuffer but that class went away. Removed Zip64
support and plans. But the resulting and eventual use of
ByteDeque is rather
nice for the most part. I made the inflation code much faster, something that
is a bit more sane. I started a bunch of JIT work also. Basically, I wrote a
rather nasty ELF output, but then rewrote that to be much nicer and more
reuseable for other systems. Did a bunch of JIT refactoring and work so that
the JIT is rather nice also. I just now need to implement register allocation
for generic targets. Spent a number of days trying to figure out why my ELF
output was not working, but I eventually figured it out and decided to just
rewrite all of that code. I made the base JIT much more sane as previously
mentioned some more. Setup a basic generic binary output which is mostly
16-bit currently to save as much space as possible. I added handling of POSIX
paths, since I will need that for native I/O and emulation of binaries for
a given system.
Thinking about it, my emulator for Linux MIPS can be very simple. It can just load in the ELF binary and then start executing it as if it were an executable. Then I could just for the most part treat it as a chunk of memory for the most part. I fixed up Lex a bunch of times and made some improvements which are quite a bit noticable, they do look better. Near the end of the month I actually got some code running on the reference implementation, despite it just throwing TODO. I will need to have more a test system in place where I can load all the JARs that I can or at least merge them into a single JAR for quick testing. Basically what I will need to do is, since I believe the liblets are not being considered by it (it should have complained about them missing, but it did not), would be to have a special output that can repackage the binaries for running on said environment. Then if I can run the tests on it, I would then be able to see what works and how things are different compared to OpenJDK and that environment. I would completely manage it in my own code, in Java, but have a helper script and such. Since it requires a Raspberry Pi, I can setup one that sits around. I placed in the skeletons for MEEP LUI, Key, and MIDlet. However, one thing I have to do is rewrite the build system and have a kind of bootstrap. Then my build system would for the most part be written for SquirrelJME and once I get a Java compiler, it would be self hosting for the most part. The only issue would be building and then potentially executing the JARs. However, if when I get enough of a working JIT that can recompile code, I can always implement an interpreter on top of that which could run the native code. Likely the best choice would be to have it generate MIPS code and then setup an emulator that uses the host filesystem and such. So although the programs being ran are purely emulated it would seem as if they were not (at least filesystem wise anyway).
Ok, so while I was away I thought about renaming the package manager to just
projects and then renaming the package also. I also thought about that
exportation I was talking about, where I would merge multiple JARs into one
and create a JAD of them. One thing I could do is have a kind of system where
I can export the JAR and then depend on other parts. Essentially since the VM
is similar to Java 7 but without
invokedynamic, what I can do is basically
go through the class files and rewrite part of their constant pools during
method processing and such. Essentially I can JIT the byte code. Although in
reality, what I could do is a kind of JIT which similar to the generic JIT
just targets existing JVMs. I thought of this before, although the best choice
would likely to be just to expand and add another JIT which targets the JVM.
Then I can have a cross-compiled environment to J2ME for example. The only
issue would be that the JVM code would have no JIT, so it would essentially be
limited to running built-in packages. Then I would need to modify statics so
that they are purely instances only. I would also need to implement writing
of the old style
StackMap attribute also. The end result though would be an
environment I can run on J2ME devices (such as my phone and PDA) before I
actually support said systems. One thing that would likely be recommended
would be to have it where each version can be separated. Since I only have a
limited bandwidth on my phone, I would want it where I can run newer and
older environments. But first, I will rename the package manager code.
Actually the register allocator only needs to know about the stack and the general purpose registers to choose. It does not need to know about the constant pool or the method pool because that is handled by the JIT itself when it needs to access things.
Well, I need a more complex register setup system. I really should match the ABI of the host, this way I do not have to do mass saving and restoring when I need to make a system call or calling a library support method. Also matching the ABI would make debugging it easier with gdb.
Ok, so on real systems, each register has a purpose. Also for a given ABI there are arguments, temporaries, alignments, and other such things. Currently my code would be heading twords initializing this information all the time which would be quite expensive and rather wasteful. I need to have a builder of register setups and such and then just re-use that. This would mean a single object shared across all instances of the JIT.
I should also look at differing ABIs such as for PowerPC, SPARC, ARM, and x86. Then I can get a better idea of what the register information has to store and such.
Then after that, instead of having allocator factories, the generic JIT is just associated with the GenericABI. Then the register allocator is completely internal for the most part.
One thing I can do instead of using
CPVariableType is used another but
explicitely for a register type. I can specify a fixed size or the word size
of the CPU, then this way I do not need two separate sets of registers for
32-bit and 64-bit.