src/share/classes/sun/reflect/generics/repository/ClassRepository.java

Print this page
rev 7735 : 8064846: Lazy-init thread safety problems in core reflection

*** 38,49 **** * The code is not dependent on a particular reflective implementation. * It is designed to be used unchanged by at least core reflection and JDI. */ public class ClassRepository extends GenericDeclRepository<ClassSignature> { ! private volatile Type superclass; // caches the generic superclass info ! private volatile Type[] superInterfaces; // caches the generic superinterface info // private, to enforce use of static factory private ClassRepository(String rawSig, GenericsFactory f) { super(rawSig, f); } --- 38,52 ---- * The code is not dependent on a particular reflective implementation. * It is designed to be used unchanged by at least core reflection and JDI. */ public class ClassRepository extends GenericDeclRepository<ClassSignature> { ! /** The generic superclass info. Lazily initialized. */ ! private volatile Type superclass; ! ! /** The generic superinterface info. Lazily initialized. */ ! private volatile Type[] superInterfaces; // private, to enforce use of static factory private ClassRepository(String rawSig, GenericsFactory f) { super(rawSig, f); }
*** 75,85 **** * using a visitor. * a visitor, which is created by feeding it the factory * with which the repository was created. */ ! public Type getSuperclass(){ Type superclass = this.superclass; if (superclass == null) { // lazily initialize superclass Reifier r = getReifier(); // obtain visitor // Extract superclass subtree from AST and reify getTree().getSuperclass().accept(r); --- 78,88 ---- * using a visitor. * a visitor, which is created by feeding it the factory * with which the repository was created. */ ! public Type getSuperclass() { Type superclass = this.superclass; if (superclass == null) { // lazily initialize superclass Reifier r = getReifier(); // obtain visitor // Extract superclass subtree from AST and reify getTree().getSuperclass().accept(r);
*** 88,112 **** this.superclass = superclass; } return superclass; // return cached result } ! public Type[] getSuperInterfaces(){ Type[] superInterfaces = this.superInterfaces; if (superInterfaces == null) { // lazily initialize super interfaces // first, extract super interface subtree(s) from AST TypeTree[] ts = getTree().getSuperInterfaces(); // create array to store reified subtree(s) ! Type[] sis = new Type[ts.length]; // reify all subtrees for (int i = 0; i < ts.length; i++) { Reifier r = getReifier(); // obtain visitor ts[i].accept(r);// reify subtree // extract result from visitor and store it ! sis[i] = r.getResult(); } - superInterfaces = sis; // cache overall result this.superInterfaces = superInterfaces; } return superInterfaces.clone(); // return cached result } } --- 91,114 ---- this.superclass = superclass; } return superclass; // return cached result } ! public Type[] getSuperInterfaces() { Type[] superInterfaces = this.superInterfaces; if (superInterfaces == null) { // lazily initialize super interfaces // first, extract super interface subtree(s) from AST TypeTree[] ts = getTree().getSuperInterfaces(); // create array to store reified subtree(s) ! superInterfaces = new Type[ts.length]; // reify all subtrees for (int i = 0; i < ts.length; i++) { Reifier r = getReifier(); // obtain visitor ts[i].accept(r);// reify subtree // extract result from visitor and store it ! superInterfaces[i] = r.getResult(); } this.superInterfaces = superInterfaces; } return superInterfaces.clone(); // return cached result } }