agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java

Print this page


   1 /*
   2  * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  30 import sun.jvm.hotspot.debugger.*;
  31 import sun.jvm.hotspot.interpreter.*;
  32 import sun.jvm.hotspot.memory.*;
  33 import sun.jvm.hotspot.runtime.*;
  34 import sun.jvm.hotspot.types.*;
  35 import sun.jvm.hotspot.utilities.*;
  36 
  37 public class ConstMethod extends Oop {
  38   static {
  39     VM.registerVMInitializedObserver(new Observer() {
  40         public void update(Observable o, Object data) {
  41           initialize(VM.getVM().getTypeDataBase());
  42         }
  43       });
  44   }
  45 
  46   // anon-enum constants for _flags.
  47   private static int HAS_LINENUMBER_TABLE;
  48   private static int HAS_CHECKED_EXCEPTIONS;
  49   private static int HAS_LOCALVARIABLE_TABLE;

  50 
  51   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
  52     Type type                  = db.lookupType("constMethodOopDesc");
  53     // Backpointer to non-const methodOop
  54     method                     = new OopField(type.getOopField("_method"), 0);
  55     // The exception handler table. 4-tuples of ints [start_pc, end_pc,
  56     // handler_pc, catch_type index] For methods with no exceptions the
  57     // table is pointing to Universe::the_empty_int_array
  58     exceptionTable             = new OopField(type.getOopField("_exception_table"), 0);
  59     constMethodSize            = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
  60     flags                      = new ByteField(type.getJByteField("_flags"), 0);
  61 
  62     // enum constants for flags
  63     HAS_LINENUMBER_TABLE      = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
  64     HAS_CHECKED_EXCEPTIONS     = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
  65     HAS_LOCALVARIABLE_TABLE   = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();

  66 
  67     // Size of Java bytecodes allocated immediately after constMethodOop.
  68     codeSize                   = new CIntField(type.getCIntegerField("_code_size"), 0);
  69     nameIndex                  = new CIntField(type.getCIntegerField("_name_index"), 0);
  70     signatureIndex             = new CIntField(type.getCIntegerField("_signature_index"), 0);
  71     genericSignatureIndex      = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
  72 
  73     // start of byte code
  74     bytecodeOffset = type.getSize();
  75 
  76     type                       = db.lookupType("CheckedExceptionElement");
  77     checkedExceptionElementSize = type.getSize();
  78 
  79     type                       = db.lookupType("LocalVariableTableElement");
  80     localVariableTableElementSize = type.getSize();



  81   }
  82 
  83   ConstMethod(OopHandle handle, ObjectHeap heap) {
  84     super(handle, heap);
  85   }
  86 
  87   // Fields
  88   private static OopField  method;
  89   private static OopField  exceptionTable;
  90   private static CIntField constMethodSize;
  91   private static ByteField flags;
  92   private static CIntField codeSize;
  93   private static CIntField nameIndex;
  94   private static CIntField signatureIndex;
  95   private static CIntField genericSignatureIndex;
  96 
  97   // start of bytecode
  98   private static long bytecodeOffset;
  99 
 100   private static long checkedExceptionElementSize;
 101   private static long localVariableTableElementSize;

 102 
 103   // Accessors for declared fields
 104   public Method getMethod() {
 105     return (Method) method.getValue(this);
 106   }
 107 
 108   public TypeArray getExceptionTable() {
 109     return (TypeArray) exceptionTable.getValue(this);
 110   }
 111 
 112   public long getConstMethodSize() {
 113     return constMethodSize.getValue(this);
 114   }
 115 
 116   public byte getFlags() {
 117     return flags.getValue(this);
 118   }
 119 
 120   public long getCodeSize() {
 121     return codeSize.getValue(this);
 122   }
 123 
 124   public long getNameIndex() {
 125     return nameIndex.getValue(this);
 126   }
 127 
 128   public long getSignatureIndex() {
 129     return signatureIndex.getValue(this);
 130   }
 131 


 207      for( int i=0; i < bc.length; i++ )
 208      {
 209         long offs = bytecodeOffset + i;
 210         bc[i] = getHandle().getJByteAt( offs );
 211      }
 212      return bc;
 213   }
 214 
 215   public long getObjectSize() {
 216     return getConstMethodSize() * getHeap().getOopSize();
 217   }
 218 
 219   public void printValueOn(PrintStream tty) {
 220     tty.print("ConstMethod " + getName().asString() + getSignature().asString() + "@" + getHandle());
 221   }
 222 
 223   public void iterateFields(OopVisitor visitor, boolean doVMFields) {
 224     super.iterateFields(visitor, doVMFields);
 225     if (doVMFields) {
 226       visitor.doOop(method, true);
 227       visitor.doOop(exceptionTable, true);
 228       visitor.doCInt(constMethodSize, true);
 229       visitor.doByte(flags, true);
 230       visitor.doCInt(codeSize, true);
 231       visitor.doCInt(nameIndex, true);
 232       visitor.doCInt(signatureIndex, true);
 233       visitor.doCInt(genericSignatureIndex, true);
 234       visitor.doCInt(codeSize, true);
 235     }
 236   }
 237 
 238   // Accessors
 239 
 240   public boolean hasLineNumberTable() {
 241     return (getFlags() & HAS_LINENUMBER_TABLE) != 0;
 242   }
 243 
 244   public int getLineNumberFromBCI(int bci) {
 245     if (!VM.getVM().isCore()) {
 246       if (bci == DebugInformationRecorder.SYNCHRONIZATION_ENTRY_BCI) bci = 0;
 247     }


 298   }
 299 
 300   public Symbol getLocalVariableName(int bci, int slot) {
 301     return getMethod().getLocalVariableName(bci, slot);
 302   }
 303 
 304   /** Should only be called if table is present */
 305   public LocalVariableTableElement[] getLocalVariableTable() {
 306     if (Assert.ASSERTS_ENABLED) {
 307       Assert.that(hasLocalVariableTable(), "should only be called if table is present");
 308     }
 309     LocalVariableTableElement[] ret = new LocalVariableTableElement[getLocalVariableTableLength()];
 310     long offset = offsetOfLocalVariableTable();
 311     for (int i = 0; i < ret.length; i++) {
 312       ret[i] = new LocalVariableTableElement(getHandle(), offset);
 313       offset += localVariableTableElementSize;
 314     }
 315     return ret;
 316   }
 317 

















 318   public boolean hasCheckedExceptions() {
 319     return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
 320   }
 321 
 322   public CheckedExceptionElement[] getCheckedExceptions() {
 323     if (Assert.ASSERTS_ENABLED) {
 324       Assert.that(hasCheckedExceptions(), "should only be called if table is present");
 325     }
 326     CheckedExceptionElement[] ret = new CheckedExceptionElement[getCheckedExceptionsLength()];
 327     long offset = offsetOfCheckedExceptions();
 328     for (int i = 0; i < ret.length; i++) {
 329       ret[i] = new CheckedExceptionElement(getHandle(), offset);
 330       offset += checkedExceptionElementSize;
 331     }
 332     return ret;
 333   }
 334 
 335 
 336   //---------------------------------------------------------------------------
 337   // Internals only below this point


 387       while (stream.readPair()) {
 388         len += 1;
 389       }
 390     }
 391     return len;
 392   }
 393 
 394   private int getLocalVariableTableLength() {
 395     if (hasLocalVariableTable()) {
 396       return (int) getHandle().getCIntegerAt(offsetOfLocalVariableTableLength(), 2, true);
 397     } else {
 398       return 0;
 399     }
 400   }
 401 
 402   // Offset of local variable table length
 403   private long offsetOfLocalVariableTableLength() {
 404     if (Assert.ASSERTS_ENABLED) {
 405       Assert.that(hasLocalVariableTable(), "should only be called if table is present");
 406     }
 407     if (hasCheckedExceptions()) {



 408       return offsetOfCheckedExceptions() - 2;
 409     } else {
 410       return offsetOfLastU2Element();
 411     }
 412   }
 413 
 414   private long offsetOfLocalVariableTable() {
 415     long offset = offsetOfLocalVariableTableLength();
 416     long length = getLocalVariableTableLength();
 417     if (Assert.ASSERTS_ENABLED) {
 418       Assert.that(length > 0, "should only be called if table is present");
 419     }
 420     offset -= length * localVariableTableElementSize;
 421     return offset;
 422   }
 423 





























 424 }
   1 /*
   2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  30 import sun.jvm.hotspot.debugger.*;
  31 import sun.jvm.hotspot.interpreter.*;
  32 import sun.jvm.hotspot.memory.*;
  33 import sun.jvm.hotspot.runtime.*;
  34 import sun.jvm.hotspot.types.*;
  35 import sun.jvm.hotspot.utilities.*;
  36 
  37 public class ConstMethod extends Oop {
  38   static {
  39     VM.registerVMInitializedObserver(new Observer() {
  40         public void update(Observable o, Object data) {
  41           initialize(VM.getVM().getTypeDataBase());
  42         }
  43       });
  44   }
  45 
  46   // anon-enum constants for _flags.
  47   private static int HAS_LINENUMBER_TABLE;
  48   private static int HAS_CHECKED_EXCEPTIONS;
  49   private static int HAS_LOCALVARIABLE_TABLE;
  50   private static int HAS_EXCEPTION_TABLE;
  51 
  52   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
  53     Type type                  = db.lookupType("constMethodOopDesc");
  54     // Backpointer to non-const methodOop
  55     method                     = new OopField(type.getOopField("_method"), 0);




  56     constMethodSize            = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
  57     flags                      = new ByteField(type.getJByteField("_flags"), 0);
  58 
  59     // enum constants for flags
  60     HAS_LINENUMBER_TABLE      = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
  61     HAS_CHECKED_EXCEPTIONS     = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
  62     HAS_LOCALVARIABLE_TABLE   = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
  63     HAS_EXCEPTION_TABLE       = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue();
  64 
  65     // Size of Java bytecodes allocated immediately after constMethodOop.
  66     codeSize                   = new CIntField(type.getCIntegerField("_code_size"), 0);
  67     nameIndex                  = new CIntField(type.getCIntegerField("_name_index"), 0);
  68     signatureIndex             = new CIntField(type.getCIntegerField("_signature_index"), 0);
  69     genericSignatureIndex      = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
  70 
  71     // start of byte code
  72     bytecodeOffset = type.getSize();
  73 
  74     type                       = db.lookupType("CheckedExceptionElement");
  75     checkedExceptionElementSize = type.getSize();
  76 
  77     type                       = db.lookupType("LocalVariableTableElement");
  78     localVariableTableElementSize = type.getSize();
  79 
  80     type                       = db.lookupType("ExceptionTableElement");
  81     exceptionTableElementSize = type.getSize();
  82   }
  83 
  84   ConstMethod(OopHandle handle, ObjectHeap heap) {
  85     super(handle, heap);
  86   }
  87 
  88   // Fields
  89   private static OopField  method;

  90   private static CIntField constMethodSize;
  91   private static ByteField flags;
  92   private static CIntField codeSize;
  93   private static CIntField nameIndex;
  94   private static CIntField signatureIndex;
  95   private static CIntField genericSignatureIndex;
  96 
  97   // start of bytecode
  98   private static long bytecodeOffset;
  99 
 100   private static long checkedExceptionElementSize;
 101   private static long localVariableTableElementSize;
 102   private static long exceptionTableElementSize;
 103 
 104   // Accessors for declared fields
 105   public Method getMethod() {
 106     return (Method) method.getValue(this);
 107   }
 108 




 109   public long getConstMethodSize() {
 110     return constMethodSize.getValue(this);
 111   }
 112 
 113   public byte getFlags() {
 114     return flags.getValue(this);
 115   }
 116 
 117   public long getCodeSize() {
 118     return codeSize.getValue(this);
 119   }
 120 
 121   public long getNameIndex() {
 122     return nameIndex.getValue(this);
 123   }
 124 
 125   public long getSignatureIndex() {
 126     return signatureIndex.getValue(this);
 127   }
 128 


 204      for( int i=0; i < bc.length; i++ )
 205      {
 206         long offs = bytecodeOffset + i;
 207         bc[i] = getHandle().getJByteAt( offs );
 208      }
 209      return bc;
 210   }
 211 
 212   public long getObjectSize() {
 213     return getConstMethodSize() * getHeap().getOopSize();
 214   }
 215 
 216   public void printValueOn(PrintStream tty) {
 217     tty.print("ConstMethod " + getName().asString() + getSignature().asString() + "@" + getHandle());
 218   }
 219 
 220   public void iterateFields(OopVisitor visitor, boolean doVMFields) {
 221     super.iterateFields(visitor, doVMFields);
 222     if (doVMFields) {
 223       visitor.doOop(method, true);

 224       visitor.doCInt(constMethodSize, true);
 225       visitor.doByte(flags, true);
 226       visitor.doCInt(codeSize, true);
 227       visitor.doCInt(nameIndex, true);
 228       visitor.doCInt(signatureIndex, true);
 229       visitor.doCInt(genericSignatureIndex, true);
 230       visitor.doCInt(codeSize, true);
 231     }
 232   }
 233 
 234   // Accessors
 235 
 236   public boolean hasLineNumberTable() {
 237     return (getFlags() & HAS_LINENUMBER_TABLE) != 0;
 238   }
 239 
 240   public int getLineNumberFromBCI(int bci) {
 241     if (!VM.getVM().isCore()) {
 242       if (bci == DebugInformationRecorder.SYNCHRONIZATION_ENTRY_BCI) bci = 0;
 243     }


 294   }
 295 
 296   public Symbol getLocalVariableName(int bci, int slot) {
 297     return getMethod().getLocalVariableName(bci, slot);
 298   }
 299 
 300   /** Should only be called if table is present */
 301   public LocalVariableTableElement[] getLocalVariableTable() {
 302     if (Assert.ASSERTS_ENABLED) {
 303       Assert.that(hasLocalVariableTable(), "should only be called if table is present");
 304     }
 305     LocalVariableTableElement[] ret = new LocalVariableTableElement[getLocalVariableTableLength()];
 306     long offset = offsetOfLocalVariableTable();
 307     for (int i = 0; i < ret.length; i++) {
 308       ret[i] = new LocalVariableTableElement(getHandle(), offset);
 309       offset += localVariableTableElementSize;
 310     }
 311     return ret;
 312   }
 313 
 314   public boolean hasExceptionTable() {
 315     return (getFlags() & HAS_EXCEPTION_TABLE) != 0;
 316   }
 317 
 318   public ExceptionTableElement[] getExceptionTable() {
 319     if (Assert.ASSERTS_ENABLED) {
 320       Assert.that(hasExceptionTable(), "should only be called if table is present");
 321     }
 322     ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
 323     long offset = offsetOfExceptionTable();
 324     for (int i = 0; i < ret.length; i++) {
 325       ret[i] = new ExceptionTableElement(getHandle(), offset);
 326       offset += exceptionTableElementSize;
 327     }
 328     return ret;
 329   }
 330 
 331   public boolean hasCheckedExceptions() {
 332     return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
 333   }
 334 
 335   public CheckedExceptionElement[] getCheckedExceptions() {
 336     if (Assert.ASSERTS_ENABLED) {
 337       Assert.that(hasCheckedExceptions(), "should only be called if table is present");
 338     }
 339     CheckedExceptionElement[] ret = new CheckedExceptionElement[getCheckedExceptionsLength()];
 340     long offset = offsetOfCheckedExceptions();
 341     for (int i = 0; i < ret.length; i++) {
 342       ret[i] = new CheckedExceptionElement(getHandle(), offset);
 343       offset += checkedExceptionElementSize;
 344     }
 345     return ret;
 346   }
 347 
 348 
 349   //---------------------------------------------------------------------------
 350   // Internals only below this point


 400       while (stream.readPair()) {
 401         len += 1;
 402       }
 403     }
 404     return len;
 405   }
 406 
 407   private int getLocalVariableTableLength() {
 408     if (hasLocalVariableTable()) {
 409       return (int) getHandle().getCIntegerAt(offsetOfLocalVariableTableLength(), 2, true);
 410     } else {
 411       return 0;
 412     }
 413   }
 414 
 415   // Offset of local variable table length
 416   private long offsetOfLocalVariableTableLength() {
 417     if (Assert.ASSERTS_ENABLED) {
 418       Assert.that(hasLocalVariableTable(), "should only be called if table is present");
 419     }
 420     
 421     if (hasExceptionTable()) {
 422       return offsetOfExceptionTable() - 2;
 423     } else if (hasCheckedExceptions()) {
 424       return offsetOfCheckedExceptions() - 2;
 425     } else {
 426       return offsetOfLastU2Element();
 427     }
 428   }
 429 
 430   private long offsetOfLocalVariableTable() {
 431     long offset = offsetOfLocalVariableTableLength();
 432     long length = getLocalVariableTableLength();
 433     if (Assert.ASSERTS_ENABLED) {
 434       Assert.that(length > 0, "should only be called if table is present");
 435     }
 436     offset -= length * localVariableTableElementSize;
 437     return offset;
 438   }
 439 
 440   private int getExceptionTableLength() {
 441     if (hasExceptionTable()) {
 442       return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
 443     } else {
 444       return 0;
 445     }
 446   }
 447 
 448   private long offsetOfExceptionTableLength() {
 449     if (Assert.ASSERTS_ENABLED) {
 450       Assert.that(hasExceptionTable(), "should only be called if table is present");
 451     }
 452     if (hasCheckedExceptions()) {
 453       return offsetOfCheckedExceptions() - 2;
 454     } else {
 455       return offsetOfLastU2Element();
 456     }
 457   }
 458 
 459   private long offsetOfExceptionTable() {
 460     long offset = offsetOfExceptionTableLength();
 461     long length = getExceptionTableLength();
 462     if (Assert.ASSERTS_ENABLED) {
 463       Assert.that(length > 0, "should only be called if table is present");
 464     }
 465     offset -= length * exceptionTableElementSize;
 466     return offset;
 467   }
 468 
 469 }