comparison agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java @ 6213:8150fa46d2ed

7178145: Change constMethodOop::_exception_table to optionally inlined u2 table. Summary: Change constMethodOop::_exception_table to optionally inlined u2 table. Reviewed-by: bdelsart, coleenp, kamg
author jiangli
date Tue, 26 Jun 2012 19:08:44 -0400
parents 2fe087c3e814
children da91efe96a93
comparison
equal deleted inserted replaced
6177:06320b1578cb 6213:8150fa46d2ed
45 45
46 // anon-enum constants for _flags. 46 // anon-enum constants for _flags.
47 private static int HAS_LINENUMBER_TABLE; 47 private static int HAS_LINENUMBER_TABLE;
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 51
51 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { 52 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
52 Type type = db.lookupType("constMethodOopDesc"); 53 Type type = db.lookupType("constMethodOopDesc");
53 constants = new OopField(type.getOopField("_constants"), 0); 54 constants = new OopField(type.getOopField("_constants"), 0);
54 // The exception handler table. 4-tuples of ints [start_pc, end_pc,
55 // handler_pc, catch_type index] For methods with no exceptions the
56 // table is pointing to Universe::the_empty_int_array
57 exceptionTable = new OopField(type.getOopField("_exception_table"), 0);
58 constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0); 55 constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
59 flags = new ByteField(type.getJByteField("_flags"), 0); 56 flags = new ByteField(type.getJByteField("_flags"), 0);
60 57
61 // enum constants for flags 58 // enum constants for flags
62 HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue(); 59 HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
63 HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue(); 60 HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
64 HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue(); 61 HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
62 HAS_EXCEPTION_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue();
65 63
66 // Size of Java bytecodes allocated immediately after constMethodOop. 64 // Size of Java bytecodes allocated immediately after constMethodOop.
67 codeSize = new CIntField(type.getCIntegerField("_code_size"), 0); 65 codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
68 nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0); 66 nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0);
69 signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0); 67 signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0);
76 type = db.lookupType("CheckedExceptionElement"); 74 type = db.lookupType("CheckedExceptionElement");
77 checkedExceptionElementSize = type.getSize(); 75 checkedExceptionElementSize = type.getSize();
78 76
79 type = db.lookupType("LocalVariableTableElement"); 77 type = db.lookupType("LocalVariableTableElement");
80 localVariableTableElementSize = type.getSize(); 78 localVariableTableElementSize = type.getSize();
79
80 type = db.lookupType("ExceptionTableElement");
81 exceptionTableElementSize = type.getSize();
81 } 82 }
82 83
83 ConstMethod(OopHandle handle, ObjectHeap heap) { 84 ConstMethod(OopHandle handle, ObjectHeap heap) {
84 super(handle, heap); 85 super(handle, heap);
85 } 86 }
86 87
87 // Fields 88 // Fields
88 private static OopField constants; 89 private static OopField constants;
89 private static OopField exceptionTable;
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;
98 // start of bytecode 98 // start of bytecode
99 private static long bytecodeOffset; 99 private static long bytecodeOffset;
100 100
101 private static long checkedExceptionElementSize; 101 private static long checkedExceptionElementSize;
102 private static long localVariableTableElementSize; 102 private static long localVariableTableElementSize;
103 private static long exceptionTableElementSize;
103 104
104 public Method getMethod() { 105 public Method getMethod() {
105 InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder(); 106 InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder();
106 ObjArray methods = ik.getMethods(); 107 ObjArray methods = ik.getMethods();
107 return (Method)methods.getObjAt(getIdNum()); 108 return (Method)methods.getObjAt(getIdNum());
108 } 109 }
109 110
110 // Accessors for declared fields 111 // Accessors for declared fields
111 public ConstantPool getConstants() { 112 public ConstantPool getConstants() {
112 return (ConstantPool) constants.getValue(this); 113 return (ConstantPool) constants.getValue(this);
113 }
114
115 public TypeArray getExceptionTable() {
116 return (TypeArray) exceptionTable.getValue(this);
117 } 114 }
118 115
119 public long getConstMethodSize() { 116 public long getConstMethodSize() {
120 return constMethodSize.getValue(this); 117 return constMethodSize.getValue(this);
121 } 118 }
233 230
234 public void iterateFields(OopVisitor visitor, boolean doVMFields) { 231 public void iterateFields(OopVisitor visitor, boolean doVMFields) {
235 super.iterateFields(visitor, doVMFields); 232 super.iterateFields(visitor, doVMFields);
236 if (doVMFields) { 233 if (doVMFields) {
237 visitor.doOop(constants, true); 234 visitor.doOop(constants, true);
238 visitor.doOop(exceptionTable, true);
239 visitor.doCInt(constMethodSize, true); 235 visitor.doCInt(constMethodSize, true);
240 visitor.doByte(flags, true); 236 visitor.doByte(flags, true);
241 visitor.doCInt(codeSize, true); 237 visitor.doCInt(codeSize, true);
242 visitor.doCInt(nameIndex, true); 238 visitor.doCInt(nameIndex, true);
243 visitor.doCInt(signatureIndex, true); 239 visitor.doCInt(signatureIndex, true);
324 offset += localVariableTableElementSize; 320 offset += localVariableTableElementSize;
325 } 321 }
326 return ret; 322 return ret;
327 } 323 }
328 324
325 public boolean hasExceptionTable() {
326 return (getFlags() & HAS_EXCEPTION_TABLE) != 0;
327 }
328
329 public ExceptionTableElement[] getExceptionTable() {
330 if (Assert.ASSERTS_ENABLED) {
331 Assert.that(hasExceptionTable(), "should only be called if table is present");
332 }
333 ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
334 long offset = offsetOfExceptionTable();
335 for (int i = 0; i < ret.length; i++) {
336 ret[i] = new ExceptionTableElement(getHandle(), offset);
337 offset += exceptionTableElementSize;
338 }
339 return ret;
340 }
341
329 public boolean hasCheckedExceptions() { 342 public boolean hasCheckedExceptions() {
330 return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0; 343 return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
331 } 344 }
332 345
333 public CheckedExceptionElement[] getCheckedExceptions() { 346 public CheckedExceptionElement[] getCheckedExceptions() {
413 // Offset of local variable table length 426 // Offset of local variable table length
414 private long offsetOfLocalVariableTableLength() { 427 private long offsetOfLocalVariableTableLength() {
415 if (Assert.ASSERTS_ENABLED) { 428 if (Assert.ASSERTS_ENABLED) {
416 Assert.that(hasLocalVariableTable(), "should only be called if table is present"); 429 Assert.that(hasLocalVariableTable(), "should only be called if table is present");
417 } 430 }
418 if (hasCheckedExceptions()) { 431
432 if (hasExceptionTable()) {
433 return offsetOfExceptionTable() - 2;
434 } else if (hasCheckedExceptions()) {
419 return offsetOfCheckedExceptions() - 2; 435 return offsetOfCheckedExceptions() - 2;
420 } else { 436 } else {
421 return offsetOfLastU2Element(); 437 return offsetOfLastU2Element();
422 } 438 }
423 } 439 }
430 } 446 }
431 offset -= length * localVariableTableElementSize; 447 offset -= length * localVariableTableElementSize;
432 return offset; 448 return offset;
433 } 449 }
434 450
451 private int getExceptionTableLength() {
452 if (hasExceptionTable()) {
453 return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
454 } else {
455 return 0;
456 }
457 }
458
459 private long offsetOfExceptionTableLength() {
460 if (Assert.ASSERTS_ENABLED) {
461 Assert.that(hasExceptionTable(), "should only be called if table is present");
462 }
463 if (hasCheckedExceptions()) {
464 return offsetOfCheckedExceptions() - 2;
465 } else {
466 return offsetOfLastU2Element();
467 }
468 }
469
470 private long offsetOfExceptionTable() {
471 long offset = offsetOfExceptionTableLength();
472 long length = getExceptionTableLength();
473 if (Assert.ASSERTS_ENABLED) {
474 Assert.that(length > 0, "should only be called if table is present");
475 }
476 offset -= length * exceptionTableElementSize;
477 return offset;
478 }
479
435 } 480 }