findStaticInit() is called in the resolution phase of
class-loading. It basically could reside in ur_java_class without any
complications (though I haven't tried and made sure), and isn't there
currently because it started out as part of the resolution functions
taking place in class_loader.cc, and was moved out as it became necessary
to call it last. All that it does is check if a static initializer
function exists, and if it does, creates a thread to run, should that
static initialization become necessary.
> (1) It looks like a new, fresh thread is spawned to run the static
> initializers. However, the thread that caused the classload doesn't
> seem to wait for the new thread to finish actually running those
> initializers (right?).
`while(jt->runOpcode());' will run until the thread finishes,
which is (normally) when the function on the bottom of the frame stack
(the static init) returns.
> This could be bad, right? (Actually, there seem
> to be a couple of multithreading hazards here in specific and in the
> class_loader abstraction in general -- basically, many threads might
> share the same classloader -- that might have to be addressed regardless
> of the answer to my next question.)
One would hope many threads share the same classloader -- where
would this be a problem? (Something I'm missing, probably...)
> (2) Is there some reason we don't just run those initializers within the
> context of the current (requesting) thread? Maybe just "push" their
> stack frames onto the stack so the vanilla machinery can tackle the
> problem? Is this a Java-ism? Is there some other advantage to spawning
> a new thread? (It pays to actually understand something before you
> attempt to muck with it, eh?)
Because it would be Very Annoying to arrange to push a method
frame in the middle of one bytecode and then return to that same point in
the bytecode after that method frame finishes executing; and there are
four such locations where static initialization is done.
Moving the method frame onto the stack (we could store a pointer
to the frame instead of a pointer to a thread) would allow for the
scheduler to take care of timeslicing the initialization but there are two
problems: (A) we'd have to take care to check at each static init point if
some other thread was mucking about with the static init also (perhaps, if
static_init == 1?) and if so, sleep until it finished -- the sleeping part
would probably be difficult to arrange; and (B) unwinding the stack & the
program counter would be annoying and result in much duplicated work for
these four locations.
It might, however, be wise to adjust the current system in some
way: should we ever implement native processes, so that one thread sitting
in its static_init loop *could* be interrupted by another, we'd have the
same problems as if the method frame had been pushed onto the frame stack.
Of course, alot of things would have to change if we ever did that, so I'm
not sure that we want to worry about it.
IMHO, since it (seems to) work, there's no need to change it.
Counter-arguments?
-_Quinn
_______________________________________________
Kernel maillist - [EMAIL PROTECTED]
http://jos.org/mailman/listinfo/kernel