Questions about type annotation on type casts.

Srikanth srikanth.adayapalam at
Mon Jan 18 06:52:33 UTC 2016

On Saturday 12 December 2015 02:47 AM, Alex Buckley wrote:
> On 12/11/2015 12:47 PM, John Rose wrote:
>> On Dec 10, 2015, at 4:25 PM, Alex Buckley <alex.buckley at
>> <mailto:alex.buckley at>> wrote:
>>> For the "(@T int)10" expression above, it would be the ldc that pushes
>>> 10. For "(float)1", it would be the fconst_1. For an auto-unbox like
>>> "int x = (int)new Integer(1);", it would be the invokevirtual on
>>> Integer.intValue().
>>> In effect, I'm recommending the offset of the last instruction of the
>>> chunk of code generated to evaluate the expression being cast.
>>> However, if javac prefers to record the offset of first instruction, I
>>> would not complain.
>> There is something especially useful about pointing at the bytecode (or
>> one of the bytecodes) that creates the finished expression value (or at
>> least moves it somewhere:  astore, areturn, etc).
>> By contrast, some earlier instruction which begins to execute the whole
>> expression is not securely related to the value whose type has been
>> annotated.  Loose language about "chunk of code" makes me nervous that
>> we might get dangling annotations.
>> For example, if I annotate the first instruction of the whole expression
>> `(@T int)a[i++]`, the annotation reader will see a logically unrelated
>> operation on `i`.  Surely pointing `@T` at `i++` is worse than merely a
>> QOI problem.  The meaning of `@T` might be "I know this is an even
>> number", and there's no way to get from the `i` bytecode to see the
>> `a[i++]`, and a reader might erroneously conclude that the programmer is
>> saying `i` is an even number.
> Especially since this expression would produce the same bytecode:
>   a[(@T int)i++]
> This might be a "big" QOI problem, but it's still "just" QOI, since 
> there's no compiler spec which javac is breaking.
> I suspect that javac "realizes" quite early that it doesn't need an 
> explicit instruction to implement the cast operator; and is aware that 
> the instruction stream for the expression being cast might be 
> complicated; and so is unwilling to hang on to @T throughout the 
> stream's generation; and so gets @T off its plate by recording the 
> most-eager offset, not the most-accurate. If most-accurate would 
> require a major rewrite of some javac phase, then it's probably 
> justified. Srikanth, please advise.

Sorry for the delayed response on this:

(1) The computation of the byte code offset for the type annotation, (2) 
the emission of byte codes for the expression being typecast
(3) the determination whether a checkcast is required in the class file 
or not and (d) the emission of checkcast if required - all happen
in the same phase (codegen) in the same order in which they are 
enumerated here, all in a span of half a dozen lines of code
that is amenable for reordering in a seemingly straightforward manner.

ATM, the computation of the annotation offset precedes translation of 
expression being typecast resulting in the big QOI problem
called out earlier. By computing the offset just after translation of 
the expression, the offset would point to the checkcast instruction
when present and when absent would point to the offset where the 
checkcast expression would have been had it not been optimized
away - i.e pointing to the earliest offset where the fully finished 
expression value is at the top of stack.

This appears to me to a better arrangement than what we have at present.

Also note that we have the same eager offset computation issue with 
instanceof - I don't see the compilers optimizing away
instanceof instructions as of now though.

> Alex

More information about the compiler-dev mailing list