Mercurial > hg > truffle
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 |