Lambda metafactory + default methods + bridges
Daniel Heidinga
Daniel_Heidinga at ca.ibm.com
Thu Sep 13 13:39:28 PDT 2012
We've been investigating a test case with Brian that causes the lambda
metafactory to generate bridges in the SAM implementation class for
signatures that would otherwise be handled by the VM processing of default
methods. This example shows a situation where the metafactory's bridging
will conflict with the bridges required for default methods:
interface I<T, V extends Number> {
String be(T s);
String be(V n);
}
interface DI extends I<String,Integer> {
String be(String s) default {return s; };
String be(Integer n);
}
DI is a SAM interface; it has one abstract method be(Integer), which has
bridge method be(Number). At the same time, be(String) is a default method
that has bridge method be(Object) generated by the VM. Without generic
analysis, the metafactory cannot distinguish the fates of its two methods
(it does not see that be(T s) will be bridged by the VM), so bridges both.
In this case generating a ClassCastException.
After considering (and rejecting) a number of options, we've been
concentrating on the idea of allowing the metafactory to request that the
VM generate all the appropriate bridges for a given class. The VM already
needs to be able to do this analysis to correctly wire in default methods
and this would lean on the same infrastructure. We currently believe this
is a feasible approach in both J9 & Hotspot.
This leaves a number of open questions to resolve:
1) How does a classfile signal to the VM that it requires the VM to
generate all bridge methods? Either a bit in the class modifiers or an
attribute could be used. We've guessed at three possible bridging modes
that could be requested: i) bridge nothing, ii) bridge everything, iii)
bridge defaults only. Both i) & ii) are obviously useful modes while iii)
may be less useful. More thought required.
2) How closely should VM bridge methods match the behaviour of bridge
methods generated by the static compiler? Should these methods be visible
in a stack trace? There are cases where the VM can skip generating a
bridge by reusing the original method and we'll need to spec the behaviour
very carefully to ensure all implementations are compatible. The spec
needs to be clear so we don't run into security / visibility issues, for
example when doing caller class checks.
I'm sure other questions will arise as we dig into this.
--Dan
More information about the lambda-spec-observers
mailing list