Updated VM-bridges document
Brian Goetz
brian.goetz at oracle.com
Thu Apr 11 23:04:15 UTC 2019
On 4/11/2019 5:18 PM, Karen Kinnear wrote:
>>
>> OK, so at this point, the classfiles that have been loaded look like:
>>
>> class D {
>> void m(LDT) { real method }
>> @Forwarding(m(LDT)) abstract void m(Date);
>> }
>>
>> class E extends D {
>> @Override
>> m(Date) { impl }
>> }
>>
>> So D has members m(LTD) and m(Date), the latter is a forwarder.
>> Therefore E has the same members (instance methods are inherited).
> From a source perspective, E has the same names of members, although
> it has overridden the contents of m(Date).
>
>>
>> Here's how I would imagine this turns into in the VM:
> not important, but this was m(LDT) not m(LTD)
>>
>> class D {
>> void m(LTD) { real method }
>> void m(Date d) { m(adapt(d)); } // generated forwarder
>> }
>>
>> class E extends D {
>> private void m$synthetic(Date d) { real method, body as
>> present in classfile }
> I would expect that the existing m(Date) with the real method would
> stay unchanged - including
> the name and the access controls - since there may be clients of
> subclass E still trying to invoke it.
I think this is our point of disconnect.
The subclass has overridden a forwarder. What we want to do is "heal
the rift" by rewriting the subclass as if it had _only_ overridden the
real method. Hence, the "shunt it off to a synthetic" and create an
overriding reverser that overrides the real method, adapting
args/return, which delegates to the shuntee.
If we left m(Date) in E, then this would be overriding the forwarder,
effectively un-doing the effect of forwarding.
Note that this is all "as if"; there are a hundred ways to _actually_ do
it.
More information about the valhalla-spec-observers
mailing list