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

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

mercurial