changeset 10257:e141fdeb9ff3

8064391: More thread safety problems in core reflection Summary: Make fields final or volatile to ensure thread safety Reviewed-by: jfranck
author martin
date Thu, 13 Nov 2014 14:48:18 +0100
parents dc4b0e9ce63f
children 3381b0df022a
files src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java src/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java src/share/classes/sun/reflect/generics/repository/AbstractRepository.java src/share/classes/sun/reflect/generics/repository/ClassRepository.java src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java src/share/classes/sun/reflect/generics/scope/AbstractScope.java src/share/classes/sun/reflect/generics/tree/ClassSignature.java
diffstat 7 files changed, 24 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java	Thu Nov 13 14:48:18 2014 +0100
@@ -45,8 +45,8 @@
  * core reflection (java.lang.reflect).
  */
 public class CoreReflectionFactory implements GenericsFactory {
-    private GenericDeclaration decl;
-    private Scope scope;
+    private final GenericDeclaration decl;
+    private final Scope scope;
 
     private CoreReflectionFactory(GenericDeclaration d, Scope s) {
         decl = d;
--- a/src/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java	Thu Nov 13 14:48:18 2014 +0100
@@ -40,7 +40,7 @@
  *
 */
 public abstract class LazyReflectiveObjectGenerator {
-    private GenericsFactory factory; // cached factory
+    private final GenericsFactory factory; // cached factory
 
     protected LazyReflectiveObjectGenerator(GenericsFactory f) {
         factory = f;
--- a/src/share/classes/sun/reflect/generics/repository/AbstractRepository.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/repository/AbstractRepository.java	Thu Nov 13 14:48:18 2014 +0100
@@ -40,9 +40,9 @@
 
     // A factory used to produce reflective objects. Provided when the
     //repository is created. Will vary across implementations.
-    private GenericsFactory factory;
+    private final GenericsFactory factory;
 
-    private T tree; // the AST for the generic type info
+    private final T tree; // the AST for the generic type info
 
     //accessors
     private GenericsFactory getFactory() { return factory;}
--- a/src/share/classes/sun/reflect/generics/repository/ClassRepository.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/repository/ClassRepository.java	Thu Nov 13 14:48:18 2014 +0100
@@ -42,8 +42,8 @@
 
     public static final ClassRepository NONE = ClassRepository.make("Ljava/lang/Object;", null);
 
-    private Type superclass; // caches the generic superclass info
-    private Type[] superInterfaces; // caches the generic superinterface info
+    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) {
@@ -80,17 +80,20 @@
  */
 
     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);
             // extract result from visitor and cache it
             superclass = r.getResult();
+            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();
@@ -104,6 +107,7 @@
                 sis[i] = r.getResult();
             }
             superInterfaces = sis; // cache overall result
+            this.superInterfaces = superInterfaces;
         }
         return superInterfaces.clone(); // return cached result
     }
--- a/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java	Thu Nov 13 14:48:18 2014 +0100
@@ -42,7 +42,7 @@
 public abstract class GenericDeclRepository<S extends Signature>
     extends AbstractRepository<S> {
 
-    private TypeVariable<?>[] typeParams; // caches the formal type parameters
+    private volatile TypeVariable<?>[] typeParams; // caches the formal type parameters
 
     protected GenericDeclRepository(String rawSig, GenericsFactory f) {
         super(rawSig, f);
@@ -65,6 +65,7 @@
      * @return the formal type parameters of this generic declaration
      */
     public TypeVariable<?>[] getTypeParameters(){
+        TypeVariable[] typeParams = this.typeParams;
         if (typeParams == null) { // lazily initialize type parameters
             // first, extract type parameter subtree(s) from AST
             FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
@@ -78,6 +79,7 @@
                 tps[i] = (TypeVariable<?>) r.getResult();
             }
             typeParams = tps; // cache overall result
+            this.typeParams = typeParams;
         }
         return typeParams.clone(); // return cached result
     }
--- a/src/share/classes/sun/reflect/generics/scope/AbstractScope.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/scope/AbstractScope.java	Thu Nov 13 14:48:18 2014 +0100
@@ -41,8 +41,8 @@
 public abstract class AbstractScope<D extends GenericDeclaration>
     implements Scope {
 
-    private D recvr; // the declaration whose scope this instance represents
-    private Scope enclosingScope; // the enclosing scope of this scope
+    private final D recvr; // the declaration whose scope this instance represents
+    private volatile Scope enclosingScope; // the enclosing scope of this scope
 
     /**
      * Constructor. Takes a reflective object whose scope the newly
@@ -71,7 +71,11 @@
      * @return the enclosing scope
      */
     protected Scope getEnclosingScope(){
-        if (enclosingScope == null) {enclosingScope = computeEnclosingScope();}
+        Scope enclosingScope = this.enclosingScope;
+        if (enclosingScope == null) {
+            enclosingScope = computeEnclosingScope();
+            this.enclosingScope = enclosingScope;
+        }
         return enclosingScope;
     }
 
--- a/src/share/classes/sun/reflect/generics/tree/ClassSignature.java	Fri Nov 14 12:00:07 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/tree/ClassSignature.java	Thu Nov 13 14:48:18 2014 +0100
@@ -28,9 +28,9 @@
 import sun.reflect.generics.visitor.Visitor;
 
 public class ClassSignature implements Signature {
-    private FormalTypeParameter[] formalTypeParams;
-    private ClassTypeSignature superclass;
-    private ClassTypeSignature[] superInterfaces;
+    private final FormalTypeParameter[] formalTypeParams;
+    private final ClassTypeSignature superclass;
+    private final ClassTypeSignature[] superInterfaces;
 
     private ClassSignature(FormalTypeParameter[] ftps,
                                       ClassTypeSignature sc,