Hi,

I propose a patch for the following and related bugs:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8011940

Here's the 1st webrev:

http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationData/webrev.01/

The patch eliminates classic synchronization by using optimistic concurrent construction. At the end of construction, the "winning" result is installed using CAS. The solution is modelled upon the similar solution used to cache reflection data. Both annotations Maps and a redefinedCount int are grouped in a container AnnotationData object which is referenced with a single volatile field. Not using any locks also solves potential deadlock situations described in a related bug:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7122142

That bug has already been closed with a fix for AnnotationType construction and caching:

http://hg.openjdk.java.net/jdk8/tl/jdk/rev/e4ce6502eac0

So the alternative solution for scalability problem is using double-checked locking instead of CAS should concurrent initial requests for annotations be a problem (CPU usage).

Micro benchmark shows about 5x improvement in raw single-threaded speed of retrieving an annotation by type and linear scalability:

http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationData/test_results1.txt

The space consumption is different with the patch. Initially j.l.Class objects are smaller, since one int and one reference field are eliminated from the j.l.Class. If annotations are requested the overhead is the AnnotationData container object and the field to reference it. But I tried to be smarter than the original code and when there's no inherited annotations (common situation), the annotations and declaredAnnotations share the same Map instance (originally new HashMap instance was constructed and entries copied). When there's no annotations declared on the class and no inherited annotations, this shared Map instance is an Collections.emptyMap() singleton.

Regards, Peter

Reply via email to