Need to increase some efficiencies in certain aspects.
Usually when it comes to immutable classes, I just have
protected final and
then have getters. Using
public final fields could cause lockin (but if
people use it, they may be forced to change). However methods may be added
and such. It would be cleaner so to speak, despite being a bit against the
existing Java mantra. There are no beans, no method handles, no lambdas. Using
fields with lambdas is interesting though (requires the
() ->), however there
is none of that here. Also, less methods would be smaller and faster to
translate. Having getters would include the method and the field itself. So
I suppose for immutable I will use public final fields if applicable, then
otherwise if it is insane to use that, then getters will be used. However
stuff which is cached, would be behind getters still. Alternatively though,
this can be seen as premature optimization.
Would be premature, the optimizer when generating code can handle such details.
I should make an interpreter which can be used as a re-compilation pass to native code (as I am doing already) but have it in a pass form. Basically it treats the class as in input stream, picks out any needed data, and then is done with it. Loading and byte code verification could be done in a single pass and be translated to register form. Then the interpreter would be a bit faster and it would be ready for native code compilation.
I could also modify the descriptors to be more cachable and be able to use CharSequence to reference the descriptor data. Then there would not be a need to duplicate strings, because the descriptor could already be a string.
Ok, so a linear loading class format should be a bit more inline. So
essentially that would mean a mutable
I can actually create a cache manager which does not use reflection. However
it would require that said
Reference objects always exist, so there would
be an extra object. There would also need to be an existing class or an extra
class in memory (so it can get
newInstance()ed). So although a bunch of the
cache code is duplicated from each other, that is actually more minimal.
Although, I could perform a kind of trick pertaining to it. Essentially I
would do the call such as:
ref = Cache.<Foo<V>>cache(this, ref, Instantiator.class);
Then the Instantiator class would be capable of creating a new of this object.
If the instantiator is not loaded (it would be in a WeakHashMap) then it would
be constructed and initialized (and stored into the map). Then if the class is
collected, then its instantiator goes away. However, the value can also be
WeakReference, so it would essentially be
WeakHashMap<Class<?>, WeakReference<?>>. This way the instantiator can be
collected when not used, yet reused multiple times if it does need to be used.
The class type would be a weak key, so if the instantiator is never referenced
again it goes away.
It would probably be a
Instantiable interface used by a
The only issue is returning the value given by the cache. I would likely need
to allocate an array for output. This would be needed because otherwise a
garbage collection cycle can during the return of the method, which will cause
the freshly cached object to be collected. Then ref would just return
which would be an error.
Cache class can be garbage collected too when it is not needed. So
although there is a slight increase in memory requirements, overall execution
may see less objects in memory because these can be freely collected as such.
The problem with this though is I need to have publically visible instantiators for this to work. To avoid this I would have too allocate a class for this. So then it would just be an anonymous class which gets initialized as needed.
Actually the cache stuff needlessly complicates things, so I am going to just not use it.
I am going to make
JVMClass mutable and patchable so that it may be used
by a compiler in the future and it would be easier to potentially mutate state
to fit the run-time if needed.
JVMClassFile becoming a parser, it can read a bunch of data and then
just throw out what it not needed by the interpreter. This simplifies things
and makes it so only the required detail is included.
So far, I like how the class is now parsed. It is much simpler and not a giant mess.
And the flag handling is much simpler too, no more is it a complex mess. I will have to do the same things for members also.
And interfaces are in their own
JVMClassInterfaces which simplifies having
a bunch of them and making sure they are correct.