changeset 80:42b1142b39b5

8000540: Improve IIOP type reuse management Reviewed-by: alanb, ahgross, coffeys
author ngmr
date Sat, 08 Dec 2012 19:06:46 +0000
parents c5203e9e0e07
children 58fdb67fcacc
files src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
diffstat 1 files changed, 57 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Sat Dec 08 18:49:21 2012 +0000
+++ b/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Sat Dec 08 19:06:46 2012 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 /*
  * Licensed Materials - Property of IBM
  * RMI-IIOP v1.0
- * Copyright IBM Corp. 1998 1999  All Rights Reserved
+ * Copyright IBM Corp. 1998 2012  All Rights Reserved
  *
  */
 
@@ -56,7 +56,8 @@
 
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import com.sun.corba.se.impl.util.RepositoryId;
 
@@ -83,8 +84,6 @@
     private static Object noArgsList[] = {};
     private static Class noTypesList[] = {};
 
-    private static Hashtable translatedFields;
-
     private static final Bridge bridge =
         (Bridge)AccessController.doPrivileged(
             new PrivilegedAction() {
@@ -380,6 +379,58 @@
          */
     }
 
+    private static final class PersistentFieldsValue {
+        private final ConcurrentMap map = new ConcurrentHashMap();
+        private static final Object NULL_VALUE =
+            (PersistentFieldsValue.class.getName() + ".NULL_VALUE");
+
+        PersistentFieldsValue() { }
+
+        ObjectStreamField[] get(Class type) {
+            Object value = map.get(type);
+            if (value == null) {
+                value = computeValue(type);
+                Object oldValue = map.putIfAbsent(type, value);
+                if (oldValue != null) {
+                    value = oldValue;
+                }
+            }
+            return ((value == NULL_VALUE) ? null : (ObjectStreamField[])value);
+        }
+
+        private static Object computeValue(Class<?> type) {
+            try {
+                Field pf = type.getDeclaredField("serialPersistentFields");
+                int mods = pf.getModifiers();
+                if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
+                        Modifier.isFinal(mods)) {
+                    pf.setAccessible(true);
+                    java.io.ObjectStreamField[] fields =
+                        (java.io.ObjectStreamField[])pf.get(type);
+                    return translateFields(fields);
+                }
+            } catch (NoSuchFieldException e1) {
+            } catch (IllegalAccessException e2) {
+            } catch (IllegalArgumentException e3) {
+            } catch (ClassCastException e4) { }
+            return NULL_VALUE;
+        }
+
+        private static ObjectStreamField[] translateFields(
+                java.io.ObjectStreamField[] fields) {
+            ObjectStreamField[] translation =
+                new ObjectStreamField[fields.length];
+            for (int i = 0; i < fields.length; i++) {
+                translation[i] = new ObjectStreamField(fields[i].getName(),
+                        fields[i].getType());
+            }
+            return translation;
+        }
+    }
+
+    private static final PersistentFieldsValue persistentFieldsValue =
+        new PersistentFieldsValue();
+
     /*
      * Initialize class descriptor.  This method is only invoked on class
      * descriptors created via calls to lookupInternal().  This method is kept
@@ -412,35 +463,7 @@
                  * If it is declared, use the declared serialPersistentFields.
                  * Otherwise, extract the fields from the class itself.
                  */
-                try {
-                    Field pf = cl.getDeclaredField("serialPersistentFields");
-                    // serial bug 7; the serialPersistentFields were not
-                    // being read and stored as Accessible bit was not set
-                    pf.setAccessible(true);
-                    // serial bug 7; need to find if the field is of type
-                    // java.io.ObjectStreamField
-                    java.io.ObjectStreamField[] f =
-                           (java.io.ObjectStreamField[])pf.get(cl);
-                    int mods = pf.getModifiers();
-                    if ((Modifier.isPrivate(mods)) &&
-                        (Modifier.isStatic(mods)) &&
-                        (Modifier.isFinal(mods)))
-                    {
-                        fields = (ObjectStreamField[])translateFields((Object[])pf.get(cl));
-                    }
-                } catch (NoSuchFieldException e) {
-                    fields = null;
-                } catch (IllegalAccessException e) {
-                    fields = null;
-                } catch (IllegalArgumentException e) {
-                    fields = null;
-                } catch (ClassCastException e) {
-                    /* Thrown if a field serialPersistentField exists
-                     * but it is not of type ObjectStreamField.
-                     */
-                    fields = null;
-                }
-
+                fields = persistentFieldsValue.get(cl);
 
                 if (fields == null) {
                     /* Get all of the declared fields for this
@@ -637,44 +660,6 @@
         superclass = null;
     }
 
-    private static Object[] translateFields(Object objs[])
-        throws NoSuchFieldException {
-        try{
-            java.io.ObjectStreamField fields[] = (java.io.ObjectStreamField[])objs;
-            Object translation[] = null;
-
-            if (translatedFields == null)
-                translatedFields = new Hashtable();
-
-            translation = (Object[])translatedFields.get(fields);
-
-            if (translation != null)
-                return translation;
-            else {
-                Class osfClass = Class.forName("com.sun.corba.se.impl.io.ObjectStreamField");
-                translation = (Object[])java.lang.reflect.Array.newInstance(osfClass, objs.length);
-                Object arg[] = new Object[2];
-                Class types[] = {String.class, Class.class};
-                Constructor constructor = osfClass.getDeclaredConstructor(types);
-                for (int i = fields.length -1; i >= 0; i--){
-                    arg[0] = fields[i].getName();
-                    arg[1] = fields[i].getType();
-
-                    translation[i] = constructor.newInstance(arg);
-                }
-                translatedFields.put(fields, translation);
-
-            }
-
-            return (Object[])translation;
-        }
-        catch(Throwable t){
-            NoSuchFieldException nsfe = new NoSuchFieldException();
-            nsfe.initCause( t ) ;
-            throw nsfe ;
-        }
-    }
-
     /*
      * Set the class this version descriptor matches.
      * The base class name and serializable hash must match.