changeset 7726:4728d748209d

8064391: More thread safety problems in core reflection Summary: Make fields final or volatile to ensure thread safety Reviewed-by: jfranck
author igerasim
date Wed, 26 Nov 2014 20:47:26 +0300
parents a812404727c0
children af7c2b5cd307
files src/share/classes/java/lang/Class.java 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 8 files changed, 27 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/Class.java	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/java/lang/Class.java	Wed Nov 26 20:47:26 2014 +0300
@@ -2460,7 +2460,7 @@
     private native String getGenericSignature();
 
     // Generic info repository; lazily initialized
-    private transient ClassRepository genericInfo;
+    private volatile transient ClassRepository genericInfo;
 
     // accessor for factory
     private GenericsFactory getFactory() {
@@ -2470,11 +2470,13 @@
 
     // accessor for generic info repository
     private ClassRepository getGenericInfo() {
+        ClassRepository genericInfo = this.genericInfo;
         // lazily initialize repository if necessary
         if (genericInfo == null) {
             // create and cache generic info repository
             genericInfo = ClassRepository.make(getGenericSignature(),
                                                getFactory());
+            this.genericInfo = genericInfo;
         }
         return genericInfo; //return cached repository
     }
--- a/src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java	Wed Nov 26 20:47:26 2014 +0300
@@ -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	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java	Wed Nov 26 20:47:26 2014 +0300
@@ -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	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/repository/AbstractRepository.java	Wed Nov 26 20:47:26 2014 +0300
@@ -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	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/repository/ClassRepository.java	Wed Nov 26 20:47:26 2014 +0300
@@ -40,8 +40,8 @@
  */
 public class ClassRepository extends GenericDeclRepository<ClassSignature> {
 
-    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) {
@@ -78,17 +78,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();
@@ -102,6 +105,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	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java	Wed Nov 26 20:47:26 2014 +0300
@@ -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	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/scope/AbstractScope.java	Wed Nov 26 20:47:26 2014 +0300
@@ -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	Tue Nov 25 17:04:11 2014 +0300
+++ b/src/share/classes/sun/reflect/generics/tree/ClassSignature.java	Wed Nov 26 20:47:26 2014 +0300
@@ -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,