Looks good.
I'm fine with pushing it directly into jdk9/dev, since the change just
relaxes the assert and the risk of a merge conflict is very small.
Best regards,
Vladimir Ivanov
PS: I wonder whether the MH cache in VarHandle
(VarHandle.typesAndInvokers.methodHandle_table) should be idempotent or not.
In the past, we had to make some caches in j.l.i idempotent
(specifically, Invokers.invokers and MethodTypeForm.methodHandles).
The problem was that the JVM can cache a method the MH points to (e.g.,
inline caches in generated code for MH invokers). If it happens, the JVM
doesn't expect to observe 2 different instances of the MH, otherwise an
assertion is fired.
I can't say for sure it's not the case for VarHandles as well.
On 5/3/16 1:18 AM, Paul Sandoz wrote:
Hi,
Please review:
http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8155258-vhs-impl-improvements-jdk/webrev/
<http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8155258-vhs-impl-improvements-jdk/webrev/>
http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8155258-vhs-impl-improvements-hotspot/webrev/
<http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8155258-vhs-impl-improvements-hotspot/webrev/>
The hotspot changes are really small. Is there is precedent in such cases to
push through jdk9-dev rather than hs, thus speeding up the integration?
There are a bunch of improvements (mostly space/time):
1) By default a VarHandle does not hold its method types for access mode
methods. Instead the erased types are held on VarForm (this shared across many
VH instances) and are leveraged by the guard methods (see 4).
1.1) The non-erased method types are created on demand and cached (see 3).
2) Remove the use of ClassValue to hold VarForm instances. Each VarHandle
implement holds its VarForm as a static instance. MemberNames to each access
mode method implementation are still calculated on construction (this can be
revisited to be lazy as a further issue).
3) A VarHandle caches invoker-based MethodHandles (access mode method type
prefixed with VarHandle as the first parameter) to the corresponding
MemberNames held on VarForm. Such handles are used by the
VarHandle.toMethodHandle, by the guard methods (see 4), or general
linkers/invokers.
4) The guard methods (on VarHandleGuards) were revamped to:
4.1) leverage the erased types in 1)
4.2) optimize for the void calling case (dropping the return value) when
linking to a non-void access mode method. This is an edge case but avoids
surprises (e.g. dropping the return value of a CompareAndExchange). This
leverages a little known fact of invokehandle linking where it is safe to drop
the return value (John assures me this is safe!), and required a slight tweak
to hotspot for verification under fastdebug execution.
4.3) leverage the cached invoker method handle in 3) for the case where
boxing/conversion is required, with an asType transformation. This is the
non-optimal path, but is much better than before since the invoker method
handle is a constant.
JPRT core and hotspot tests pass.
Paul.