1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
# HG changeset patch
# User ngmr
# Date 1354993606 0
# Node ID 42b1142b39b5a511e1e07b5877cc55e93767064e
# Parent c5203e9e0e07559914a9c46dbba4fe85df945624
8000540: Improve IIOP type reuse management
Reviewed-by: alanb, ahgross, coffeys
diff --git a/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java b/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
--- corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
+++ corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
@@ -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.io.Serializable;
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;
@@ -82,8 +83,6 @@ public class ObjectStreamClass implement
private static Object noArgsList[] = {};
private static Class noTypesList[] = {};
-
- private static Hashtable translatedFields;
private static final Bridge bridge =
(Bridge)AccessController.doPrivileged(
@@ -380,6 +379,58 @@ public class ObjectStreamClass implement
*/
}
+ 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 @@ public class ObjectStreamClass implement
* 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
@@ -635,44 +658,6 @@ public class ObjectStreamClass implement
name = n;
suid = s;
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 ;
- }
}
/*
|