On Fri, 23 Oct 2020 18:06:51 GMT, Jorn Vernee <jver...@openjdk.org> wrote:
>> Hi, >> >> This patch adds an asExact() combinator to VarHandle, that will return a new >> VarHandle that performs exact type checks, similar to >> MethodHandle::invokeExact, to help developers catch inexact VarHandle usage, >> which can lead to performance degradation. >> >> This is implemented using a boolean flag in VarForm. If the flag is set, the >> exact type of the invocation is checked against the exact type in the >> VarForm. If there is a mismatch, a WrongMethodTypeException is thrown. >> >> Other than that, there is also an asGeneric() combinator added that does the >> inverse operation (thanks to Rémi for the suggestion). I've also added The >> `@Hidden` annotation to the VarHandleGuards methods, as well as a >> type-checking helper method called from the generic invocation lambda form, >> so that the stack trace we get points at the location where the VarHandle is >> being used. >> >> Thanks, >> Jorn >> >> GH action link (at time of submission): >> https://github.com/JornVernee/jdk/actions/runs/324660237 > > Jorn Vernee has updated the pull request incrementally with one additional > commit since the last revision: > > Make internalName helper method static This approach does not work for reference types, since they are erased to `Object`, and then exact checking will be performed on the erased reference types. For example try this: import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; public class Test { int x; public static void main(String[] args) throws Throwable { VarHandle x = MethodHandles.lookup().findVarHandle(Test.class, "x", int.class); VarHandle ex = x.asExact(); Test t = new Test(); ex.set(t, 1); } } Which results in: Exception in thread "main" java.lang.invoke.WrongMethodTypeException: expected (Object,int)void but found (Test,int)void at Test.main(Test.java:11) Exact type checking requires that match be performed on the VH access mode method type and the exact symbolic method type, something like: final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { if (handle.vform.exact && handle.accessModeType(ad.type) != ad.symbolicMethodTypeExact) { throw new WrongMethodTypeException("expected " + handle.vform.methodType_table_exact[ad.type] + " but found " + ad.symbolicMethodTypeExact); } Then it's precisely the same as `MH.invokeExact`, rather than `MH.invoke`. A `VarForm` is a resource shared across many instances of the same _kind_ of `VarHandle`, so cannot be used for exact matching, except in specific scenarios e.g. access on a primitive array. ------------- PR: https://git.openjdk.java.net/jdk/pull/843