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 }