I am still seriously concerned about JIT compilation and class loading
on shared memory multiprocessors.
On the Alpha for example, consider the case where processor 1
* loads a class Bar,
* creates all of the internal data structures for Bar,
* generates native code for some of the methods in Bar
* runs the static initializer for Bar
* creates an instance of Bar
* does a memory barrier (possibly at other points above)
* stores a reference to that instance in Foo.x
(while not calling any synchronized methods, and thus
not needing memory barriers, except to prohibit behavior
I am about to describe)
* reads the reference in Foo.x, happens to see the value
written by processor 1
* Invokes a virtual method on that reference
* reads the vtbl pointer in the instance
* reads the contents of the vtbl
* jumps to native code generated by processor 1
* does an instanceof on "this", reading C-level fields
of the class data structure
* reads instance and static fields of the instance
All of the stuff done on processor 2 after reading Foo.x
might see stale values. We've discussed way processor 2
could detect and recover from reading stale values for the
vtbl pointer from the object header. But in order to be sure that
all the class data structures and vtbl entries are valid, processor
2 must do a memory barrier instruction. To ensure that the
native code generated by processor 1 isn't stale,
processor 2 needs to do a CALL_PAL IMB (instruction
Even without class loading, if a HotSpot compiler decided
to generate optimized native code for a method, it couldn't
just substitute the new, optimized code: other processors
might see stale, invalid versions.
The only reasonable way I see to fix this, is to not make
newly loaded classes or newly compiled code available
until the next garbage collection (at which time, everyone does
a global memory barrier).
If you wanted to reduce that latency, but were willing to endure
a higher per-invocation cost, here is one possibility:
* In each class structure, have a field that says which thread
is know to have a coherent view of that class. When a class is
created, it is set to the creating thread.
* At garbage collection time, this field is set to a special value
* Whenever a thread references the class data structure, the thread must
check to see if the field is either ANY or itself. If not, it must do
a memory barrier, and optionally change the field to be itself.
You could do a similar thing for native code.
Do people agree that something like this is required?
This is the JavaMemoryModel mailing list, managed by Majordomo 1.94.4.
To send a message to the list, email JavaMemoryModel@cs.umd.edu
To send a request to the list, email firstname.lastname@example.org and put
your request in the body of the message (use the request "help" for help).
For more information, visit http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:16 EDT