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 }
|