comparison agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.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 b2dbd323c668
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
32 import sun.jvm.hotspot.memory.*; 32 import sun.jvm.hotspot.memory.*;
33 import sun.jvm.hotspot.runtime.*; 33 import sun.jvm.hotspot.runtime.*;
34 import sun.jvm.hotspot.types.*; 34 import sun.jvm.hotspot.types.*;
35 import sun.jvm.hotspot.utilities.*; 35 import sun.jvm.hotspot.utilities.*;
36 36
37 public class ConstMethod extends Oop { 37 public class ConstMethod extends VMObject {
38 static { 38 static {
39 VM.registerVMInitializedObserver(new Observer() { 39 VM.registerVMInitializedObserver(new Observer() {
40 public void update(Observable o, Object data) { 40 public void update(Observable o, Object data) {
41 initialize(VM.getVM().getTypeDataBase()); 41 initialize(VM.getVM().getTypeDataBase());
42 } 42 }
48 private static int HAS_CHECKED_EXCEPTIONS; 48 private static int HAS_CHECKED_EXCEPTIONS;
49 private static int HAS_LOCALVARIABLE_TABLE; 49 private static int HAS_LOCALVARIABLE_TABLE;
50 private static int HAS_EXCEPTION_TABLE; 50 private static int HAS_EXCEPTION_TABLE;
51 51
52 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { 52 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
53 Type type = db.lookupType("constMethodOopDesc"); 53 Type type = db.lookupType("ConstMethod");
54 constants = new OopField(type.getOopField("_constants"), 0); 54 constants = new MetadataField(type.getAddressField("_constants"), 0);
55 constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0); 55 constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
56 flags = new ByteField(type.getJByteField("_flags"), 0); 56 flags = new ByteField(type.getJByteField("_flags"), 0);
57 57
58 // enum constants for flags 58 // enum constants for flags
59 HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue(); 59 HAS_LINENUMBER_TABLE = db.lookupIntConstant("ConstMethod::_has_linenumber_table").intValue();
60 HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue(); 60 HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("ConstMethod::_has_checked_exceptions").intValue();
61 HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue(); 61 HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("ConstMethod::_has_localvariable_table").intValue();
62 HAS_EXCEPTION_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue(); 62 HAS_EXCEPTION_TABLE = db.lookupIntConstant("ConstMethod::_has_exception_table").intValue();
63 63
64 // Size of Java bytecodes allocated immediately after constMethodOop. 64 // Size of Java bytecodes allocated immediately after ConstMethod*.
65 codeSize = new CIntField(type.getCIntegerField("_code_size"), 0); 65 codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
66 nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0); 66 nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0);
67 signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0); 67 signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0);
68 genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"),0); 68 genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
69 idnum = new CIntField(type.getCIntegerField("_method_idnum"), 0); 69 idnum = new CIntField(type.getCIntegerField("_method_idnum"), 0);
79 79
80 type = db.lookupType("ExceptionTableElement"); 80 type = db.lookupType("ExceptionTableElement");
81 exceptionTableElementSize = type.getSize(); 81 exceptionTableElementSize = type.getSize();
82 } 82 }
83 83
84 ConstMethod(OopHandle handle, ObjectHeap heap) { 84 public ConstMethod(Address addr) {
85 super(handle, heap); 85 super(addr);
86 } 86 }
87 87
88 // Fields 88 // Fields
89 private static OopField constants; 89 private static MetadataField constants;
90 private static CIntField constMethodSize; 90 private static CIntField constMethodSize;
91 private static ByteField flags; 91 private static ByteField flags;
92 private static CIntField codeSize; 92 private static CIntField codeSize;
93 private static CIntField nameIndex; 93 private static CIntField nameIndex;
94 private static CIntField signatureIndex; 94 private static CIntField signatureIndex;
102 private static long localVariableTableElementSize; 102 private static long localVariableTableElementSize;
103 private static long exceptionTableElementSize; 103 private static long exceptionTableElementSize;
104 104
105 public Method getMethod() { 105 public Method getMethod() {
106 InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder(); 106 InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder();
107 ObjArray methods = ik.getMethods(); 107 MethodArray methods = ik.getMethods();
108 return (Method)methods.getObjAt(getIdNum()); 108 return methods.at((int)getIdNum());
109 } 109 }
110 110
111 // Accessors for declared fields 111 // Accessors for declared fields
112 public ConstantPool getConstants() { 112 public ConstantPool getConstants() {
113 return (ConstantPool) constants.getValue(this); 113 return (ConstantPool) constants.getValue(this);
155 155
156 // bytecode accessors 156 // bytecode accessors
157 157
158 /** Get a bytecode or breakpoint at the given bci */ 158 /** Get a bytecode or breakpoint at the given bci */
159 public int getBytecodeOrBPAt(int bci) { 159 public int getBytecodeOrBPAt(int bci) {
160 return getHandle().getJByteAt(bytecodeOffset + bci) & 0xFF; 160 return getAddress().getJByteAt(bytecodeOffset + bci) & 0xFF;
161 } 161 }
162 162
163 public byte getBytecodeByteArg(int bci) { 163 public byte getBytecodeByteArg(int bci) {
164 return (byte) getBytecodeOrBPAt(bci); 164 return (byte) getBytecodeOrBPAt(bci);
165 } 165 }
213 public byte[] getByteCode() { 213 public byte[] getByteCode() {
214 byte[] bc = new byte[ (int) getCodeSize() ]; 214 byte[] bc = new byte[ (int) getCodeSize() ];
215 for( int i=0; i < bc.length; i++ ) 215 for( int i=0; i < bc.length; i++ )
216 { 216 {
217 long offs = bytecodeOffset + i; 217 long offs = bytecodeOffset + i;
218 bc[i] = getHandle().getJByteAt( offs ); 218 bc[i] = getAddress().getJByteAt( offs );
219 } 219 }
220 return bc; 220 return bc;
221 } 221 }
222 222
223 public long getObjectSize() { 223 public long getSize() {
224 return getConstMethodSize() * getHeap().getOopSize(); 224 return getConstMethodSize();
225 } 225 }
226 226
227 public void printValueOn(PrintStream tty) { 227 public void printValueOn(PrintStream tty) {
228 tty.print("ConstMethod " + getName().asString() + getSignature().asString() + "@" + getHandle()); 228 tty.print("ConstMethod " + getName().asString() + getSignature().asString() + "@" + getAddress());
229 } 229 }
230 230
231 public void iterateFields(OopVisitor visitor, boolean doVMFields) { 231 public void iterateFields(MetadataVisitor visitor) {
232 super.iterateFields(visitor, doVMFields); 232 visitor.doMetadata(constants, true);
233 if (doVMFields) {
234 visitor.doOop(constants, true);
235 visitor.doCInt(constMethodSize, true); 233 visitor.doCInt(constMethodSize, true);
236 visitor.doByte(flags, true); 234 visitor.doByte(flags, true);
237 visitor.doCInt(codeSize, true); 235 visitor.doCInt(codeSize, true);
238 visitor.doCInt(nameIndex, true); 236 visitor.doCInt(nameIndex, true);
239 visitor.doCInt(signatureIndex, true); 237 visitor.doCInt(signatureIndex, true);
240 visitor.doCInt(genericSignatureIndex, true); 238 visitor.doCInt(genericSignatureIndex, true);
241 visitor.doCInt(codeSize, true); 239 visitor.doCInt(codeSize, true);
242 } 240 }
243 }
244 241
245 // Accessors 242 // Accessors
246 243
247 public boolean hasLineNumberTable() { 244 public boolean hasLineNumberTable() {
248 return (getFlags() & HAS_LINENUMBER_TABLE) != 0; 245 return (getFlags() & HAS_LINENUMBER_TABLE) != 0;
264 int bestLine = -1; 261 int bestLine = -1;
265 if (hasLineNumberTable()) { 262 if (hasLineNumberTable()) {
266 // The line numbers are a short array of 2-tuples [start_pc, line_number]. 263 // The line numbers are a short array of 2-tuples [start_pc, line_number].
267 // Not necessarily sorted and not necessarily one-to-one. 264 // Not necessarily sorted and not necessarily one-to-one.
268 CompressedLineNumberReadStream stream = 265 CompressedLineNumberReadStream stream =
269 new CompressedLineNumberReadStream(getHandle(), (int) offsetOfCompressedLineNumberTable()); 266 new CompressedLineNumberReadStream(getAddress(), (int) offsetOfCompressedLineNumberTable());
270 while (stream.readPair()) { 267 while (stream.readPair()) {
271 if (stream.bci() == bci) { 268 if (stream.bci() == bci) {
272 // perfect match 269 // perfect match
273 return stream.line(); 270 return stream.line();
274 } else { 271 } else {
288 Assert.that(hasLineNumberTable(), 285 Assert.that(hasLineNumberTable(),
289 "should only be called if table is present"); 286 "should only be called if table is present");
290 } 287 }
291 int len = getLineNumberTableLength(); 288 int len = getLineNumberTableLength();
292 CompressedLineNumberReadStream stream = 289 CompressedLineNumberReadStream stream =
293 new CompressedLineNumberReadStream(getHandle(), (int) offsetOfCompressedLineNumberTable()); 290 new CompressedLineNumberReadStream(getAddress(), (int) offsetOfCompressedLineNumberTable());
294 LineNumberTableElement[] ret = new LineNumberTableElement[len]; 291 LineNumberTableElement[] ret = new LineNumberTableElement[len];
295 292
296 for (int idx = 0; idx < len; idx++) { 293 for (int idx = 0; idx < len; idx++) {
297 stream.readPair(); 294 stream.readPair();
298 ret[idx] = new LineNumberTableElement(stream.bci(), stream.line()); 295 ret[idx] = new LineNumberTableElement(stream.bci(), stream.line());
314 Assert.that(hasLocalVariableTable(), "should only be called if table is present"); 311 Assert.that(hasLocalVariableTable(), "should only be called if table is present");
315 } 312 }
316 LocalVariableTableElement[] ret = new LocalVariableTableElement[getLocalVariableTableLength()]; 313 LocalVariableTableElement[] ret = new LocalVariableTableElement[getLocalVariableTableLength()];
317 long offset = offsetOfLocalVariableTable(); 314 long offset = offsetOfLocalVariableTable();
318 for (int i = 0; i < ret.length; i++) { 315 for (int i = 0; i < ret.length; i++) {
319 ret[i] = new LocalVariableTableElement(getHandle(), offset); 316 ret[i] = new LocalVariableTableElement(getAddress(), offset);
320 offset += localVariableTableElementSize; 317 offset += localVariableTableElementSize;
321 } 318 }
322 return ret; 319 return ret;
323 } 320 }
324 321
331 Assert.that(hasExceptionTable(), "should only be called if table is present"); 328 Assert.that(hasExceptionTable(), "should only be called if table is present");
332 } 329 }
333 ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()]; 330 ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
334 long offset = offsetOfExceptionTable(); 331 long offset = offsetOfExceptionTable();
335 for (int i = 0; i < ret.length; i++) { 332 for (int i = 0; i < ret.length; i++) {
336 ret[i] = new ExceptionTableElement(getHandle(), offset); 333 ret[i] = new ExceptionTableElement(getAddress(), offset);
337 offset += exceptionTableElementSize; 334 offset += exceptionTableElementSize;
338 } 335 }
339 return ret; 336 return ret;
340 } 337 }
341 338
348 Assert.that(hasCheckedExceptions(), "should only be called if table is present"); 345 Assert.that(hasCheckedExceptions(), "should only be called if table is present");
349 } 346 }
350 CheckedExceptionElement[] ret = new CheckedExceptionElement[getCheckedExceptionsLength()]; 347 CheckedExceptionElement[] ret = new CheckedExceptionElement[getCheckedExceptionsLength()];
351 long offset = offsetOfCheckedExceptions(); 348 long offset = offsetOfCheckedExceptions();
352 for (int i = 0; i < ret.length; i++) { 349 for (int i = 0; i < ret.length; i++) {
353 ret[i] = new CheckedExceptionElement(getHandle(), offset); 350 ret[i] = new CheckedExceptionElement(getAddress(), offset);
354 offset += checkedExceptionElementSize; 351 offset += checkedExceptionElementSize;
355 } 352 }
356 return ret; 353 return ret;
357 } 354 }
358 355
368 // Offset of end of code 365 // Offset of end of code
369 private long offsetOfCodeEnd() { 366 private long offsetOfCodeEnd() {
370 return bytecodeOffset + getCodeSize(); 367 return bytecodeOffset + getCodeSize();
371 } 368 }
372 369
373 // Offset of start of compressed line number table (see methodOop.hpp) 370 // Offset of start of compressed line number table (see method.hpp)
374 private long offsetOfCompressedLineNumberTable() { 371 private long offsetOfCompressedLineNumberTable() {
375 return offsetOfCodeEnd() + (isNative() ? 2 * VM.getVM().getAddressSize() : 0); 372 return offsetOfCodeEnd() + (isNative() ? 2 * VM.getVM().getAddressSize() : 0);
376 } 373 }
377 374
378 // Offset of last short in methodOop 375 // Offset of last short in Method*
379 private long offsetOfLastU2Element() { 376 private long offsetOfLastU2Element() {
380 return getObjectSize() - 2; 377 return getSize() * VM.getVM().getObjectHeap().getOopSize() - 2;
381 } 378 }
382 379
383 private long offsetOfCheckedExceptionsLength() { 380 private long offsetOfCheckedExceptionsLength() {
384 return offsetOfLastU2Element(); 381 return offsetOfLastU2Element();
385 } 382 }
386 383
387 private int getCheckedExceptionsLength() { 384 private int getCheckedExceptionsLength() {
388 if (hasCheckedExceptions()) { 385 if (hasCheckedExceptions()) {
389 return (int) getHandle().getCIntegerAt(offsetOfCheckedExceptionsLength(), 2, true); 386 return (int) getAddress().getCIntegerAt(offsetOfCheckedExceptionsLength(), 2, true);
390 } else { 387 } else {
391 return 0; 388 return 0;
392 } 389 }
393 } 390 }
394 391
405 402
406 private int getLineNumberTableLength() { 403 private int getLineNumberTableLength() {
407 int len = 0; 404 int len = 0;
408 if (hasLineNumberTable()) { 405 if (hasLineNumberTable()) {
409 CompressedLineNumberReadStream stream = 406 CompressedLineNumberReadStream stream =
410 new CompressedLineNumberReadStream(getHandle(), (int) offsetOfCompressedLineNumberTable()); 407 new CompressedLineNumberReadStream(getAddress(), (int) offsetOfCompressedLineNumberTable());
411 while (stream.readPair()) { 408 while (stream.readPair()) {
412 len += 1; 409 len += 1;
413 } 410 }
414 } 411 }
415 return len; 412 return len;
416 } 413 }
417 414
418 private int getLocalVariableTableLength() { 415 private int getLocalVariableTableLength() {
419 if (hasLocalVariableTable()) { 416 if (hasLocalVariableTable()) {
420 return (int) getHandle().getCIntegerAt(offsetOfLocalVariableTableLength(), 2, true); 417 return (int) getAddress().getCIntegerAt(offsetOfLocalVariableTableLength(), 2, true);
421 } else { 418 } else {
422 return 0; 419 return 0;
423 } 420 }
424 } 421 }
425 422
448 return offset; 445 return offset;
449 } 446 }
450 447
451 private int getExceptionTableLength() { 448 private int getExceptionTableLength() {
452 if (hasExceptionTable()) { 449 if (hasExceptionTable()) {
453 return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true); 450 return (int) getAddress().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
454 } else { 451 } else {
455 return 0; 452 return 0;
456 } 453 }
457 } 454 }
458 455