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