On 12/15/2010 07:31 AM, John Rose wrote:
On Dec 13, 2010, at 12:19 AM, Rémi Forax wrote:
On 12/12/2010 05:02 PM, Rich Hickey wrote:
Rémi's synchronized block only coordinates the activities of updaters.
Other threads may, and in some cases may have to, see some of the
setTarget results prior to the sync call, which could be a mess. The
point of syncTargets is to make the setting and the visibility atomic,
which synchronized cannot do.
Yes, syncTargets would be very powerful. But it would also be hard to
require of all JVMs. Speaking only for HotSpot, we don't do everything
with safepoints, because they are expensive. We use racy updates
whenever we can get away with it. The cost of a racy update is the
co-existence of two states, unpredictably visible to various threads.
I think that's a normal complexity cost for doing good language
implementations.
I think mapping a global atomic update to the JMM would require
more "magic edges" in the happens-before graph. The proposal
I posted, while weaker, has a correspondingly simpler impact on
the JMM. This is another way of observing that JVMs are likely to
have an easier time of adding the proposed functionality.
So a globally atomic update is harder to implement and harder
to specify. It is also overkill for a common use case, which is
delayed optimization of call sites. See below...
Rich,
I don't think you can provide an optimized method handle when syncing but
more probably a default generic method that will later installs a fast path.
Thanks, Remi, for explaining this. I'm going to pile on here.
(I have one comment on your code; see below.)
[...]
So if the result of setTarget is visible before the sync call, it will
execute
a default generic method which will also enter in a synchronized block.
This will effectively coordinate things between readers and writers.
invariant broken (writer):
synchronized(masterLock) {
// mutate meta data
// update all callsites
foreach(impacted callsites) {
callsite.setTarget(callsite.defaultGenericPath);
}
sync(impacted callsites);
}
default generic method (reader):
synchonized(masterLock) {
// check arguments
// use meta data to create a fast path
}
(This next line should also be synchronized. -- JRR)
setTarget(guard + fastpath);
Correct me if I'm wrong.
Le last line can be in the synchronized block but it don't have to.
The JMM guarantees that the current thread will see the new target (T2).
Other threads can see T1 and in that case will update to a T2' which is
semantically equivalent to T2.
It's a racy update.
This pattern intends to mimick the way the VM do lazy deoptimization
i.e mark the callsite as deoptimized and later when the callsite is used
re-create a fast path.
Rémi
--
You received this message because you are subscribed to the Google Groups "JVM
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en.