jdk7 b58, VM doesn't smell good
forax at univ-mlv.fr
Tue May 12 16:55:37 PDT 2009
John Rose a écrit :
> On May 12, 2009, at 3:46 PM, Rémi Forax wrote:
>> I've found that if you convert the leading argument of the method
>> you have to cast the leading argument of MethodHandle.invoke() too.
> Yes, that's because method handle invocation sites do not allow
> variation in the target method handle's type, not even covariant
> argument type changes or contravariant return type changes.
Yes, and the VM should report a WrongMethodTypeException.
But It throws the *famous* NoClassDefFoundError.
> Sorry about your code. The root cause is that the resolution of the
> type signature for MH.invoke is done relative to MH itself (which
> would be correct if MH actually statically declared its invoke
> methods). Since MH is on the BCP, and your app class is on some other
> class loader, MH cannot resolve type names from your app in the
> signature of its invoke methods. That's why b59 erases non-BCP
> receiver types in findVirtual. Yuck.
Ok, that why I haven't found that bug before b58 because
my old tests was also on the boot class path.
So this is a another workaround, put all your app on the boot class path.
> I find it slightly annoying anyway (even if this bug did not exist)
> that findVirtual(my.random.class, "foo", t) returns a MH whose type
> leads off with my.random.class. This class may in fact by an
> anonymous class whose identity I don't care about (in the case of
> MHs.bind), so it's hard to see what I gain from being so exact about
> the type. Of course, if I'm doing
> findVirtual(my.important.and.public.api.interface.or.class, "foo", t),
> I probably do want to know about the type of the leading argument. So
> I don't see that there's a cleanup to be done at this point in the API.
The VM doesn't differentiate a Java anonymous class from a standard class,
so it seems there is no way to improve the API.
> -- John
> P.S. Having method handles auto-convert among "reasonably similar"
> method-tyeps is implementable, but it would slow down every method
> handle call, unless we were to institute a static type checking system
> that the verifier would enforce. Today's reality is dynamic type
> safety checks, and complicating that check (which is currently a
> single pointer comparison) would have questionable benefit. This is
> because dynamic languages do not follow the covariant/contravariant
> conventions of statically typed functional languages. (I would prefer
> to call dynamic call sites "malvariant" in recognition of the fact
> that they usually vary, but half the time in the wrong direction, as
> in the canonical case of a call of type (Object)->Object.) Moreover,
> the type conversions that dynamic languages require are not obviously
> aligned with any particular theory of function types; for example,
> auto boxing and unboxing are important features for dynamic languages,
> and it would be a long stretch to call these conversions subtype
The downside of that is that the only way to implement Neal's closure
type system with the current spec is to erase all Method handle type
(with convert) just after the creation of a method handle.
About the slow down effect, It can be removed by allowing the two way
(John's one and Fredrik's one) to call a method handle:
MethodHandle.invoke() that performs a single pointer check and
MethodHandle.apply() that performs a less restrictive/more expensive
But I don't know if it worth the additional complexity.
More information about the mlvm-dev