Hi Peter,

As Alan said, a big thanks for looking into this.

I have been toying with a slightly different approach to breaking the infinite 
recursion by pre-construct AnnotationType instances for Retention and 
Inherited. While cleaner in some places others became uglier. I'm fine with 
this approach.

As Alan said, you need to update the patch with a modification in 
TypeAnnotationParser. After doing that all java/lang tests in the jdk/test 
directory passes.

Also, can you please explain to me why the update race is safe. I have done 
the/some research myself but I would like to know which angles you have covered.

Given that and that you fix Alan's comments I think this is good to go.

Thanks again!

cheers
/Joel

On Jun 24, 2013, at 8:23 PM, Peter Levart <peter.lev...@gmail.com> wrote:

> On 06/19/2013 08:54 PM, Alan Bateman wrote:
>> Thank you for coming back to this.
>> 
>> I've looked over the webrev and the approach looks good to me. Joel might 
>> want to look at this too. Do you think you could include a test (as we try 
>> to include a test with all fixes if we can)?
>> 
>> It would be good to remove the synchronizaiton on initAnnotationsIfNecessary 
>> too, but one step as time (and smaller changes are always easier to discuss).
>> 
>> -Alan
> 
> Hi Alan,
> 
> I have prepared the 2nd revision of the patch:
> 
> http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationType/webrev.02/
> 
> There is a little change in AnnotationParser's alternative parsing method. 
> This time the parser does not assume anything about annotations being parsed 
> (previously it assumed that they had RUNTIME retention). The only difference 
> from standard parsing is that only the select annotation types are parsed and 
> the rest are quickly skipped. Infinite recursion is broken by the special 
> cased evaluation in AnnotationType constructor:
> 
> 129         // Initialize retention, & inherited fields.  Special treatment
> 130         // of the corresponding annotation types breaks infinite 
> recursion.
> 131         if (annotationClass != Retention.class &&
> 132             annotationClass != Inherited.class) {
> 133             JavaLangAccess jla = 
> sun.misc.SharedSecrets.getJavaLangAccess();
> 134             Map<Class<? extends Annotation>, Annotation> metaAnnotations =
> 135                 AnnotationParser.parseAnnotations(
> 136                     jla.getRawClassAnnotations(annotationClass),
> 137                     jla.getConstantPool(annotationClass),
> 138                     annotationClass,
> 139                     Retention.class, Inherited.class
> 140                 );
> 141             Retention ret = (Retention) 
> metaAnnotations.get(Retention.class);
> 142             retention = (ret == null ? RetentionPolicy.CLASS : 
> ret.value());
> 143             inherited = metaAnnotations.containsKey(Inherited.class);
> 144         }
> 145         else {
> 146             retention = RetentionPolicy.RUNTIME;
> 147             inherited = false;
> 148         }
> 
> 
> This is enough to break recursion. The RUNTIME and !inherited assumptions for 
> @Retention and @Inherited meta-annotations are therefore localized in this 
> code only.
> 
> I have also added two tests. The one for detecting deadlock situation and the 
> other for consistent parsing of mutually recursive annotations in presence of 
> separate compilation.
> 
> 
> 
> Regards, Peter
> 

Reply via email to