agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java

Mon, 12 Aug 2013 17:37:02 +0200

author
ehelin
date
Mon, 12 Aug 2013 17:37:02 +0200
changeset 5694
7944aba7ba41
parent 5327
38ea2efa32a7
child 5790
72b7e96c1922
permissions
-rw-r--r--

8015107: NPG: Use consistent naming for metaspace concepts
Reviewed-by: coleenp, mgerdin, hseigel

     1 /*
     2  * Copyright (c) 2000, 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  *
    23  */
    25 package sun.jvm.hotspot.runtime;
    27 import java.io.*;
    28 import java.net.*;
    29 import java.util.*;
    30 import java.util.regex.*;
    31 import sun.jvm.hotspot.code.*;
    32 import sun.jvm.hotspot.c1.*;
    33 import sun.jvm.hotspot.code.*;
    34 import sun.jvm.hotspot.debugger.*;
    35 import sun.jvm.hotspot.interpreter.*;
    36 import sun.jvm.hotspot.memory.*;
    37 import sun.jvm.hotspot.oops.*;
    38 import sun.jvm.hotspot.types.*;
    39 import sun.jvm.hotspot.utilities.*;
    40 import sun.jvm.hotspot.runtime.*;
    42 /** <P> This class encapsulates the global state of the VM; the
    43     universe, object heap, interpreter, etc. It is a Singleton and
    44     must be initialized with a call to initialize() before calling
    45     getVM(). </P>
    47     <P> Many auxiliary classes (i.e., most of the VMObjects) keep
    48     needed field offsets in the form of static Field objects. In a
    49     debugging system, the VM might be shutdown and re-initialized (on
    50     a differently-configured build, i.e., 32- vs. 64-bit), and all old
    51     cached state (including fields and field offsets) must be
    52     flushed. </P>
    54     <P> An Observer pattern is used to implement the initialization of
    55     such classes. Each such class, in its static initializer,
    56     registers an Observer with the VM class via
    57     VM.registerVMInitializedObserver(). This Observer is guaranteed to
    58     be notified whenever the VM is initialized (or re-initialized). To
    59     implement the first-time initialization, the observer is also
    60     notified when it registers itself with the VM. (For bootstrapping
    61     reasons, this implies that the constructor of VM can not
    62     instantiate any such objects, since VM.soleInstance will not have
    63     been set yet. This is a bootstrapping issue which may have to be
    64     revisited later.) </P>
    65 */
    67 public class VM {
    68   private static VM    soleInstance;
    69   private static List  vmInitializedObservers = new ArrayList();
    70   private List         vmResumedObservers   = new ArrayList();
    71   private List         vmSuspendedObservers = new ArrayList();
    72   private TypeDataBase db;
    73   private boolean      isBigEndian;
    74   /** This is only present if in a debugging system */
    75   private JVMDebugger  debugger;
    76   private long         stackBias;
    77   private long         logAddressSize;
    78   private Universe     universe;
    79   private ObjectHeap   heap;
    80   private SymbolTable  symbols;
    81   private StringTable  strings;
    82   private SystemDictionary dict;
    83   private Threads      threads;
    84   private ObjectSynchronizer synchronizer;
    85   private JNIHandles   handles;
    86   private Interpreter  interpreter;
    87   private StubRoutines stubRoutines;
    88   private Bytes        bytes;
    90   /** Flags indicating whether we are attached to a core, C1, or C2 build */
    91   private boolean      usingClientCompiler;
    92   private boolean      usingServerCompiler;
    93   /** alignment constants */
    94   private boolean      isLP64;
    95   private int          bytesPerLong;
    96   private int          bytesPerWord;
    97   private int          objectAlignmentInBytes;
    98   private int          minObjAlignmentInBytes;
    99   private int          logMinObjAlignmentInBytes;
   100   private int          heapWordSize;
   101   private int          heapOopSize;
   102   private int          klassPtrSize;
   103   private int          oopSize;
   104   /** This is only present in a non-core build */
   105   private CodeCache    codeCache;
   106   /** This is only present in a C1 build */
   107   private Runtime1     runtime1;
   108   /** These constants come from globalDefinitions.hpp */
   109   private int          invocationEntryBCI;
   110   private int          invalidOSREntryBCI;
   111   private ReversePtrs  revPtrs;
   112   private VMRegImpl    vmregImpl;
   113   private int          reserveForAllocationPrefetch;
   115   // System.getProperties from debuggee VM
   116   private Properties   sysProps;
   118   // VM version strings come from Abstract_VM_Version class
   119   private String       vmRelease;
   120   private String       vmInternalInfo;
   122   private Flag[] commandLineFlags;
   123   private Map flagsMap;
   125   private static Type intxType;
   126   private static Type uintxType;
   127   private static CIntegerType boolType;
   128   private Boolean sharingEnabled;
   129   private Boolean compressedOopsEnabled;
   130   private Boolean compressedKlassPointersEnabled;
   132   // command line flags supplied to VM - see struct Flag in globals.hpp
   133   public static final class Flag {
   134      private String type;
   135      private String name;
   136      private Address addr;
   137      private String kind;
   138      private int origin;
   140      private Flag(String type, String name, Address addr, String kind, int origin) {
   141         this.type = type;
   142         this.name = name;
   143         this.addr = addr;
   144         this.kind = kind;
   145         this.origin = origin;
   146      }
   148      public String getType() {
   149         return type;
   150      }
   152      public String getName() {
   153         return name;
   154      }
   156      public Address getAddress() {
   157         return addr;
   158      }
   160      public String getKind() {
   161         return kind;
   162      }
   164      public int getOrigin() {
   165         return origin;
   166      }
   168      public boolean isBool() {
   169         return type.equals("bool");
   170      }
   172      public boolean getBool() {
   173         if (Assert.ASSERTS_ENABLED) {
   174            Assert.that(isBool(), "not a bool flag!");
   175         }
   176         return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned())
   177                != 0;
   178      }
   180      public boolean isIntx() {
   181         return type.equals("intx");
   182      }
   184      public long getIntx() {
   185         if (Assert.ASSERTS_ENABLED) {
   186            Assert.that(isIntx(), "not a intx flag!");
   187         }
   188         return addr.getCIntegerAt(0, intxType.getSize(), false);
   189      }
   191      public boolean isUIntx() {
   192         return type.equals("uintx");
   193      }
   195      public long getUIntx() {
   196         if (Assert.ASSERTS_ENABLED) {
   197            Assert.that(isUIntx(), "not a uintx flag!");
   198         }
   199         return addr.getCIntegerAt(0, uintxType.getSize(), true);
   200      }
   202      public String getValue() {
   203         if (isBool()) {
   204            return new Boolean(getBool()).toString();
   205         } else if (isIntx()) {
   206            return new Long(getIntx()).toString();
   207         } else if (isUIntx()) {
   208            return new Long(getUIntx()).toString();
   209         } else {
   210            return null;
   211         }
   212      }
   213   };
   215   private static void checkVMVersion(String vmRelease) {
   216      if (System.getProperty("sun.jvm.hotspot.runtime.VM.disableVersionCheck") == null) {
   217         // read sa build version.
   218         String versionProp = "sun.jvm.hotspot.runtime.VM.saBuildVersion";
   219         String saVersion = saProps.getProperty(versionProp);
   220         if (saVersion == null)
   221            throw new RuntimeException("Missing property " + versionProp);
   223         // Strip nonproduct VM version substring (note: saVersion doesn't have it).
   224         String vmVersion = vmRelease.replaceAll("(-fastdebug)|(-debug)|(-jvmg)|(-optimized)|(-profiled)","");
   226         if (saVersion.equals(vmVersion)) {
   227            // Exact match
   228            return;
   229         }
   230         if (saVersion.indexOf('-') == saVersion.lastIndexOf('-') &&
   231             vmVersion.indexOf('-') == vmVersion.lastIndexOf('-')) {
   232            // Throw exception if different release versions:
   233            // <major>.<minor>-b<n>
   234            throw new VMVersionMismatchException(saVersion, vmRelease);
   235         } else {
   236            // Otherwise print warning to allow mismatch not release versions
   237            // during development.
   238            System.err.println("WARNING: Hotspot VM version " + vmRelease +
   239                               " does not match with SA version " + saVersion +
   240                               "." + " You may see unexpected results. ");
   241         }
   242      } else {
   243         System.err.println("WARNING: You have disabled SA and VM version check. You may be "  +
   244                            "using incompatible version of SA and you may see unexpected " +
   245                            "results.");
   246      }
   247   }
   249   private static final boolean disableDerivedPointerTableCheck;
   250   private static final Properties saProps;
   252   static {
   253      saProps = new Properties();
   254      URL url = null;
   255      try {
   256        url = VM.class.getClassLoader().getResource("sa.properties");
   257        saProps.load(new BufferedInputStream(url.openStream()));
   258      } catch (Exception e) {
   259        System.err.println("Unable to load properties  " +
   260                                   (url == null ? "null" : url.toString()) +
   261                                   ": " + e.getMessage());
   262      }
   264      disableDerivedPointerTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null;
   265   }
   267   private VM(TypeDataBase db, JVMDebugger debugger, boolean isBigEndian) {
   268     this.db          = db;
   269     this.debugger    = debugger;
   270     this.isBigEndian = isBigEndian;
   272     // Note that we don't construct universe, heap, threads,
   273     // interpreter, or stubRoutines here (any more).  The current
   274     // initialization mechanisms require that the VM be completely set
   275     // up (i.e., out of its constructor, with soleInstance assigned)
   276     // before their static initializers are run.
   278     if (db.getAddressSize() == 4) {
   279       logAddressSize = 2;
   280     } else if (db.getAddressSize() == 8) {
   281       logAddressSize = 3;
   282     } else {
   283       throw new RuntimeException("Address size " + db.getAddressSize() + " not yet supported");
   284     }
   286     // read VM version info
   287     try {
   288        Type vmVersion = db.lookupType("Abstract_VM_Version");
   289        Address releaseAddr = vmVersion.getAddressField("_s_vm_release").getValue();
   290        vmRelease = CStringUtilities.getString(releaseAddr);
   291        Address vmInternalInfoAddr = vmVersion.getAddressField("_s_internal_vm_info_string").getValue();
   292        vmInternalInfo = CStringUtilities.getString(vmInternalInfoAddr);
   294        CIntegerType intType = (CIntegerType) db.lookupType("int");
   295        CIntegerField reserveForAllocationPrefetchField = vmVersion.getCIntegerField("_reserve_for_allocation_prefetch");
   296        reserveForAllocationPrefetch = (int)reserveForAllocationPrefetchField.getCInteger(intType);
   297     } catch (Exception exp) {
   298        throw new RuntimeException("can't determine target's VM version : " + exp.getMessage());
   299     }
   301     checkVMVersion(vmRelease);
   303     stackBias    = db.lookupIntConstant("STACK_BIAS").intValue();
   304     invocationEntryBCI = db.lookupIntConstant("InvocationEntryBci").intValue();
   305     invalidOSREntryBCI = db.lookupIntConstant("InvalidOSREntryBci").intValue();
   307     // We infer the presence of C1 or C2 from a couple of fields we
   308     // already have present in the type database
   309     {
   310       Type type = db.lookupType("Method");
   311       if (type.getField("_from_compiled_entry", false, false) == null) {
   312         // Neither C1 nor C2 is present
   313         usingClientCompiler = false;
   314         usingServerCompiler = false;
   315       } else {
   316         // Determine whether C2 is present
   317         if (db.lookupType("Matcher", false) != null) {
   318           usingServerCompiler = true;
   319         } else {
   320           usingClientCompiler = true;
   321         }
   322       }
   323     }
   325     if (debugger != null) {
   326       isLP64 = debugger.getMachineDescription().isLP64();
   327     }
   328     bytesPerLong = db.lookupIntConstant("BytesPerLong").intValue();
   329     bytesPerWord = db.lookupIntConstant("BytesPerWord").intValue();
   330     heapWordSize = db.lookupIntConstant("HeapWordSize").intValue();
   331     oopSize  = db.lookupIntConstant("oopSize").intValue();
   333     intxType = db.lookupType("intx");
   334     uintxType = db.lookupType("uintx");
   335     boolType = (CIntegerType) db.lookupType("bool");
   337     minObjAlignmentInBytes = getObjectAlignmentInBytes();
   338     if (minObjAlignmentInBytes == 8) {
   339       logMinObjAlignmentInBytes = 3;
   340     } else if (minObjAlignmentInBytes == 16) {
   341       logMinObjAlignmentInBytes = 4;
   342     } else {
   343       throw new RuntimeException("Object alignment " + minObjAlignmentInBytes + " not yet supported");
   344     }
   346     if (isCompressedOopsEnabled()) {
   347       // Size info for oops within java objects is fixed
   348       heapOopSize = (int)getIntSize();
   349     } else {
   350       heapOopSize = (int)getOopSize();
   351     }
   353     if (isCompressedKlassPointersEnabled()) {
   354       klassPtrSize = (int)getIntSize();
   355     } else {
   356       klassPtrSize = (int)getOopSize(); // same as an oop
   357     }
   358   }
   360   /** This could be used by a reflective runtime system */
   361   public static void initialize(TypeDataBase db, boolean isBigEndian) {
   362     if (soleInstance != null) {
   363       throw new RuntimeException("Attempt to initialize VM twice");
   364     }
   365     soleInstance = new VM(db, null, isBigEndian);
   366     for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
   367       ((Observer) iter.next()).update(null, null);
   368     }
   369   }
   371   /** This is used by the debugging system */
   372   public static void initialize(TypeDataBase db, JVMDebugger debugger) {
   373     if (soleInstance != null) {
   374       // Using multiple SA Tool classes in the same process creates a call here.
   375       return;
   376     }
   377     soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
   379     for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
   380       ((Observer) iter.next()).update(null, null);
   381     }
   383     debugger.putHeapConst(soleInstance.getHeapOopSize(), soleInstance.getKlassPtrSize(),
   384                           Universe.getNarrowOopBase(), Universe.getNarrowOopShift(),
   385                           Universe.getNarrowKlassBase(), Universe.getNarrowKlassShift());
   386   }
   388   /** This is used by the debugging system */
   389   public static void shutdown() {
   390     soleInstance = null;
   391   }
   393   /** This is used by both the debugger and any runtime system. It is
   394       the basic mechanism by which classes which mimic underlying VM
   395       functionality cause themselves to be initialized. The given
   396       observer will be notified (with arguments (null, null)) when the
   397       VM is re-initialized, as well as when it registers itself with
   398       the VM. */
   399   public static void registerVMInitializedObserver(Observer o) {
   400     vmInitializedObservers.add(o);
   401     o.update(null, null);
   402   }
   404   /** This is the primary accessor used by both the debugger and any
   405       potential runtime system */
   406   public static VM getVM() {
   407     if (soleInstance == null) {
   408       throw new RuntimeException("VM.initialize() was not yet called");
   409     }
   410     return soleInstance;
   411   }
   413   /** This is only used by the debugging system. The given observer
   414       will be notified if the underlying VM resumes execution. NOTE
   415       that the given observer is not triggered if the VM is currently
   416       running and therefore differs in behavior from {@link
   417       #registerVMInitializedObserver} (because of the possibility of
   418       race conditions if the observer is added while the VM is being
   419       suspended or resumed).  */
   420   public void registerVMResumedObserver(Observer o) {
   421     vmResumedObservers.add(o);
   422   }
   424   /** This is only used by the debugging system. The given observer
   425       will be notified if the underlying VM suspends execution. NOTE
   426       that the given observer is not triggered if the VM is currently
   427       suspended and therefore differs in behavior from {@link
   428       #registerVMInitializedObserver} (because of the possibility of
   429       race conditions if the observer is added while the VM is being
   430       suspended or resumed).  */
   431   public void registerVMSuspendedObserver(Observer o) {
   432     vmSuspendedObservers.add(o);
   433   }
   435   /** This is only used by the debugging system. Informs all
   436       registered resumption observers that the VM has been resumed.
   437       The application is responsible for actually having performed the
   438       resumption. No OopHandles must be used after this point, as they
   439       may move in the target address space due to garbage
   440       collection. */
   441   public void fireVMResumed() {
   442     for (Iterator iter = vmResumedObservers.iterator(); iter.hasNext(); ) {
   443       ((Observer) iter.next()).update(null, null);
   444     }
   445   }
   447   /** This is only used by the debugging system. Informs all
   448       registered suspension observers that the VM has been suspended.
   449       The application is responsible for actually having performed the
   450       suspension. Garbage collection must be forbidden at this point;
   451       for example, a JPDA-level suspension is not adequate since the
   452       VM thread may still be running. */
   453   public void fireVMSuspended() {
   454     for (Iterator iter = vmSuspendedObservers.iterator(); iter.hasNext(); ) {
   455       ((Observer) iter.next()).update(null, null);
   456     }
   457   }
   459   /** Returns the OS this VM is running on. Notice that by delegating
   460       to the debugger we can transparently support remote
   461       debugging. */
   462   public String getOS() {
   463     if (debugger != null) {
   464       return debugger.getOS();
   465     }
   466     return PlatformInfo.getOS();
   467   }
   469   /** Returns the CPU this VM is running on. Notice that by delegating
   470       to the debugger we can transparently support remote
   471       debugging. */
   472   public String getCPU() {
   473     if (debugger != null) {
   474       return debugger.getCPU();
   475     }
   476     return PlatformInfo.getCPU();
   477   }
   479   public Type lookupType(String cTypeName) {
   480     return db.lookupType(cTypeName);
   481   }
   483   public Integer lookupIntConstant(String name) {
   484     return db.lookupIntConstant(name);
   485   }
   487   // Convenience function for conversions
   488   static public long getAddressValue(Address addr) {
   489     return VM.getVM().getDebugger().getAddressValue(addr);
   490   }
   492   public long getAddressSize() {
   493     return db.getAddressSize();
   494   }
   496   public long getOopSize() {
   497     return oopSize;
   498   }
   500   public long getLogAddressSize() {
   501     return logAddressSize;
   502   }
   504   public long getIntSize() {
   505     return db.getJIntType().getSize();
   506   }
   508   /** NOTE: this offset is in BYTES in this system! */
   509   public long getStackBias() {
   510     return stackBias;
   511   }
   513   /** Indicates whether the underlying machine supports the LP64 data
   514       model. This is needed for conditionalizing code in a few places */
   515   public boolean isLP64() {
   516     if (Assert.ASSERTS_ENABLED) {
   517       Assert.that(isDebugging(), "Debugging system only for now");
   518     }
   519     return isLP64;
   520   }
   522   /** Get bytes-per-long == long/double natural alignment. */
   523   public int getBytesPerLong() {
   524     return bytesPerLong;
   525   }
   527   public int getBytesPerWord() {
   528     return bytesPerWord;
   529   }
   531   /** Get minimum object alignment in bytes. */
   532   public int getMinObjAlignmentInBytes() {
   533     return minObjAlignmentInBytes;
   534   }
   535   public int getLogMinObjAlignmentInBytes() {
   536     return logMinObjAlignmentInBytes;
   537   }
   539   public int getHeapWordSize() {
   540     return heapWordSize;
   541   }
   543   public int getHeapOopSize() {
   544     return heapOopSize;
   545   }
   547   public int getKlassPtrSize() {
   548     return klassPtrSize;
   549   }
   550   /** Utility routine for getting data structure alignment correct */
   551   public long alignUp(long size, long alignment) {
   552     return (size + alignment - 1) & ~(alignment - 1);
   553   }
   555   /** Utility routine for getting data structure alignment correct */
   556   public long alignDown(long size, long alignment) {
   557     return size & ~(alignment - 1);
   558   }
   560   /** Utility routine for building an int from two "unsigned" 16-bit
   561       shorts */
   562   public int buildIntFromShorts(short low, short high) {
   563     return (((int) high) << 16) | (((int) low) & 0xFFFF);
   564   }
   566   /** Utility routine for building a long from two "unsigned" 32-bit
   567       ints in <b>platform-dependent</b> order */
   568   public long buildLongFromIntsPD(int oneHalf, int otherHalf) {
   569     if (isBigEndian) {
   570       return (((long) otherHalf) << 32) | (((long) oneHalf) & 0x00000000FFFFFFFFL);
   571     } else{
   572       return (((long) oneHalf) << 32) | (((long) otherHalf) & 0x00000000FFFFFFFFL);
   573     }
   574   }
   576   public TypeDataBase getTypeDataBase() {
   577     return db;
   578   }
   580   public Universe    getUniverse() {
   581     if (universe == null) {
   582       universe = new Universe();
   583     }
   584     return universe;
   585   }
   587   public ObjectHeap  getObjectHeap() {
   588     if (heap == null) {
   589       heap = new ObjectHeap(db);
   590     }
   591     return heap;
   592   }
   594   public SymbolTable getSymbolTable() {
   595     if (symbols == null) {
   596       symbols = SymbolTable.getTheTable();
   597     }
   598     return symbols;
   599   }
   601   public StringTable getStringTable() {
   602     if (strings == null) {
   603       strings = StringTable.getTheTable();
   604     }
   605     return strings;
   606   }
   608   public SystemDictionary getSystemDictionary() {
   609     if (dict == null) {
   610       dict = new SystemDictionary();
   611     }
   612     return dict;
   613   }
   615   public Threads     getThreads() {
   616     if (threads == null) {
   617       threads = new Threads();
   618     }
   619     return threads;
   620   }
   622   public ObjectSynchronizer getObjectSynchronizer() {
   623     if (synchronizer == null) {
   624       synchronizer = new ObjectSynchronizer();
   625     }
   626     return synchronizer;
   627   }
   629   public JNIHandles getJNIHandles() {
   630     if (handles == null) {
   631       handles = new JNIHandles();
   632     }
   633     return handles;
   634   }
   636   public Interpreter getInterpreter() {
   637     if (interpreter == null) {
   638       interpreter = new Interpreter();
   639     }
   640     return interpreter;
   641   }
   643   public StubRoutines getStubRoutines() {
   644     if (stubRoutines == null) {
   645       stubRoutines = new StubRoutines();
   646     }
   647     return stubRoutines;
   648   }
   650   public VMRegImpl getVMRegImplInfo() {
   651     if (vmregImpl == null) {
   652       vmregImpl = new VMRegImpl();
   653     }
   654     return vmregImpl;
   655   }
   657   public Bytes getBytes() {
   658     if (bytes == null) {
   659       bytes = new Bytes(debugger.getMachineDescription());
   660     }
   661     return bytes;
   662   }
   664   /** Returns true if this is a isBigEndian, false otherwise */
   665   public boolean isBigEndian() {
   666     return isBigEndian;
   667   }
   669   /** Returns true if this is a "core" build, false if either C1 or C2
   670       is present */
   671   public boolean isCore() {
   672     return (!(usingClientCompiler || usingServerCompiler));
   673   }
   675   /** Returns true if this is a C1 build, false otherwise */
   676   public boolean isClientCompiler() {
   677     return usingClientCompiler;
   678   }
   680   /** Returns true if this is a C2 build, false otherwise */
   681   public boolean isServerCompiler() {
   682     return usingServerCompiler;
   683   }
   685   /** Returns true if C2 derived pointer table should be used, false otherwise */
   686   public boolean useDerivedPointerTable() {
   687     return !disableDerivedPointerTableCheck;
   688   }
   690   /** Returns the code cache; should not be used if is core build */
   691   public CodeCache getCodeCache() {
   692     if (Assert.ASSERTS_ENABLED) {
   693       Assert.that(!isCore(), "noncore builds only");
   694     }
   695     if (codeCache == null) {
   696       codeCache = new CodeCache();
   697     }
   698     return codeCache;
   699   }
   701   /** Should only be called for C1 builds */
   702   public Runtime1 getRuntime1() {
   703     if (Assert.ASSERTS_ENABLED) {
   704       Assert.that(isClientCompiler(), "C1 builds only");
   705     }
   706     if (runtime1 == null) {
   707       runtime1 = new Runtime1();
   708     }
   709     return runtime1;
   710   }
   712   /** Test to see whether we're in debugging mode (NOTE: this really
   713       should not be tested by this code; currently only used in
   714       StackFrameStream) */
   715   public boolean isDebugging() {
   716     return (debugger != null);
   717   }
   719   /** This is only used by the debugging (i.e., non-runtime) system */
   720   public JVMDebugger getDebugger() {
   721     if (debugger == null) {
   722       throw new RuntimeException("Attempt to use debugger in runtime system");
   723     }
   724     return debugger;
   725   }
   727   /** Indicates whether a given program counter is in Java code. This
   728       includes but is not spanned by the interpreter and code cache.
   729       Only used in the debugging system, for implementing
   730       JavaThread.currentFrameGuess() on x86. */
   731   public boolean isJavaPCDbg(Address addr) {
   732     // FIXME: this is not a complete enough set: must include areas
   733     // like vtable stubs
   734     return (getInterpreter().contains(addr) ||
   735             getCodeCache().contains(addr));
   736   }
   738   /** FIXME: figure out where to stick this */
   739   public int getInvocationEntryBCI() {
   740     return invocationEntryBCI;
   741   }
   743   /** FIXME: figure out where to stick this */
   744   public int getInvalidOSREntryBCI() {
   745     return invalidOSREntryBCI;
   746   }
   748   // FIXME: figure out where to stick this
   749   public boolean wizardMode() {
   750     return true;
   751   }
   753   public ReversePtrs getRevPtrs() {
   754     return revPtrs;
   755   }
   757   public void setRevPtrs(ReversePtrs rp) {
   758     revPtrs = rp;
   759   }
   761   // returns null, if not available.
   762   public String getVMRelease() {
   763     return vmRelease;
   764   }
   766   // returns null, if not available.
   767   public String getVMInternalInfo() {
   768     return vmInternalInfo;
   769   }
   771   public int getReserveForAllocationPrefetch() {
   772     return reserveForAllocationPrefetch;
   773   }
   775   public boolean isSharingEnabled() {
   776     if (sharingEnabled == null) {
   777       Flag flag = getCommandLineFlag("UseSharedSpaces");
   778       sharingEnabled = (flag == null)? Boolean.FALSE :
   779           (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
   780     }
   781     return sharingEnabled.booleanValue();
   782   }
   784   public boolean isCompressedOopsEnabled() {
   785     if (compressedOopsEnabled == null) {
   786         Flag flag = getCommandLineFlag("UseCompressedOops");
   787         compressedOopsEnabled = (flag == null) ? Boolean.FALSE:
   788              (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
   789     }
   790     return compressedOopsEnabled.booleanValue();
   791   }
   793   public boolean isCompressedKlassPointersEnabled() {
   794     if (compressedKlassPointersEnabled == null) {
   795         Flag flag = getCommandLineFlag("UseCompressedClassPointers");
   796         compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE:
   797              (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
   798     }
   799     return compressedKlassPointersEnabled.booleanValue();
   800   }
   802   public int getObjectAlignmentInBytes() {
   803     if (objectAlignmentInBytes == 0) {
   804         Flag flag = getCommandLineFlag("ObjectAlignmentInBytes");
   805         objectAlignmentInBytes = (flag == null) ? 8 : (int)flag.getIntx();
   806     }
   807     return objectAlignmentInBytes;
   808   }
   810   /** Indicates whether Thread-Local Allocation Buffers are used */
   811   public boolean getUseTLAB() {
   812       Flag flag = getCommandLineFlag("UseTLAB");
   813       return (flag == null) ? false: flag.getBool();
   814   }
   816   // returns null, if not available.
   817   public Flag[] getCommandLineFlags() {
   818     if (commandLineFlags == null) {
   819        readCommandLineFlags();
   820     }
   822     return commandLineFlags;
   823   }
   825   public Flag getCommandLineFlag(String name) {
   826     if (flagsMap == null) {
   827       flagsMap = new HashMap();
   828       Flag[] flags = getCommandLineFlags();
   829       for (int i = 0; i < flags.length; i++) {
   830         flagsMap.put(flags[i].getName(), flags[i]);
   831       }
   832     }
   833     return (Flag) flagsMap.get(name);
   834   }
   836   private void readCommandLineFlags() {
   837     // get command line flags
   838     TypeDataBase db = getTypeDataBase();
   839     Type flagType = db.lookupType("Flag");
   840     int numFlags = (int) flagType.getCIntegerField("numFlags").getValue();
   841     // NOTE: last flag contains null values.
   842     commandLineFlags = new Flag[numFlags - 1];
   844     Address flagAddr = flagType.getAddressField("flags").getValue();
   846     AddressField typeFld = flagType.getAddressField("type");
   847     AddressField nameFld = flagType.getAddressField("name");
   848     AddressField addrFld = flagType.getAddressField("addr");
   849     AddressField kindFld = flagType.getAddressField("kind");
   850     CIntField originFld = new CIntField(flagType.getCIntegerField("origin"), 0);
   852     long flagSize = flagType.getSize(); // sizeof(Flag)
   854     // NOTE: last flag contains null values.
   855     for (int f = 0; f < numFlags - 1; f++) {
   856       String type = CStringUtilities.getString(typeFld.getValue(flagAddr));
   857       String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
   858       Address addr = addrFld.getValue(flagAddr);
   859       String kind = CStringUtilities.getString(kindFld.getValue(flagAddr));
   860       int origin = (int)originFld.getValue(flagAddr);
   861       commandLineFlags[f] = new Flag(type, name, addr, kind, origin);
   862       flagAddr = flagAddr.addOffsetTo(flagSize);
   863     }
   865     // sort flags by name
   866     Arrays.sort(commandLineFlags, new Comparator() {
   867         public int compare(Object o1, Object o2) {
   868           Flag f1 = (Flag) o1;
   869           Flag f2 = (Flag) o2;
   870           return f1.getName().compareTo(f2.getName());
   871         }
   872       });
   873   }
   875   public String getSystemProperty(String key) {
   876     Properties props = getSystemProperties();
   877     return (props != null)? props.getProperty(key) : null;
   878   }
   880   public Properties getSystemProperties() {
   881     if (sysProps == null) {
   882        readSystemProperties();
   883     }
   884     return sysProps;
   885   }
   887   private void readSystemProperties() {
   888     final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
   889     systemKls.iterateStaticFields(new DefaultOopVisitor() {
   890         ObjectReader objReader = new ObjectReader();
   891         public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
   892           if (field.getID().getName().equals("props")) {
   893             try {
   894               sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
   895             } catch (Exception e) {
   896               e.printStackTrace();
   897             }
   898           }
   899         }
   900       });
   901   }
   902 }

mercurial