For stack entries, I need to actually hide when the stack grows a bit too small, since currently they are treated like locals.
Was mowing about 2 acres of grass. Anyway, I have an idea for semi-whole
program optimization when it comes to fields. When I load a class I need to
have it so that partially loaded classes can be read. Then if global
field optimization is enabled, I look in the partially loaded set of classes
to see if one matches the field the class is in. If it is found, then the
flags and potential constant value of the class determine if the value is
treated as constant or not. By default if it is not enabled then fields in
other classes would be treated as always volatile, while fields in the current
class are treated with their respective flags and values. I have to watch when
loading classes though, that I do not fail if the dependent class is malformed.
I would have to catch the
JVMClassFormat error and then just default to the
volatile state. Also, to prevent failing classes from loading again I can
put in a list of failed classes which are not in the classpath at all. That
way they are never retried over and over again.
One thing though is that there has to be checking whether the operations flow correctly when they go from one set to another. I could actually be smart about it and put the code in the program state atoms and such. Doing it that way would also mean I can easily handle the metadata also without having the metadata handling code everywhere. So I would essentially perform a virtual not yet done push to the stack of the current atom to affect the next atom. If the next atom has state set for it and has variables then it is made sure that the given state would still be valid. So essentially, do a virtual pop of of the stack (does not actually change the state), then perform the operation of it where the result is stored in the target atom. If the target atom has state then it must match (except for the operator links). This I suppose would be the cleanest way to handle the operator links, since having that code in all of the byte code handlers would be very messy and error prone.
Actually looking at my code, the previous slot for the previous operation is incorrect.
Thinking about it, I wonder what would be the cleanest and efficient way to do
what I wrote previously about performing operations on the next of state.
Perhaps I could use internal temporaries of sorts, however those might not be
needed at all because the operator links are just virtual. If for example
is called which duplicates a stack element, then it just copies the operator
link without requiring temporary variables at all. Thus the code generator
would be smart enough to know that no actual work has to be done for said
operations. The stack contains most of the work however. So I suppose a
method which contains the operation to perform which also pushes the result
to the stack with the correct operator links and such. Then later on when
store needs to be done, the opposite effect. The only operation which really
takes from the locals and stores a value back in without using the stack is
iinc (which can also be used as an explicit add). So initially the first
method will be essentially
operatorLocalToStack which reads a local,
performs an operation, and places the result onto the stack. That seems simple
enough. Then it can check the target atom to make sure that it has the correct
state and such specified (that is, it would result in the same stack if it is