Multiple this$1 fields when mixing subclassing and inner classes
Stefan Reich
stefan.reich.maker.of.eye at googlemail.com
Sat Sep 21 15:16:06 UTC 2019
I thought about it some more and I think it is theoretically possible. You
just compile the invokespecial statements on the "magic" this$1 field into
something involving a cast.
That cast does have to be a checked one, because in the presence of
reflection, we can't guarantee that this$1 has the correct (formally
undeclared) subtype. So it involves a performance degradation.
Or you move that degradation to Field.set() which would have to check for
this special case. Sounds nasty too. It would probably slow down every
single Field.set() on any field which is rather not acceptable.
In effect, we'd have a field that does not have its declared type, but,
when the whole class is subclased, only allows a certain subtype.
All in all, I guess it's not worth doing. But that wasted space of a
doubled reference to the same object just irks me :-D
Regarding the bureaucracy, I think I'll actually sign the OCA. Maybe I'll
need it at some point...
It's not like in the old Sun days where you had to be careful to never have
looked at "classified" parts of the JDK if you wanted to re-implement parts
of it yourself, is it? I remember this being an issue in the JOS project
back in the day. ("Clean-room implementations.") I don't remember exactly
what the subprojects were, but people were so hyped about Java, they
basically wanted to make their own clones of it.
On Tue, 10 Sep 2019 at 01:17, David Holmes <david.holmes at oracle.com> wrote:
> On 10/09/2019 9:09 am, Stefan Reich wrote:
> > But you're not talking about bytecode here you're talking about
> inside
> > the VM. If there is an invokespecial on this$1 of type A then the
> > constant pool lookup of its type will be A and we will resolve the
> call
> > based on A's methods. If it were of type B then the resolution
> process
> > would be different. There's nowhere to "insert a cast" here.
> >
> >
> > Can invokespecials on this$0/this$1 happen? I'm struggling to imagine a
> > case for this.
> >
> > invokespecial invokes private instance methods, superclass methods or
> > constructors. Superclass methods don't apply, neither do constructors.
> > And calls to private methods happen through bridges (just verified this
> > for myself again :):
> >
> > 13: aload_0
> > 14: getfield #1 // Field this$0:Lbla;
> > 17: invokestatic #4 // Method
> > bla.access$000:(Lbla;)V
> >
> > So what remains?
>
> This changed in JDK 11 with the addition of nestmates. Now inner classes
> have direct private access, no bridges needed, and we use invokespecial
> or invokevirtual as appropriate. For private methods invokevirtual is
> mainly used now, but of course we don't do virtual dispatch - there are
> special rules for private method resolution and selection.
>
> class A {
> void m() {}
> class InnerA {
> void callM() { m(); }
> }
> }
>
> void callM();
> descriptor: ()V
> flags: (0x0000)
> Code:
> stack=1, locals=1, args_size=1
> 0: aload_0
> 1: getfield #1 // Field this$0:LA;
> 4: invokevirtual #13 // Method A.m:()V
> 7: return
> LineNumberTable:
> line 4: 0
>
> > BTW what introspection tool did you use to show this?
> >
> > My own tools ("JavaX")... here's the example program:
> > http://code.botcompany.de/1025166
>
> Thanks for the pointer.
>
> Cheers,
> David
>
> > Many greetings :)
>
--
Stefan Reich
BotCompany.de // Java-based operating systems
More information about the hotspot-dev
mailing list