Miranda methods and Methods added by Code Generators

Andrew Dinn adinn at redhat.com
Mon Aug 9 06:56:45 PDT 2010


On 08/09/2010 02:11 PM, Maurizio Cimadamore wrote:
>> Your description of the current situation is not quite accurate. When
>> javac compiles the source of Child it is not at that time compiling
>> the source of Parent. It only has the bytecode of Parent available
>> (the generated SYNTHETIC method _only occurs_ in the bytecode). So, it
>> is possible for javac to end up finding SYNTHETIC methods in its
>> method tables which it has not itself introduced directly through
>> analysis of source code.
> Are you suggesting that the check can erroneously fail in a scenario
> without AOP? If so, please post an example.

Err, no, not exactly. Although it is not specifically the use of AOP 
which is pertinent here. Any bytecode transformer can take a compiled 
class, introduce extra interfaces and implementations of the interfaces' 
methods into the class then rewrite the bytecode file. If it labels 
these methods as SYNTHETIC then the question is how should javac 
interpret this when it compiles sources against the transformed bytecode.

The point I was trying to make was that javac does not always see the 
source for every class it handles during a compile -- some of the code 
is only available as bytecode. Clearly it can assume that SYNTHETIC 
methods of classes it has translated from source are so because it has 
labelled them so. Clearly it also does assume that any code found in 
bytecode which is SYNTHETIC must have been labelled as SYNTHETIC by it 
on a previous compile. This was obviously a valid assumption before 
anyone implemented a bytecode transformer. All I am saying is that it is 
not necessarily valid now. These days the tool chain is more complex 
than just javac.

As a consequence of this assumption javac assumes that anything with the 
SYNTHETIC attribute cannot be regarded as an implementation of an 
abstract method - it assumes this even if the method also has bytecode. 
Now, that definitely looks to be an anomaly prima facie as far as Im 
concerned. Whether or not this is a valid assumption on its own terms it 
is most definitely at variance with what the JVM does. The latter will 
happily load and execute SYNTHETIC bytecode. As I said previously, take 
away the abstract qualifies in the Parent child example and you can will 
see the JVM happily execute Parent.getAdvisor() when a call is made to 
child.getAdvisor() where child is an instance of Child.

In fact, there is a  more immediate disparity between the JVM and javac 
which applies even in the case where abstract classes are involved. The 
problem I raised in my example only occurs if the AOP transform is 
applied between two successive compiles, first of Parent then of Child. 
If you compile them both in one call to javac and then transform Parent 
to add interface Advised and method getAdvisor() you arrive at the 
situation javac is banning: a SYNTHETIC implementation of 
Parent.getAdvisor() on abstract class Parent inherited by a non-abstract 
subclass Child. In this case the JVM will load Parrent and Child and 
validate both classes. It is quite happy to accept the SYNTHETIC 
implementation of getAdvisor() as an implementation of the method 
declared in interface Advised.

This is why I regards the behaviour of javac as an error. At the very 
least it is a rather obvious inconsistency between what the JVM and the 
compiler take to be the semantics of SYNTHETIC. More importantly, by 
applying this narrower meaning to SYNTHETIC javac is stopping other 
compile-chain tools profiting from the availability of the SYNTHETIC 
flag. Now maybe they ought to use their own attributes to identify that 
this is generated code but it would be much easier and more convenient 
if this meaning were applied consistently by JVM, javac and other 
compile-chain tools.

>> What I don't understand is why you have to rely on just the SYNTHETIC
>> attribute to identify the cases which javac should discount. Looking
>> at ClassWriter.java it appears that bridge methods are written to the
>> classfile with the BRIDGE attribute. Similarly, Miranda methods are
>> written with the SYNTHETIC and ABSTRACT attribute. So, why
>> automatically discount SYNTHETIC methods? Could you not instead
>> discount SYNTHETIC|BRIDGE or SYNTHETIC|ABSTRACT methods?
> That's what I had in mind when I said that the check could be perceived
> as too strict.

Well, ok then, I do perceive it as too strict. So, here's the $64M 
questionL can this be relaxed :-)

regards,


Andrew Dinn
-----------



More information about the compiler-dev mailing list