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

Print this page
rev 611 : Merge
   1 /*
   2  * Copyright 2000-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *  
  23  */
  24 
  25 package sun.jvm.hotspot.runtime;
  26 
  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.debugger.*;
  34 import sun.jvm.hotspot.interpreter.*;
  35 import sun.jvm.hotspot.memory.*;
  36 import sun.jvm.hotspot.oops.*;
  37 import sun.jvm.hotspot.types.*;
  38 import sun.jvm.hotspot.utilities.*;

  39 
  40 /** <P> This class encapsulates the global state of the VM; the
  41     universe, object heap, interpreter, etc. It is a Singleton and
  42     must be initialized with a call to initialize() before calling
  43     getVM(). </P>
  44 
  45     <P> Many auxiliary classes (i.e., most of the VMObjects) keep
  46     needed field offsets in the form of static Field objects. In a
  47     debugging system, the VM might be shutdown and re-initialized (on
  48     a differently-configured build, i.e., 32- vs. 64-bit), and all old
  49     cached state (including fields and field offsets) must be
  50     flushed. </P>
  51 
  52     <P> An Observer pattern is used to implement the initialization of
  53     such classes. Each such class, in its static initializer,
  54     registers an Observer with the VM class via
  55     VM.registerVMInitializedObserver(). This Observer is guaranteed to
  56     be notified whenever the VM is initialized (or re-initialized). To
  57     implement the first-time initialization, the observer is also
  58     notified when it registers itself with the VM. (For bootstrapping


  76   private Universe     universe;
  77   private ObjectHeap   heap;
  78   private SymbolTable  symbols;
  79   private StringTable  strings;
  80   private SystemDictionary dict;
  81   private Threads      threads;
  82   private ObjectSynchronizer synchronizer;
  83   private JNIHandles   handles;
  84   private Interpreter  interpreter;
  85   private StubRoutines stubRoutines;
  86   private Bytes        bytes;
  87   /** Flags indicating whether we are attached to a core, C1, or C2 build */
  88   private boolean      usingClientCompiler;
  89   private boolean      usingServerCompiler;
  90   /** Flag indicating whether UseTLAB is turned on */
  91   private boolean      useTLAB;
  92   /** alignment constants */
  93   private boolean      isLP64;
  94   private int          bytesPerLong;
  95   private int          minObjAlignmentInBytes;




  96   /** This is only present in a non-core build */
  97   private CodeCache    codeCache;
  98   /** This is only present in a C1 build */
  99   private Runtime1     runtime1;
 100   /** These constants come from globalDefinitions.hpp */
 101   private int          invocationEntryBCI;
 102   private int          invalidOSREntryBCI;
 103   private ReversePtrs  revPtrs;
 104   private VMRegImpl    vmregImpl;
 105 
 106   // System.getProperties from debuggee VM
 107   private Properties   sysProps;
 108 
 109   // VM version strings come from Abstract_VM_Version class
 110   private String       vmRelease;
 111   private String       vmInternalInfo;
 112 
 113   private Flag[] commandLineFlags;
 114   private Map flagsMap;
 115 
 116   private static Type intxType;
 117   private static Type uintxType;
 118   private static CIntegerType boolType;
 119   private Boolean sharingEnabled;

 120  
 121   // command line flags supplied to VM - see struct Flag in globals.hpp
 122   public static final class Flag {
 123      private String type;
 124      private String name;
 125      private Address addr;
 126      private String kind;
 127 
 128      private Flag(String type, String name, Address addr, String kind) {
 129         this.type = type;
 130         this.name = name;
 131         this.addr = addr;
 132         this.kind = kind;
 133      }
 134 
 135      public String getType() {
 136         return type;
 137      }
 138 
 139      public String getName() {


 291         // Neither C1 nor C2 is present
 292         usingClientCompiler = false;
 293         usingServerCompiler = false;
 294       } else {
 295         // Determine whether C2 is present
 296         if (type.getField("_interpreter_invocation_count", false, false) != null) {
 297           usingServerCompiler = true;
 298         } else {
 299           usingClientCompiler = true;
 300         }
 301       }
 302     }
 303 
 304     useTLAB = (db.lookupIntConstant("UseTLAB").intValue() != 0);
 305 
 306     if (debugger != null) {
 307       isLP64 = debugger.getMachineDescription().isLP64();
 308     }
 309     bytesPerLong = db.lookupIntConstant("BytesPerLong").intValue();
 310     minObjAlignmentInBytes = db.lookupIntConstant("MinObjAlignmentInBytes").intValue();





 311 
 312     intxType = db.lookupType("intx");
 313     uintxType = db.lookupType("uintx");
 314     boolType = (CIntegerType) db.lookupType("bool");
 315   }
 316 
 317   /** This could be used by a reflective runtime system */
 318   public static void initialize(TypeDataBase db, boolean isBigEndian) {
 319     if (soleInstance != null) {
 320       throw new RuntimeException("Attempt to initialize VM twice");
 321     }
 322     soleInstance = new VM(db, null, isBigEndian);
 323     for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
 324       ((Observer) iter.next()).update(null, null);
 325     }
 326   }
 327 
 328   /** This is used by the debugging system */
 329   public static void initialize(TypeDataBase db, JVMDebugger debugger) {
 330     if (soleInstance != null) {
 331       throw new RuntimeException("Attempt to initialize VM twice");
 332     }
 333     soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());


 334     for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
 335       ((Observer) iter.next()).update(null, null);
 336     }
 337   }
 338 
 339   /** This is used by the debugging system */
 340   public static void shutdown() {
 341     soleInstance = null;
 342   }
 343 
 344   /** This is used by both the debugger and any runtime system. It is
 345       the basic mechanism by which classes which mimic underlying VM
 346       functionality cause themselves to be initialized. The given
 347       observer will be notified (with arguments (null, null)) when the
 348       VM is re-initialized, as well as when it registers itself with
 349       the VM. */
 350   public static void registerVMInitializedObserver(Observer o) {
 351     vmInitializedObservers.add(o);
 352     o.update(null, null);
 353   }


 423   public String getCPU() {
 424     if (debugger != null) {
 425       return debugger.getCPU();
 426     }
 427     return PlatformInfo.getCPU();
 428   }
 429 
 430   public Type lookupType(String cTypeName) {
 431     return db.lookupType(cTypeName);
 432   }
 433 
 434   public Integer lookupIntConstant(String name) {
 435     return db.lookupIntConstant(name);
 436   }
 437 
 438   public long getAddressSize() {
 439     return db.getAddressSize();
 440   }
 441 
 442   public long getOopSize() {
 443     return db.getOopSize();
 444   }
 445 
 446   public long getLogAddressSize() {
 447     return logAddressSize;
 448   }
 449 




 450   /** NOTE: this offset is in BYTES in this system! */
 451   public long getStackBias() {
 452     return stackBias;
 453   }
 454 
 455   /** Indicates whether the underlying machine supports the LP64 data
 456       model. This is needed for conditionalizing code in a few places */
 457   public boolean isLP64() {
 458     if (Assert.ASSERTS_ENABLED) {
 459       Assert.that(isDebugging(), "Debugging system only for now");
 460     }
 461     return isLP64;
 462   }
 463 
 464   /** Get bytes-per-long == long/double natural alignment. */
 465   public int getBytesPerLong() {
 466     return bytesPerLong;
 467   }
 468 
 469   /** Get minimum object alignment in bytes. */




 470   public int getMinObjAlignmentInBytes() {
 471     return minObjAlignmentInBytes;
 472   }







 473 



 474   /** Utility routine for getting data structure alignment correct */
 475   public long alignUp(long size, long alignment) {
 476     return (size + alignment - 1) & ~(alignment - 1);
 477   }
 478 
 479   /** Utility routine for getting data structure alignment correct */
 480   public long alignDown(long size, long alignment) {
 481     return size & ~(alignment - 1);
 482   }
 483 
 484   /** Utility routine for building an int from two "unsigned" 16-bit
 485       shorts */
 486   public int buildIntFromShorts(short low, short high) {
 487     return (((int) high) << 16) | (((int) low) & 0xFFFF);
 488   }
 489 
 490   /** Utility routine for building a long from two "unsigned" 32-bit
 491       ints in <b>platform-dependent</b> order */
 492   public long buildLongFromIntsPD(int oneHalf, int otherHalf) {
 493     if (isBigEndian) {


 573     if (stubRoutines == null) {
 574       stubRoutines = new StubRoutines();
 575     }
 576     return stubRoutines;
 577   }
 578 
 579   public VMRegImpl getVMRegImplInfo() {
 580     if (vmregImpl == null) {
 581       vmregImpl = new VMRegImpl();
 582     }
 583     return vmregImpl;
 584   }
 585 
 586   public Bytes getBytes() {
 587     if (bytes == null) {
 588       bytes = new Bytes(debugger.getMachineDescription());
 589     }
 590     return bytes;
 591   }
 592 





 593   /** Returns true if this is a "core" build, false if either C1 or C2
 594       is present */
 595   public boolean isCore() {
 596     return (!(usingClientCompiler || usingServerCompiler));
 597   }
 598 
 599   /** Returns true if this is a C1 build, false otherwise */
 600   public boolean isClientCompiler() {
 601     return usingClientCompiler;
 602   }
 603 
 604   /** Returns true if this is a C2 build, false otherwise */
 605   public boolean isServerCompiler() {
 606     return usingServerCompiler;
 607   }
 608 
 609   /** Returns true if C2 derived pointer table should be used, false otherwise */
 610   public boolean useDerivedPointerTable() {
 611     return !disableDerivedPrinterTableCheck; 
 612   }


 684 
 685   // returns null, if not available.
 686   public String getVMRelease() {
 687     return vmRelease;
 688   }
 689 
 690   // returns null, if not available.
 691   public String getVMInternalInfo() {
 692     return vmInternalInfo;
 693   }
 694 
 695   public boolean isSharingEnabled() {
 696     if (sharingEnabled == null) {
 697       Flag flag = getCommandLineFlag("UseSharedSpaces");
 698       sharingEnabled = (flag == null)? Boolean.FALSE : 
 699           (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
 700     }
 701     return sharingEnabled.booleanValue();
 702   }
 703 








 704 
 705   // returns null, if not available.
 706   public Flag[] getCommandLineFlags() {
 707     if (commandLineFlags == null) {
 708        readCommandLineFlags();
 709     }
 710 
 711     return commandLineFlags;
 712   }
 713 
 714   public Flag getCommandLineFlag(String name) {
 715     if (flagsMap == null) {
 716       flagsMap = new HashMap();
 717       Flag[] flags = getCommandLineFlags();
 718       for (int i = 0; i < flags.length; i++) {
 719         flagsMap.put(flags[i].getName(), flags[i]);
 720       }
 721     }
 722     return (Flag) flagsMap.get(name);
 723   }


   1 /*
   2  * Copyright 2000-2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.runtime;
  26 
  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.debugger.*;
  34 import sun.jvm.hotspot.interpreter.*;
  35 import sun.jvm.hotspot.memory.*;
  36 import sun.jvm.hotspot.oops.*;
  37 import sun.jvm.hotspot.types.*;
  38 import sun.jvm.hotspot.utilities.*;
  39 import sun.jvm.hotspot.runtime.*;
  40 
  41 /** <P> This class encapsulates the global state of the VM; the
  42     universe, object heap, interpreter, etc. It is a Singleton and
  43     must be initialized with a call to initialize() before calling
  44     getVM(). </P>
  45 
  46     <P> Many auxiliary classes (i.e., most of the VMObjects) keep
  47     needed field offsets in the form of static Field objects. In a
  48     debugging system, the VM might be shutdown and re-initialized (on
  49     a differently-configured build, i.e., 32- vs. 64-bit), and all old
  50     cached state (including fields and field offsets) must be
  51     flushed. </P>
  52 
  53     <P> An Observer pattern is used to implement the initialization of
  54     such classes. Each such class, in its static initializer,
  55     registers an Observer with the VM class via
  56     VM.registerVMInitializedObserver(). This Observer is guaranteed to
  57     be notified whenever the VM is initialized (or re-initialized). To
  58     implement the first-time initialization, the observer is also
  59     notified when it registers itself with the VM. (For bootstrapping


  77   private Universe     universe;
  78   private ObjectHeap   heap;
  79   private SymbolTable  symbols;
  80   private StringTable  strings;
  81   private SystemDictionary dict;
  82   private Threads      threads;
  83   private ObjectSynchronizer synchronizer;
  84   private JNIHandles   handles;
  85   private Interpreter  interpreter;
  86   private StubRoutines stubRoutines;
  87   private Bytes        bytes;
  88   /** Flags indicating whether we are attached to a core, C1, or C2 build */
  89   private boolean      usingClientCompiler;
  90   private boolean      usingServerCompiler;
  91   /** Flag indicating whether UseTLAB is turned on */
  92   private boolean      useTLAB;
  93   /** alignment constants */
  94   private boolean      isLP64;
  95   private int          bytesPerLong;
  96   private int          minObjAlignmentInBytes;
  97   private int          logMinObjAlignmentInBytes;
  98   private int          heapWordSize;
  99   private int          heapOopSize;
 100   private int          oopSize;
 101   /** This is only present in a non-core build */
 102   private CodeCache    codeCache;
 103   /** This is only present in a C1 build */
 104   private Runtime1     runtime1;
 105   /** These constants come from globalDefinitions.hpp */
 106   private int          invocationEntryBCI;
 107   private int          invalidOSREntryBCI;
 108   private ReversePtrs  revPtrs;
 109   private VMRegImpl    vmregImpl;
 110 
 111   // System.getProperties from debuggee VM
 112   private Properties   sysProps;
 113 
 114   // VM version strings come from Abstract_VM_Version class
 115   private String       vmRelease;
 116   private String       vmInternalInfo;
 117 
 118   private Flag[] commandLineFlags;
 119   private Map flagsMap;
 120 
 121   private static Type intxType;
 122   private static Type uintxType;
 123   private static CIntegerType boolType;
 124   private Boolean sharingEnabled;
 125   private Boolean compressedOopsEnabled;
 126 
 127   // command line flags supplied to VM - see struct Flag in globals.hpp
 128   public static final class Flag {
 129      private String type;
 130      private String name;
 131      private Address addr;
 132      private String kind;
 133 
 134      private Flag(String type, String name, Address addr, String kind) {
 135         this.type = type;
 136         this.name = name;
 137         this.addr = addr;
 138         this.kind = kind;
 139      }
 140 
 141      public String getType() {
 142         return type;
 143      }
 144 
 145      public String getName() {


 297         // Neither C1 nor C2 is present
 298         usingClientCompiler = false;
 299         usingServerCompiler = false;
 300       } else {
 301         // Determine whether C2 is present
 302         if (type.getField("_interpreter_invocation_count", false, false) != null) {
 303           usingServerCompiler = true;
 304         } else {
 305           usingClientCompiler = true;
 306         }
 307       }
 308     }
 309 
 310     useTLAB = (db.lookupIntConstant("UseTLAB").intValue() != 0);
 311 
 312     if (debugger != null) {
 313       isLP64 = debugger.getMachineDescription().isLP64();
 314     }
 315     bytesPerLong = db.lookupIntConstant("BytesPerLong").intValue();
 316     minObjAlignmentInBytes = db.lookupIntConstant("MinObjAlignmentInBytes").intValue();
 317     // minObjAlignment = db.lookupIntConstant("MinObjAlignment").intValue();
 318     logMinObjAlignmentInBytes = db.lookupIntConstant("LogMinObjAlignmentInBytes").intValue();
 319     heapWordSize = db.lookupIntConstant("HeapWordSize").intValue();
 320     oopSize  = db.lookupIntConstant("oopSize").intValue();
 321     heapOopSize  = db.lookupIntConstant("heapOopSize").intValue();
 322 
 323     intxType = db.lookupType("intx");
 324     uintxType = db.lookupType("uintx");
 325     boolType = (CIntegerType) db.lookupType("bool");
 326   }
 327 
 328   /** This could be used by a reflective runtime system */
 329   public static void initialize(TypeDataBase db, boolean isBigEndian) {
 330     if (soleInstance != null) {
 331       throw new RuntimeException("Attempt to initialize VM twice");
 332     }
 333     soleInstance = new VM(db, null, isBigEndian);
 334     for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
 335       ((Observer) iter.next()).update(null, null);
 336     }
 337   }
 338 
 339   /** This is used by the debugging system */
 340   public static void initialize(TypeDataBase db, JVMDebugger debugger) {
 341     if (soleInstance != null) {
 342       throw new RuntimeException("Attempt to initialize VM twice");
 343     }
 344     soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
 345     debugger.putHeapConst(Universe.getHeapBase(), soleInstance.getHeapOopSize(),
 346                           soleInstance.logMinObjAlignmentInBytes);
 347     for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
 348       ((Observer) iter.next()).update(null, null);
 349     }
 350   }
 351 
 352   /** This is used by the debugging system */
 353   public static void shutdown() {
 354     soleInstance = null;
 355   }
 356 
 357   /** This is used by both the debugger and any runtime system. It is
 358       the basic mechanism by which classes which mimic underlying VM
 359       functionality cause themselves to be initialized. The given
 360       observer will be notified (with arguments (null, null)) when the
 361       VM is re-initialized, as well as when it registers itself with
 362       the VM. */
 363   public static void registerVMInitializedObserver(Observer o) {
 364     vmInitializedObservers.add(o);
 365     o.update(null, null);
 366   }


 436   public String getCPU() {
 437     if (debugger != null) {
 438       return debugger.getCPU();
 439     }
 440     return PlatformInfo.getCPU();
 441   }
 442 
 443   public Type lookupType(String cTypeName) {
 444     return db.lookupType(cTypeName);
 445   }
 446 
 447   public Integer lookupIntConstant(String name) {
 448     return db.lookupIntConstant(name);
 449   }
 450 
 451   public long getAddressSize() {
 452     return db.getAddressSize();
 453   }
 454 
 455   public long getOopSize() {
 456     return oopSize;
 457   }
 458 
 459   public long getLogAddressSize() {
 460     return logAddressSize;
 461   }
 462 
 463   public long getIntSize() {
 464     return db.getJIntType().getSize();
 465   }
 466 
 467   /** NOTE: this offset is in BYTES in this system! */
 468   public long getStackBias() {
 469     return stackBias;
 470   }
 471 
 472   /** Indicates whether the underlying machine supports the LP64 data
 473       model. This is needed for conditionalizing code in a few places */
 474   public boolean isLP64() {
 475     if (Assert.ASSERTS_ENABLED) {
 476       Assert.that(isDebugging(), "Debugging system only for now");
 477     }
 478     return isLP64;
 479   }
 480 
 481   /** Get bytes-per-long == long/double natural alignment. */
 482   public int getBytesPerLong() {
 483     return bytesPerLong;
 484   }
 485 
 486   /** Get minimum object alignment in bytes. */
 487   public int getMinObjAlignment() {
 488     return minObjAlignmentInBytes;
 489   }
 490 
 491   public int getMinObjAlignmentInBytes() {
 492     return minObjAlignmentInBytes;
 493   }
 494   public int getLogMinObjAlignmentInBytes() {
 495     return logMinObjAlignmentInBytes;
 496   }
 497 
 498   public int getHeapWordSize() {
 499     return heapWordSize;
 500   }
 501 
 502   public int getHeapOopSize() {
 503     return heapOopSize;
 504   }
 505   /** Utility routine for getting data structure alignment correct */
 506   public long alignUp(long size, long alignment) {
 507     return (size + alignment - 1) & ~(alignment - 1);
 508   }
 509 
 510   /** Utility routine for getting data structure alignment correct */
 511   public long alignDown(long size, long alignment) {
 512     return size & ~(alignment - 1);
 513   }
 514 
 515   /** Utility routine for building an int from two "unsigned" 16-bit
 516       shorts */
 517   public int buildIntFromShorts(short low, short high) {
 518     return (((int) high) << 16) | (((int) low) & 0xFFFF);
 519   }
 520 
 521   /** Utility routine for building a long from two "unsigned" 32-bit
 522       ints in <b>platform-dependent</b> order */
 523   public long buildLongFromIntsPD(int oneHalf, int otherHalf) {
 524     if (isBigEndian) {


 604     if (stubRoutines == null) {
 605       stubRoutines = new StubRoutines();
 606     }
 607     return stubRoutines;
 608   }
 609 
 610   public VMRegImpl getVMRegImplInfo() {
 611     if (vmregImpl == null) {
 612       vmregImpl = new VMRegImpl();
 613     }
 614     return vmregImpl;
 615   }
 616 
 617   public Bytes getBytes() {
 618     if (bytes == null) {
 619       bytes = new Bytes(debugger.getMachineDescription());
 620     }
 621     return bytes;
 622   }
 623 
 624   /** Returns true if this is a isBigEndian, false otherwise */
 625   public boolean isBigEndian() {
 626     return isBigEndian;
 627   }
 628 
 629   /** Returns true if this is a "core" build, false if either C1 or C2
 630       is present */
 631   public boolean isCore() {
 632     return (!(usingClientCompiler || usingServerCompiler));
 633   }
 634 
 635   /** Returns true if this is a C1 build, false otherwise */
 636   public boolean isClientCompiler() {
 637     return usingClientCompiler;
 638   }
 639 
 640   /** Returns true if this is a C2 build, false otherwise */
 641   public boolean isServerCompiler() {
 642     return usingServerCompiler;
 643   }
 644 
 645   /** Returns true if C2 derived pointer table should be used, false otherwise */
 646   public boolean useDerivedPointerTable() {
 647     return !disableDerivedPrinterTableCheck;
 648   }


 720 
 721   // returns null, if not available.
 722   public String getVMRelease() {
 723     return vmRelease;
 724   }
 725 
 726   // returns null, if not available.
 727   public String getVMInternalInfo() {
 728     return vmInternalInfo;
 729   }
 730 
 731   public boolean isSharingEnabled() {
 732     if (sharingEnabled == null) {
 733       Flag flag = getCommandLineFlag("UseSharedSpaces");
 734       sharingEnabled = (flag == null)? Boolean.FALSE :
 735           (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
 736     }
 737     return sharingEnabled.booleanValue();
 738   }
 739 
 740   public boolean isCompressedOopsEnabled() {
 741     if (compressedOopsEnabled == null) {
 742         Flag flag = getCommandLineFlag("UseCompressedOops");
 743         compressedOopsEnabled = (flag == null) ? Boolean.FALSE:
 744              (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
 745     }
 746     return compressedOopsEnabled.booleanValue();
 747   }
 748 
 749   // returns null, if not available.
 750   public Flag[] getCommandLineFlags() {
 751     if (commandLineFlags == null) {
 752        readCommandLineFlags();
 753     }
 754 
 755     return commandLineFlags;
 756   }
 757 
 758   public Flag getCommandLineFlag(String name) {
 759     if (flagsMap == null) {
 760       flagsMap = new HashMap();
 761       Flag[] flags = getCommandLineFlags();
 762       for (int i = 0; i < flags.length; i++) {
 763         flagsMap.put(flags[i].getName(), flags[i]);
 764       }
 765     }
 766     return (Flag) flagsMap.get(name);
 767   }