Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | c18cbe5936b8 |
children | 6bd680e9ea35 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.utilities.soql; | |
26 | |
27 import java.util.*; | |
28 import sun.jvm.hotspot.oops.*; | |
29 import sun.jvm.hotspot.utilities.*; | |
30 | |
31 /** | |
32 This is JavaScript wrapper for InstanceKlass. | |
33 */ | |
34 public class JSJavaInstanceKlass extends JSJavaKlass { | |
35 private static final int FIELD_SOURCE_FILE = 1; | |
36 private static final int FIELD_INTERFACES = 2; | |
37 private static final int FIELD_FIELDS = 3; | |
38 private static final int FIELD_METHODS = 4; | |
39 private static final int FIELD_IS_PRIVATE = 5; | |
40 private static final int FIELD_IS_PUBLIC = 6; | |
41 private static final int FIELD_IS_PROTECTED = 7; | |
42 private static final int FIELD_IS_PACKAGE_PRIVATE = 8; | |
43 private static final int FIELD_IS_STATIC = 9; | |
44 private static final int FIELD_IS_FINAL = 10; | |
45 private static final int FIELD_IS_ABSTRACT = 11; | |
46 private static final int FIELD_IS_STRICT = 12; | |
47 private static final int FIELD_IS_SYNTHETIC = 13; | |
48 private static final int FIELD_IS_INTERFACE = 14; | |
49 private static final int FIELD_CLASS_LOADER = 15; | |
50 private static final int FIELD_PROTECTION_DOMAIN = 16; | |
51 private static final int FIELD_SIGNERS = 17; | |
52 private static final int FIELD_STATICS = 18; | |
53 private static final int FIELD_UNDEFINED = -1; | |
54 | |
55 public JSJavaInstanceKlass(InstanceKlass kls, JSJavaFactory fac) { | |
56 super(kls, fac); | |
57 this.instanceFields = new HashMap(); | |
58 this.staticFields = new HashMap(); | |
59 } | |
60 | |
61 public final InstanceKlass getInstanceKlass() { | |
62 return (InstanceKlass) getKlass(); | |
63 } | |
64 | |
65 public Object getMetaClassFieldValue(String name) { | |
66 int fieldID = getFieldID(name); | |
67 InstanceKlass ik = getInstanceKlass(); | |
68 switch (fieldID) { | |
69 case FIELD_SOURCE_FILE: { | |
70 Symbol sourceFile = ik.getSourceFileName(); | |
71 return (sourceFile != null)? sourceFile.asString() : "<unknown>"; | |
72 } | |
73 case FIELD_INTERFACES: | |
74 return getInterfaces(); | |
75 case FIELD_FIELDS: | |
76 return factory.newJSList(ik.getImmediateFields()); | |
77 case FIELD_METHODS: | |
78 return factory.newJSList(ik.getImmediateMethods()); | |
79 case FIELD_IS_PRIVATE: | |
80 return Boolean.valueOf(getAccessFlags().isPrivate()); | |
81 case FIELD_IS_PUBLIC: | |
82 return Boolean.valueOf(getAccessFlags().isPublic()); | |
83 case FIELD_IS_PROTECTED: | |
84 return Boolean.valueOf(getAccessFlags().isProtected()); | |
85 case FIELD_IS_PACKAGE_PRIVATE: { | |
86 AccessFlags acc = getAccessFlags(); | |
87 return Boolean.valueOf(!acc.isPrivate() && !acc.isPublic() && !acc.isProtected()); | |
88 } | |
89 case FIELD_IS_STATIC: | |
90 return Boolean.valueOf(getAccessFlags().isStatic()); | |
91 case FIELD_IS_FINAL: | |
92 return Boolean.valueOf(getAccessFlags().isFinal()); | |
93 case FIELD_IS_ABSTRACT: | |
94 return Boolean.valueOf(getAccessFlags().isAbstract()); | |
95 case FIELD_IS_STRICT: | |
96 return Boolean.valueOf(getAccessFlags().isStrict()); | |
97 case FIELD_IS_SYNTHETIC: | |
98 return Boolean.valueOf(getAccessFlags().isSynthetic()); | |
99 case FIELD_IS_INTERFACE: | |
100 return Boolean.valueOf(ik.isInterface()); | |
101 case FIELD_CLASS_LOADER: | |
102 return factory.newJSJavaObject(ik.getClassLoader()); | |
103 case FIELD_PROTECTION_DOMAIN: | |
104 return factory.newJSJavaObject(ik.getProtectionDomain()); | |
105 case FIELD_SIGNERS: | |
106 return factory.newJSJavaObject(ik.getSigners()); | |
107 case FIELD_STATICS: | |
108 return getStatics(); | |
109 case FIELD_UNDEFINED: | |
110 default: | |
111 return super.getMetaClassFieldValue(name); | |
112 } | |
113 } | |
114 | |
115 public boolean hasMetaClassField(String name) { | |
116 if (getFieldID(name) != FIELD_UNDEFINED) { | |
117 return true; | |
118 } else { | |
119 return super.hasMetaClassField(name); | |
120 } | |
121 } | |
122 | |
123 public String getName() { | |
124 return getInstanceKlass().getName().asString().replace('/', '.'); | |
125 } | |
126 | |
127 public boolean isArray() { | |
128 return false; | |
129 } | |
130 | |
131 public String[] getMetaClassFieldNames() { | |
132 String[] superFields = super.getMetaClassFieldNames(); | |
133 Set k = fields.keySet(); | |
134 String[] res = new String[k.size() + superFields.length]; | |
135 System.arraycopy(superFields, 0, res, 0, superFields.length); | |
136 int i = superFields.length; | |
137 for (Iterator itr = k.iterator(); itr.hasNext();) { | |
138 res[i] = (String) itr.next(); | |
139 i++; | |
140 } | |
141 return res; | |
142 } | |
143 | |
144 public Object getInstanceFieldValue(String name, Instance instance) throws NoSuchFieldException { | |
145 Field fld = findInstanceField(name); | |
146 if (fld != null) { | |
147 return getFieldValue(fld, name, instance); | |
148 } else { | |
149 throw new NoSuchFieldException(name + " is not field of " | |
150 + getInstanceKlass().getName().asString().replace('/', '.')); | |
151 } | |
152 } | |
153 | |
154 public Object getStaticFieldValue(String name) throws NoSuchFieldException { | |
155 Field fld = findStaticField(name); | |
156 if (fld != null) { | |
157 return getFieldValue(fld, name, getInstanceKlass()); | |
158 } else { | |
159 throw new NoSuchFieldException(name + " is not field of " | |
160 + getInstanceKlass().getName().asString().replace('/', '.')); | |
161 } | |
162 } | |
163 | |
164 public String[] getInstanceFieldNames() { | |
165 if (instanceFieldNames == null) { | |
166 InstanceKlass current = getInstanceKlass(); | |
167 while (current != null) { | |
168 List tmp = current.getImmediateFields(); | |
169 for (Iterator itr = tmp.iterator(); itr.hasNext();) { | |
170 Field fld = (Field) itr.next(); | |
171 if (!fld.isStatic()) { | |
172 String name = fld.getID().getName(); | |
173 if (instanceFields.get(name) == null) { | |
174 instanceFields.put(name, fld); | |
175 } | |
176 } | |
177 } | |
178 current = (InstanceKlass) current.getSuper(); | |
179 } | |
180 | |
181 Set s = instanceFields.keySet(); | |
182 instanceFieldNames = new String[s.size()]; | |
183 int i = 0; | |
184 for (Iterator itr = s.iterator(); itr.hasNext(); i++) { | |
185 instanceFieldNames[i] = (String) itr.next(); | |
186 } | |
187 } | |
188 return instanceFieldNames; | |
189 } | |
190 | |
191 public boolean hasInstanceField(String name) { | |
192 Field fld = findInstanceField(name); | |
193 return (fld != null)? true: false; | |
194 } | |
195 | |
196 public String[] getStaticFieldNames() { | |
197 if (staticFieldNames == null) { | |
198 InstanceKlass current = getInstanceKlass(); | |
199 List tmp = current.getImmediateFields(); | |
200 for (Iterator itr = tmp.iterator(); itr.hasNext();) { | |
201 Field fld = (Field) itr.next(); | |
202 if (fld.isStatic()) { | |
203 staticFields.put(fld.getID().getName(), fld); | |
204 } | |
205 } | |
206 | |
207 Set s = staticFields.keySet(); | |
208 staticFieldNames = new String[s.size()]; | |
209 int i = 0; | |
210 for (Iterator itr = s.iterator(); itr.hasNext(); i++) { | |
211 staticFieldNames[i] = (String) itr.next(); | |
212 } | |
213 } | |
214 return staticFieldNames; | |
215 } | |
216 | |
217 public boolean hasStaticField(String name) { | |
218 Field fld = findStaticField(name); | |
219 return (fld != null)? true: false; | |
220 } | |
221 | |
222 //-- Intenals only below this point | |
223 private static Map fields = new HashMap(); | |
224 private static void addField(String name, int fieldId) { | |
225 fields.put(name, new Integer(fieldId)); | |
226 } | |
227 | |
228 private static int getFieldID(String name) { | |
229 Integer res = (Integer) fields.get(name); | |
230 return (res != null)? res.intValue() : FIELD_UNDEFINED; | |
231 } | |
232 | |
233 static { | |
234 addField("sourceFile", FIELD_SOURCE_FILE); | |
235 addField("interfaces", FIELD_INTERFACES); | |
236 addField("fields", FIELD_FIELDS); | |
237 addField("methods", FIELD_METHODS); | |
238 addField("isPrivate", FIELD_IS_PRIVATE); | |
239 addField("isPublic", FIELD_IS_PUBLIC); | |
240 addField("isProtected", FIELD_IS_PROTECTED); | |
241 addField("isPackagePrivate", FIELD_IS_PACKAGE_PRIVATE); | |
242 addField("isStatic", FIELD_IS_STATIC); | |
243 addField("isFinal", FIELD_IS_FINAL); | |
244 addField("isAbstract", FIELD_IS_ABSTRACT); | |
245 addField("isStrict", FIELD_IS_STRICT); | |
246 addField("isSynthetic", FIELD_IS_SYNTHETIC); | |
247 addField("isInterface", FIELD_IS_INTERFACE); | |
248 addField("classLoader", FIELD_CLASS_LOADER); | |
249 addField("protectionDomain", FIELD_PROTECTION_DOMAIN); | |
250 addField("signers", FIELD_SIGNERS); | |
251 addField("statics", FIELD_STATICS); | |
252 } | |
253 | |
254 private AccessFlags getAccessFlags() { | |
255 if (accFlags == null) { | |
256 accFlags = new AccessFlags(getInstanceKlass().computeModifierFlags()); | |
257 } | |
258 return accFlags; | |
259 } | |
260 | |
261 private Object getFieldValue(Field fld, String name, Oop oop) { | |
262 FieldType fd = fld.getFieldType(); | |
263 if (fd.isObject() || fd.isArray()) { | |
264 return factory.newJSJavaObject(((OopField)fld).getValue(oop)); | |
265 } else if (fd.isByte()) { | |
266 return new Byte(((ByteField)fld).getValue(oop)); | |
267 } else if (fd.isChar()) { | |
268 return new String(new char[] { ((CharField)fld).getValue(oop) }); | |
269 } else if (fd.isDouble()) { | |
270 return new Double(((DoubleField)fld).getValue(oop)); | |
271 } else if (fd.isFloat()) { | |
272 return new Float(((FloatField)fld).getValue(oop)); | |
273 } else if (fd.isInt()) { | |
274 return new Integer(((IntField)fld).getValue(oop)); | |
275 } else if (fd.isLong()) { | |
276 return new Long(((LongField)fld).getValue(oop)); | |
277 } else if (fd.isShort()) { | |
278 return new Short(((ShortField)fld).getValue(oop)); | |
279 } else if (fd.isBoolean()) { | |
280 return Boolean.valueOf(((BooleanField)fld).getValue(oop)); | |
281 } else { | |
282 if (Assert.ASSERTS_ENABLED) { | |
283 Assert.that(false, "invalid field type for " + name); | |
284 } | |
285 return null; | |
286 } | |
287 } | |
288 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
289 private Object getFieldValue(Field fld, String name, InstanceKlass oop) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
290 FieldType fd = fld.getFieldType(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
291 if (fd.isObject() || fd.isArray()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
292 return factory.newJSJavaObject(((OopField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
293 } else if (fd.isByte()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
294 return new Byte(((ByteField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
295 } else if (fd.isChar()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
296 return new String(new char[] { ((CharField)fld).getValue(oop) }); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
297 } else if (fd.isDouble()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
298 return new Double(((DoubleField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
299 } else if (fd.isFloat()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
300 return new Float(((FloatField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
301 } else if (fd.isInt()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
302 return new Integer(((IntField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
303 } else if (fd.isLong()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
304 return new Long(((LongField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
305 } else if (fd.isShort()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
306 return new Short(((ShortField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
307 } else if (fd.isBoolean()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
308 return Boolean.valueOf(((BooleanField)fld).getValue(oop)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
309 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
310 if (Assert.ASSERTS_ENABLED) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
311 Assert.that(false, "invalid field type for " + name); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
312 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
313 return null; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
314 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
315 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1552
diff
changeset
|
316 |
0 | 317 private Field findInstanceField(String name) { |
318 Field fld = (Field) instanceFields.get(name); | |
319 if (fld != null) { | |
320 return fld; | |
321 } else { | |
322 InstanceKlass current = getInstanceKlass(); | |
323 while (current != null) { | |
324 List tmp = current.getImmediateFields(); | |
325 for (Iterator itr = tmp.iterator(); itr.hasNext();) { | |
326 fld = (Field) itr.next(); | |
327 if (fld.getID().getName().equals(name) && !fld.isStatic()) { | |
328 instanceFields.put(name, fld); | |
329 return fld; | |
330 } | |
331 } | |
332 // lookup in super class. | |
333 current = (InstanceKlass) current.getSuper(); | |
334 } | |
335 } | |
336 // no match | |
337 return null; | |
338 } | |
339 | |
340 private Field findStaticField(String name) { | |
341 Field fld = (Field) staticFields.get(name); | |
342 if (fld != null) { | |
343 return fld; | |
344 } else { | |
345 // static fields are searched only in current. | |
346 // Direct/indirect super classes and interfaces | |
347 // are not included in search. | |
348 InstanceKlass current = getInstanceKlass(); | |
349 List tmp = current.getImmediateFields(); | |
350 for (Iterator itr = tmp.iterator(); itr.hasNext();) { | |
351 fld = (Field) itr.next(); | |
352 if (fld.getID().getName().equals(name) && fld.isStatic()) { | |
353 staticFields.put(name, fld); | |
354 return fld; | |
355 } | |
356 } | |
357 // no match | |
358 return null; | |
359 } | |
360 } | |
361 | |
362 private JSList getInterfaces() { | |
363 InstanceKlass ik = getInstanceKlass(); | |
364 List intfs = ik.getDirectImplementedInterfaces(); | |
365 List res = new ArrayList(0); | |
366 for (Iterator itr = intfs.iterator(); itr.hasNext();) { | |
367 Klass k = (Klass) itr.next(); | |
368 res.add(k.getJavaMirror()); | |
369 } | |
370 return factory.newJSList(res); | |
371 } | |
372 | |
373 private JSMap getStatics() { | |
374 String[] names = getStaticFieldNames(); | |
375 Map map = new HashMap(); | |
376 for (int i=0; i < names.length; i++) { | |
377 try { | |
378 map.put(names[i], getStaticFieldValue(names[i])); | |
379 } catch (NoSuchFieldException exp) {} | |
380 } | |
381 return factory.newJSMap(map); | |
382 } | |
383 | |
384 private Map instanceFields; | |
385 private Map staticFields; | |
386 private String[] instanceFieldNames; | |
387 private String[] staticFieldNames; | |
388 private AccessFlags accFlags; | |
389 } |