I can imagine some implementation approaches to this problem.
1) Do whatever barriers are necessary, all the time, in the
interpreter. If you're doing a lot of interpretation, you're not
interested in high performance, so performance in the interpreter
isn't very critical (see Ole Agesen and my upcoming PLDI submission).
2) When method A.m references static variable B.x, the compilation of
A.m occurs before or after B.x has been initialized.
a) If after, then we have no problem: referencing B.x will cause
b) If before, then we have to, as you point out, be conservative
and surpress reorderings and insert the necessary barriers.
Even in this case we can do better, though: the compilation can
record that the compilation of A.m was "impeded" by the fact
that B had not yet been initialized. When B is eventually,
initialized we can record that fact on a list. At the next GC,
say, when all threads are stopped and can presumably be made to
do a read barrier, A.m and other threads that were compiled
suboptimally because of B can be recompiled (or at least the
B-related memory barriers could be changed to NOPs.)
While I argued in (1) that you can't do a lot of interpretation if
you want to perform well, this sort of situation is one reason why
doing a little interpretation before compiling often leads to
Because of this, it's interesting that these semantics, if left
unchanged and taken seriously, might be a large advantage for dynamic
compilation over static compilation. In the dynamic case, the
compilation can know whether the referenced class has been initialized
yet, where this is much harder in the static case.
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:23 EDT