Mercurial > hg > graal-jvmci-8
comparison agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.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 | 8150fa46d2ed |
children | 7a40901e0d5c |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
26 | 26 |
27 import java.io.*; | 27 import java.io.*; |
28 import java.util.*; | 28 import java.util.*; |
29 import sun.jvm.hotspot.oops.*; | 29 import sun.jvm.hotspot.oops.*; |
30 import sun.jvm.hotspot.runtime.*; | 30 import sun.jvm.hotspot.runtime.*; |
31 import sun.jvm.hotspot.utilities.*; | |
31 | 32 |
32 public class ClassWriter implements /* imports */ ClassConstants | 33 public class ClassWriter implements /* imports */ ClassConstants |
33 { | 34 { |
34 public static final boolean DEBUG = false; | 35 public static final boolean DEBUG = false; |
35 | 36 |
40 protected InstanceKlass klass; | 41 protected InstanceKlass klass; |
41 protected DataOutputStream dos; | 42 protected DataOutputStream dos; |
42 protected ConstantPool cpool; | 43 protected ConstantPool cpool; |
43 | 44 |
44 // Map between class name to index of type CONSTANT_Class | 45 // Map between class name to index of type CONSTANT_Class |
45 protected Map classToIndex = new HashMap(); | 46 protected Map<String, Short> classToIndex = new HashMap<String, Short>(); |
46 | 47 |
47 // Map between any modified UTF-8 and it's constant pool index. | 48 // Map between any modified UTF-8 and it's constant pool index. |
48 protected Map utf8ToIndex = new HashMap(); | 49 protected Map<String, Short> utf8ToIndex = new HashMap<String, Short>(); |
49 | 50 |
50 // constant pool index for attribute names. | 51 // constant pool index for attribute names. |
51 | 52 |
52 protected short _sourceFileIndex; | 53 protected short _sourceFileIndex; |
53 protected short _innerClassesIndex; | 54 protected short _innerClassesIndex; |
59 protected short _lineNumberTableIndex; | 60 protected short _lineNumberTableIndex; |
60 protected short _localVariableTableIndex; | 61 protected short _localVariableTableIndex; |
61 protected short _signatureIndex; | 62 protected short _signatureIndex; |
62 | 63 |
63 protected static int extractHighShortFromInt(int val) { | 64 protected static int extractHighShortFromInt(int val) { |
64 // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. | 65 // must stay in sync with ConstantPool::name_and_type_at_put, method_at_put, etc. |
65 return (val >> 16) & 0xFFFF; | 66 return (val >> 16) & 0xFFFF; |
66 } | 67 } |
67 | 68 |
68 protected static int extractLowShortFromInt(int val) { | 69 protected static int extractLowShortFromInt(int val) { |
69 // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. | 70 // must stay in sync with ConstantPool::name_and_type_at_put, method_at_put, etc. |
70 return val & 0xFFFF; | 71 return val & 0xFFFF; |
71 } | 72 } |
72 | 73 |
73 public ClassWriter(InstanceKlass kls, OutputStream os) { | 74 public ClassWriter(InstanceKlass kls, OutputStream os) { |
74 klass = kls; | 75 klass = kls; |
105 if (index == 0) throw new InternalError(); | 106 if (index == 0) throw new InternalError(); |
106 dos.writeShort(index); | 107 dos.writeShort(index); |
107 } | 108 } |
108 | 109 |
109 protected void writeConstantPool() throws IOException { | 110 protected void writeConstantPool() throws IOException { |
110 final TypeArray tags = cpool.getTags(); | 111 final U1Array tags = cpool.getTags(); |
111 final long len = tags.getLength(); | 112 final long len = tags.length(); |
112 dos.writeShort((short) len); | 113 dos.writeShort((short) len); |
113 | 114 |
114 if (DEBUG) debugMessage("constant pool length = " + len); | 115 if (DEBUG) debugMessage("constant pool length = " + len); |
115 | 116 |
116 int ci = 0; // constant pool index | 117 int ci = 0; // constant pool index |
117 | 118 |
118 // collect all modified UTF-8 Strings from Constant Pool | 119 // collect all modified UTF-8 Strings from Constant Pool |
119 | 120 |
120 for (ci = 1; ci < len; ci++) { | 121 for (ci = 1; ci < len; ci++) { |
121 byte cpConstType = tags.getByteAt(ci); | 122 int cpConstType = tags.at(ci); |
122 if(cpConstType == JVM_CONSTANT_Utf8) { | 123 if(cpConstType == JVM_CONSTANT_Utf8) { |
123 Symbol sym = cpool.getSymbolAt(ci); | 124 Symbol sym = cpool.getSymbolAt(ci); |
124 utf8ToIndex.put(sym.asString(), new Short((short) ci)); | 125 utf8ToIndex.put(sym.asString(), new Short((short) ci)); |
125 } | 126 } |
126 else if(cpConstType == JVM_CONSTANT_Long || | 127 else if(cpConstType == JVM_CONSTANT_Long || |
180 Short signatureIdx = (Short) utf8ToIndex.get("Signature"); | 181 Short signatureIdx = (Short) utf8ToIndex.get("Signature"); |
181 _signatureIndex = (signatureIdx != null)? signatureIdx.shortValue() : 0; | 182 _signatureIndex = (signatureIdx != null)? signatureIdx.shortValue() : 0; |
182 if (DEBUG) debugMessage("Signature index = " + _signatureIndex); | 183 if (DEBUG) debugMessage("Signature index = " + _signatureIndex); |
183 | 184 |
184 for(ci = 1; ci < len; ci++) { | 185 for(ci = 1; ci < len; ci++) { |
186 int cpConstType = tags.at(ci); | |
185 // write cp_info | 187 // write cp_info |
186 // write constant type | 188 // write constant type |
187 byte cpConstType = tags.getByteAt(ci); | |
188 switch(cpConstType) { | 189 switch(cpConstType) { |
189 case JVM_CONSTANT_Utf8: { | 190 case JVM_CONSTANT_Utf8: { |
190 dos.writeByte(cpConstType); | 191 dos.writeByte(cpConstType); |
191 Symbol sym = cpool.getSymbolAt(ci); | 192 Symbol sym = cpool.getSymbolAt(ci); |
192 dos.writeShort((short)sym.getLength()); | 193 dos.writeShort((short)sym.getLength()); |
224 dos.writeDouble(cpool.getDoubleAt(ci)); | 225 dos.writeDouble(cpool.getDoubleAt(ci)); |
225 // double entries occupy two pool entries | 226 // double entries occupy two pool entries |
226 ci++; | 227 ci++; |
227 break; | 228 break; |
228 | 229 |
229 case JVM_CONSTANT_Class: { | 230 case JVM_CONSTANT_Class: |
230 dos.writeByte(cpConstType); | 231 case JVM_CONSTANT_UnresolvedClass: |
231 // Klass already resolved. ConstantPool constains klassOop. | 232 case JVM_CONSTANT_UnresolvedClassInError: { |
232 Klass refKls = (Klass) cpool.getObjAtRaw(ci); | 233 dos.writeByte(JVM_CONSTANT_Class); |
233 String klassName = refKls.getName().asString(); | 234 String klassName = cpool.getKlassNameAt(ci).asString(); |
234 | |
235 Short s = (Short) utf8ToIndex.get(klassName); | 235 Short s = (Short) utf8ToIndex.get(klassName); |
236 classToIndex.put(klassName, new Short((short)ci)); | 236 classToIndex.put(klassName, new Short((short)ci)); |
237 dos.writeShort(s.shortValue()); | 237 dos.writeShort(s.shortValue()); |
238 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s); | 238 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s); |
239 break; | 239 break; |
240 } | 240 } |
241 | 241 |
242 // case JVM_CONSTANT_ClassIndex: | |
243 case JVM_CONSTANT_UnresolvedClassInError: | |
244 case JVM_CONSTANT_UnresolvedClass: { | |
245 dos.writeByte(JVM_CONSTANT_Class); | |
246 String klassName = cpool.getSymbolAt(ci).asString(); | |
247 | |
248 Short s = (Short) utf8ToIndex.get(klassName); | |
249 classToIndex.put(klassName, new Short((short) ci)); | |
250 | |
251 dos.writeShort(s.shortValue()); | |
252 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s); | |
253 break; | |
254 } | |
255 | |
256 case JVM_CONSTANT_String: { | 242 case JVM_CONSTANT_String: { |
257 dos.writeByte(cpConstType); | 243 dos.writeByte(cpConstType); |
258 String str = OopUtilities.stringOopToString(cpool.getObjAtRaw(ci)); | 244 String str = cpool.getUnresolvedStringAt(ci).asString(); |
259 Short s = (Short) utf8ToIndex.get(str); | 245 Short s = (Short) utf8ToIndex.get(str); |
260 dos.writeShort(s.shortValue()); | |
261 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); | |
262 break; | |
263 } | |
264 | |
265 // case JVM_CONSTANT_StringIndex: | |
266 case JVM_CONSTANT_UnresolvedString: { | |
267 dos.writeByte(JVM_CONSTANT_String); | |
268 String val = cpool.getSymbolAt(ci).asString(); | |
269 | |
270 Short s = (Short) utf8ToIndex.get(val); | |
271 dos.writeShort(s.shortValue()); | 246 dos.writeShort(s.shortValue()); |
272 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); | 247 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); |
273 break; | 248 break; |
274 } | 249 } |
275 | 250 |
361 } else { | 336 } else { |
362 dos.writeShort(0); // no super class | 337 dos.writeShort(0); // no super class |
363 } | 338 } |
364 } | 339 } |
365 protected void writeInterfaces() throws IOException { | 340 protected void writeInterfaces() throws IOException { |
366 ObjArray interfaces = klass.getLocalInterfaces(); | 341 KlassArray interfaces = klass.getLocalInterfaces(); |
367 final int len = (int) interfaces.getLength(); | 342 final int len = interfaces.length(); |
368 | 343 |
369 if (DEBUG) debugMessage("number of interfaces = " + len); | 344 if (DEBUG) debugMessage("number of interfaces = " + len); |
370 | 345 |
371 // write interfaces count | 346 // write interfaces count |
372 dos.writeShort((short) len); | 347 dos.writeShort((short) len); |
373 for (int i = 0; i < len; i++) { | 348 for (int i = 0; i < len; i++) { |
374 Klass k = (Klass) interfaces.getObjAt(i); | 349 Klass k = interfaces.getAt(i); |
375 Short index = (Short) classToIndex.get(k.getName().asString()); | 350 Short index = (Short) classToIndex.get(k.getName().asString()); |
376 dos.writeShort(index.shortValue()); | 351 dos.writeShort(index.shortValue()); |
377 if (DEBUG) debugMessage("\t" + index); | 352 if (DEBUG) debugMessage("\t" + index); |
378 } | 353 } |
379 } | 354 } |
380 | 355 |
381 protected void writeFields() throws IOException { | 356 protected void writeFields() throws IOException { |
382 final int length = klass.getJavaFieldsCount(); | 357 U2Array fields = klass.getFields(); |
358 final int length = (int) fields.length(); | |
383 | 359 |
384 // write number of fields | 360 // write number of fields |
385 dos.writeShort((short) length); | 361 dos.writeShort((short) length); |
386 | 362 |
387 if (DEBUG) debugMessage("number of fields = " + length); | 363 if (DEBUG) debugMessage("number of fields = " + length); |
445 writeIndex(_syntheticIndex); | 421 writeIndex(_syntheticIndex); |
446 dos.writeInt(0); | 422 dos.writeInt(0); |
447 } | 423 } |
448 | 424 |
449 protected void writeMethods() throws IOException { | 425 protected void writeMethods() throws IOException { |
450 ObjArray methods = klass.getMethods(); | 426 MethodArray methods = klass.getMethods(); |
451 final int len = (int) methods.getLength(); | 427 final int len = methods.length(); |
452 // write number of methods | 428 // write number of methods |
453 dos.writeShort((short) len); | 429 dos.writeShort((short) len); |
454 if (DEBUG) debugMessage("number of methods = " + len); | 430 if (DEBUG) debugMessage("number of methods = " + len); |
455 for (int m = 0; m < len; m++) { | 431 for (int m = 0; m < len; m++) { |
456 writeMethod((Method) methods.getObjAt(m)); | 432 writeMethod(methods.at(m)); |
457 } | 433 } |
458 } | 434 } |
459 | 435 |
460 protected void writeMethod(Method m) throws IOException { | 436 protected void writeMethod(Method m) throws IOException { |
461 long accessFlags = m.getAccessFlags(); | 437 long accessFlags = m.getAccessFlags(); |
681 | 657 |
682 Symbol genericSignature = klass.getGenericSignature(); | 658 Symbol genericSignature = klass.getGenericSignature(); |
683 if (genericSignature != null) | 659 if (genericSignature != null) |
684 classAttributeCount++; | 660 classAttributeCount++; |
685 | 661 |
686 TypeArray innerClasses = klass.getInnerClasses(); | 662 U2Array innerClasses = klass.getInnerClasses(); |
687 final int numInnerClasses = (int) (innerClasses.getLength() / 4); | 663 final int numInnerClasses = (int) (innerClasses.length() / 4); |
688 if (numInnerClasses != 0) | 664 if (numInnerClasses != 0) |
689 classAttributeCount++; | 665 classAttributeCount++; |
690 | 666 |
691 dos.writeShort(classAttributeCount); | 667 dos.writeShort(classAttributeCount); |
692 if (DEBUG) debugMessage("class attribute count = " + classAttributeCount); | 668 if (DEBUG) debugMessage("class attribute count = " + classAttributeCount); |
722 | 698 |
723 dos.writeShort(numInnerClasses); | 699 dos.writeShort(numInnerClasses); |
724 if (DEBUG) debugMessage("class has " + numInnerClasses + " inner class entries"); | 700 if (DEBUG) debugMessage("class has " + numInnerClasses + " inner class entries"); |
725 | 701 |
726 for (int index = 0; index < numInnerClasses * 4; index++) { | 702 for (int index = 0; index < numInnerClasses * 4; index++) { |
727 dos.writeShort(innerClasses.getShortAt(index)); | 703 dos.writeShort(innerClasses.at(index)); |
728 } | 704 } |
729 } | 705 } |
730 } | 706 } |
731 } | 707 } |