RFR 8155258: VarHandle implementation improvements
vladimir.x.ivanov at oracle.com
Wed May 4 16:19:48 UTC 2016
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.
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:
> 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.
More information about the hotspot-dev