Ask for a patch review: CallSite.target is not volatile
John Rose
John.Rose at Sun.COM
Thu Sep 18 15:31:14 PDT 2008
On Sep 13, 2008, at 7:27 AM, Rémi Forax wrote:
> currently CallSite.target is not volatile, so if an invokedynamic
> bootstrap
> method calls setTarget() in one thread, other threads may not see the
> new target.
>
> Proposed changes :
> - make target volatile
> - use unsafe.putOrdered to set the field in a more lightweight way.
Hmm... The EDR is ambiguous about this, and needs to be tightened
up. It does say that the bulk invalidation API is intended to
provide a global interlock, and gives some freedom to the propagation
of setTarget effects. What the EDR says about "next call" refers to
a global ordering that doesn't really exist in the JVM apart from
synchronization.
Native JVM implementations don't require target to be explicitly
volatile. In fact, individual threads need the freedom to cache the
target, e.g., as a loop invariant for a fast-path version of a loop.
The important thing to optimize here is the speed of *reading* the
target field. Writes can be as slow as we want (I use a native
method call).
All this is independent of whether the code says "volatile" or not on
the field, but it may be better not to mark it volatile, since that
seems to make a guarantee about propagation of setTarget effects.
Note that the JVM reads the target field in a specialized way, not
necessarily through a bytecode. Also, the writes to the target field
go through an accessor, so once again, the volatility of the field
does not necessarily matter. Except to the backport. For the
backport, I guess the volatile bit is needed. So, yes, that's a good
change.
Maybe the right thing to do is move target into a mixin-style
superclass, java.dyn.impl.CS, and have it be volatile in the backport.
This takes me to the second proposed change.
> - change alls field visibility from protected to private because :
> 1) protected fields appear in the JavaDoc,
> so another implementation of CallSite (like the one currently
> use by the backport)
> is not allowed.
> 2) caller, name and type are final so caller(), name() and type()
> can be used instead.
> subclasses can override checkTarget() to do nothing, in that
> case setTarget() is equivalent to change the target field.
> So I see no reason to declare this fields protected.
I want the CallSite to be usable two ways:
1. created by the JVM to reify invokedynamic instructions
2. creatable by Java code to simulate invokedynamic sites interpretively
Therefore, it's important to allow Java code to make its own flavor
of CallSite. Hence the protected methods & fields.
This could also be done with a CallSite interface, but it seems
easier to me (and to other JVM vendors I think) to make it a concrete
class.
Therefore, let's keep the protected stuff for now, unless we decide
to make CallSite into an interface.
I want to factor the 292 API into common classes, including the
public ones, and non-standard implementation-specific classes, one
version for each kind of JVM and one for the backport. The
java.dyn.impl package contains the implementation-specific classes.
(This name will change to go outside of the java.* hierarchy.) When
a public type needs to mix in fields or methods, it does so via
inheritance from an implementation superclass. Switching between
backport and native implementations will therefore require
adjustments to boot class path or the installed rt.jar.
Why use mixins? Although such pluggable implementations are more
often done via delegation or subclassing, the performance
requirements of method handles requires a more aggressive (less
flexible) pattern of single-inheritance mixins.
-- John
More information about the mlvm-dev
mailing list