Covariant overrides on the Buffer Hierachy (original) (raw)
David M. Lloyd david.lloyd at redhat.com
Tue Apr 22 12:48:15 UTC 2014
- Previous message: Covariant overrides on the Buffer Hierachy
- Next message: Covariant overrides on the Buffer Hierachy
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 04/22/2014 04:17 AM, Peter Levart wrote:
On 04/22/2014 12:02 AM, David M. Lloyd wrote:
Um, do we know that there is a performance cost to covariantly overriding these methods? There would seem to be enough information to keep them monomorphic, if the optimizer is smart enough to inline the bridge methods and the delegating override method. The overridden methods in addition can be final, meaning that in the 99% case that you're invoking directly on the desired buffer type, it should be just as optimizable for the same reason that the original methods were optimizable. The only potentially "slow" invocation path is if you call the method on a Buffer reference, and even then it seems like there's enough information to avoid slowness - and if not, then that seems like a HotSpot problem that is very solvable ("if all overrides of this method call super.xxx(), inline & eliminate them"). It's more complicated than that. Maybe we need an expert for hotspot JIT to answer this question, but as the code is written in the Rickard's webrev, then the reasoning behind the JIT to keep the monomorphic dispatch would have to be more involving. Richard is doing the following (in ByteBuffer): @Override public ByteBuffer position(int newPosition) { super.position(newPosition); return this; } javac compiles each of the covariant overrides as two methods - one that actually "overrides" the virtual method in superclass (has the same signature) and calls the covariant-returning method with a virtual dispatch. So ByteBuffer.position(int) is compiled as: public ByteBuffer position(int newPosition) { super.position(newPosition); return this; } public Buffer position(int newPosition) { // this is an invokevirtual for position:(I)Ljava/nio/ByteBuffer; return (ByteBuffer) position( (int) newPosition); }
If the methods were final, AFAICT it'd be more like this:
public final ByteBuffer position(int newPosition) { // iirc super upcall is already bytecoded as invokespecial invokespecial (Buffer)Buffer.position(newPosition); return this; }
public synthetic final Buffer position(int newPosition) { return effectively-invokespecial (ByteBuffer)ByteBuffer.position(newPosition); }
Since there would only be one possible target for the invokevirtual, my understanding is that the JIT will convert that into an invokespecial, letting the whole works be optimized at worst and inlined at best.
--
- DML
- Previous message: Covariant overrides on the Buffer Hierachy
- Next message: Covariant overrides on the Buffer Hierachy
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]