6362677: Change parallel GC collector default number of parallel GC threads.
authorjmasa
Fri Feb 22 17:17:14 2008 -0800 (21 months ago)
changeset 1028372612af5e
parent 9173195ff483a
child 113c1dbcaaab1d
6362677: Change parallel GC collector default number of parallel GC threads.
Summary: Use the same default number of GC threads as used by ParNewGC and ConcMarkSweepGC (i.e., the 5/8th rule).
Reviewed-by: ysr, tonyp
src/cpu/sparc/vm/vm_version_sparc.cpp
src/cpu/sparc/vm/vm_version_sparc.hpp
src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.hpp
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/vm_version.cpp
src/share/vm/runtime/vm_version.hpp
--- a/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Feb 22 17:17:14 2008 -0800
@@ -27,6 +27,12 @@
int VM_Version::_features = VM_Version::unknown_m;
const char* VM_Version::_features_str = "";
+
+bool VM_Version::is_niagara1_plus() {
+ // This is a placeholder until the real test is determined.
+ return is_niagara1() &&
+ (os::processor_count() > maximum_niagara1_processor_count());
+}
void VM_Version::initialize() {
_features = determine_features();
@@ -160,3 +166,13 @@ void VM_Version::revert() {
void VM_Version::revert() {
_features = saved_features;
}
+
+unsigned int VM_Version::calc_parallel_worker_threads() {
+ unsigned int result;
+ if (is_niagara1_plus()) {
+ result = nof_parallel_worker_threads(5, 16, 8);
+ } else {
+ result = nof_parallel_worker_threads(5, 8, 8);
+ }
+ return result;
+}
--- a/src/cpu/sparc/vm/vm_version_sparc.hpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/cpu/sparc/vm/vm_version_sparc.hpp Fri Feb 22 17:17:14 2008 -0800
@@ -64,6 +64,11 @@ protected:
static bool is_niagara1(int features) { return (features & niagara1_m) == niagara1_m; }
+ static int maximum_niagara1_processor_count() { return 32; }
+ // Returns true if the platform is in the niagara line and
+ // newer than the niagara1.
+ static bool is_niagara1_plus();
+
public:
// Initialization
static void initialize();
@@ -129,4 +134,7 @@ public:
// Override the Abstract_VM_Version implementation.
static uint page_size_count() { return is_sun4v() ? 4 : 2; }
+
+ // Calculates the number of parallel threads
+ static unsigned int calc_parallel_worker_threads();
};
--- a/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp Fri Feb 22 17:17:14 2008 -0800
@@ -39,10 +39,10 @@ class GenerationSizer : public TwoGenera
// If the user hasn't explicitly set the number of worker
// threads, set the count.
- if (ParallelGCThreads == 0) {
- assert(UseParallelGC, "Setting ParallelGCThreads without UseParallelGC");
- ParallelGCThreads = os::active_processor_count();
- }
+ assert(UseSerialGC ||
+ !FLAG_IS_DEFAULT(ParallelGCThreads) ||
+ (ParallelGCThreads > 0),
+ "ParallelGCThreads should be set before flag initialization");
// The survivor ratio's are calculated "raw", unlike the
// default gc, which adds 2 to the ratio value. We need to
--- a/src/share/vm/runtime/arguments.cpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/share/vm/runtime/arguments.cpp Fri Feb 22 17:17:14 2008 -0800
@@ -924,10 +924,18 @@ void Arguments::set_parnew_gc_flags() {
void Arguments::set_parnew_gc_flags() {
assert(!UseSerialGC && !UseParallelGC, "control point invariant");
+ // Turn off AdaptiveSizePolicy by default for parnew until it is
+ // complete.
+ if (UseParNewGC &&
+ FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
+ FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
+ }
+
if (FLAG_IS_DEFAULT(UseParNewGC) && ParallelGCThreads > 1) {
FLAG_SET_DEFAULT(UseParNewGC, true);
} else if (UseParNewGC && ParallelGCThreads == 0) {
- FLAG_SET_DEFAULT(ParallelGCThreads, nof_parallel_gc_threads());
+ FLAG_SET_DEFAULT(ParallelGCThreads,
+ Abstract_VM_Version::parallel_worker_threads());
if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
FLAG_SET_DEFAULT(UseParNewGC, false);
}
@@ -953,25 +961,6 @@ void Arguments::set_parnew_gc_flags() {
if (AlwaysTenure) {
FLAG_SET_CMDLINE(intx, MaxTenuringThreshold, 0);
}
- }
-}
-
-// CAUTION: this code is currently shared by UseParallelGC, UseParNewGC and
-// UseconcMarkSweepGC. Further tuning of individual collectors might
-// dictate refinement on a per-collector basis.
-int Arguments::nof_parallel_gc_threads() {
- if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
- // For very large machines, there are diminishing returns
- // for large numbers of worker threads. Instead of
- // hogging the whole system, use 5/8ths of a worker for every
- // processor after the first 8. For example, on a 72 cpu
- // machine use 8 + (72 - 8) * (5/8) == 48 worker threads.
- // This is just a start and needs further tuning and study in
- // Tiger.
- int ncpus = os::active_processor_count();
- return (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8);
- } else {
- return ParallelGCThreads;
}
}
@@ -984,26 +973,24 @@ void Arguments::set_cms_and_parnew_gc_fl
return;
}
+ assert(UseConcMarkSweepGC, "CMS is expected to be on here");
+
// If we are using CMS, we prefer to UseParNewGC,
// unless explicitly forbidden.
- if (UseConcMarkSweepGC && !UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) {
- FLAG_SET_DEFAULT(UseParNewGC, true);
+ if (!UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) {
+ FLAG_SET_ERGO(bool, UseParNewGC, true);
}
// Turn off AdaptiveSizePolicy by default for cms until it is
- // complete. Also turn it off in general if the
- // parnew collector has been selected.
- if ((UseConcMarkSweepGC || UseParNewGC) &&
- FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
+ // complete.
+ if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
}
// In either case, adjust ParallelGCThreads and/or UseParNewGC
// as needed.
- set_parnew_gc_flags();
-
- if (!UseConcMarkSweepGC) {
- return;
+ if (UseParNewGC) {
+ set_parnew_gc_flags();
}
// Now make adjustments for CMS
@@ -1147,17 +1134,11 @@ void Arguments::set_ergonomics_flags() {
FLAG_IS_DEFAULT(UseParallelGC)) {
if (should_auto_select_low_pause_collector()) {
FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
- set_cms_and_parnew_gc_flags();
} else {
FLAG_SET_ERGO(bool, UseParallelGC, true);
}
no_shared_spaces();
}
-
- // This is here because the parallel collector could
- // have been selected so this initialization should
- // still be done.
- set_parallel_gc_flags();
}
}
@@ -1170,6 +1151,9 @@ void Arguments::set_parallel_gc_flags()
// If no heap maximum was requested explicitly, use some reasonable fraction
// of the physical memory, up to a maximum of 1GB.
if (UseParallelGC) {
+ FLAG_SET_ERGO(uintx, ParallelGCThreads,
+ Abstract_VM_Version::parallel_worker_threads());
+
if (FLAG_IS_DEFAULT(MaxHeapSize)) {
const uint64_t reasonable_fraction =
os::physical_memory() / DefaultMaxRAMFraction;
@@ -1312,96 +1296,9 @@ static bool verify_serial_gc_flags() {
UseParallelOldGC));
}
-// Check the consistency of vm_init_args
-bool Arguments::check_vm_args_consistency() {
- // Method for adding checks for flag consistency.
- // The intent is to warn the user of all possible conflicts,
- // before returning an error.
- // Note: Needs platform-dependent factoring.
+// Check consistency of GC selection
+bool Arguments::check_gc_consistency() {
bool status = true;
-
-#if ( (defined(COMPILER2) && defined(SPARC)))
- // NOTE: The call to VM_Version_init depends on the fact that VM_Version_init
- // on sparc doesn't require generation of a stub as is the case on, e.g.,
- // x86. Normally, VM_Version_init must be called from init_globals in
- // init.cpp, which is called by the initial java thread *after* arguments
- // have been parsed. VM_Version_init gets called twice on sparc.
- extern void VM_Version_init();
- VM_Version_init();
- if (!VM_Version::has_v9()) {
- jio_fprintf(defaultStream::error_stream(),
- "V8 Machine detected, Server requires V9\n");
- status = false;
- }
-#endif /* COMPILER2 && SPARC */
-
- // Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product
- // builds so the cost of stack banging can be measured.
-#if (defined(PRODUCT) && defined(SOLARIS))
- if (!UseBoundThreads && !UseStackBanging) {
- jio_fprintf(defaultStream::error_stream(),
- "-UseStackBanging conflicts with -UseBoundThreads\n");
-
- status = false;
- }
-#endif
-
- if (TLABRefillWasteFraction == 0) {
- jio_fprintf(defaultStream::error_stream(),
- "TLABRefillWasteFraction should be a denominator, "
- "not " SIZE_FORMAT "\n",
- TLABRefillWasteFraction);
- status = false;
- }
-
- status &= verify_percentage(MaxLiveObjectEvacuationRatio,
- "MaxLiveObjectEvacuationRatio");
- status &= verify_percentage(AdaptiveSizePolicyWeight,
- "AdaptiveSizePolicyWeight");
- status &= verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight");
- status &= verify_percentage(ThresholdTolerance, "ThresholdTolerance");
- status &= verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
- status &= verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
-
- if (MinHeapFreeRatio > MaxHeapFreeRatio) {
- jio_fprintf(defaultStream::error_stream(),
- "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
- "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
- MinHeapFreeRatio, MaxHeapFreeRatio);
- status = false;
- }
- // Keeping the heap 100% free is hard ;-) so limit it to 99%.
- MinHeapFreeRatio = MIN2(MinHeapFreeRatio, (uintx) 99);
-
- if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) {
- MarkSweepAlwaysCompactCount = 1; // Move objects every gc.
- }
-
- status &= verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
- status &= verify_percentage(GCTimeLimit, "GCTimeLimit");
- if (GCTimeLimit == 100) {
- // Turn off gc-overhead-limit-exceeded checks
- FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
- }
-
- status &= verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
-
- // Check user specified sharing option conflict with Parallel GC
- bool cannot_share = (UseConcMarkSweepGC || UseParallelGC ||
- UseParallelOldGC || UseParNewGC ||
- SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages));
-
- if (cannot_share) {
- // Either force sharing on by forcing the other options off, or
- // force sharing off.
- if (DumpSharedSpaces || ForceSharedSpaces) {
- set_serial_gc_flags();
- FLAG_SET_DEFAULT(SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages), false);
- } else {
- no_shared_spaces();
- }
- }
-
// Ensure that the user has not selected conflicting sets
// of collectors. [Note: this check is merely a user convenience;
// collectors over-ride each other so that only a non-conflicting
@@ -1421,6 +1318,101 @@ bool Arguments::check_vm_args_consistenc
status = false;
}
+ return status;
+}
+
+// Check the consistency of vm_init_args
+bool Arguments::check_vm_args_consistency() {
+ // Method for adding checks for flag consistency.
+ // The intent is to warn the user of all possible conflicts,
+ // before returning an error.
+ // Note: Needs platform-dependent factoring.
+ bool status = true;
+
+#if ( (defined(COMPILER2) && defined(SPARC)))
+ // NOTE: The call to VM_Version_init depends on the fact that VM_Version_init
+ // on sparc doesn't require generation of a stub as is the case on, e.g.,
+ // x86. Normally, VM_Version_init must be called from init_globals in
+ // init.cpp, which is called by the initial java thread *after* arguments
+ // have been parsed. VM_Version_init gets called twice on sparc.
+ extern void VM_Version_init();
+ VM_Version_init();
+ if (!VM_Version::has_v9()) {
+ jio_fprintf(defaultStream::error_stream(),
+ "V8 Machine detected, Server requires V9\n");
+ status = false;
+ }
+#endif /* COMPILER2 && SPARC */
+
+ // Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product
+ // builds so the cost of stack banging can be measured.
+#if (defined(PRODUCT) && defined(SOLARIS))
+ if (!UseBoundThreads && !UseStackBanging) {
+ jio_fprintf(defaultStream::error_stream(),
+ "-UseStackBanging conflicts with -UseBoundThreads\n");
+
+ status = false;
+ }
+#endif
+
+ if (TLABRefillWasteFraction == 0) {
+ jio_fprintf(defaultStream::error_stream(),
+ "TLABRefillWasteFraction should be a denominator, "
+ "not " SIZE_FORMAT "\n",
+ TLABRefillWasteFraction);
+ status = false;
+ }
+
+ status = status && verify_percentage(MaxLiveObjectEvacuationRatio,
+ "MaxLiveObjectEvacuationRatio");
+ status = status && verify_percentage(AdaptiveSizePolicyWeight,
+ "AdaptiveSizePolicyWeight");
+ status = status && verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight");
+ status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
+ status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
+ status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
+
+ if (MinHeapFreeRatio > MaxHeapFreeRatio) {
+ jio_fprintf(defaultStream::error_stream(),
+ "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
+ "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
+ MinHeapFreeRatio, MaxHeapFreeRatio);
+ status = false;
+ }
+ // Keeping the heap 100% free is hard ;-) so limit it to 99%.
+ MinHeapFreeRatio = MIN2(MinHeapFreeRatio, (uintx) 99);
+
+ if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) {
+ MarkSweepAlwaysCompactCount = 1; // Move objects every gc.
+ }
+
+ status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
+ status = status && verify_percentage(GCTimeLimit, "GCTimeLimit");
+ if (GCTimeLimit == 100) {
+ // Turn off gc-overhead-limit-exceeded checks
+ FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
+ }
+
+ status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
+
+ // Check user specified sharing option conflict with Parallel GC
+ bool cannot_share = (UseConcMarkSweepGC || UseParallelGC ||
+ UseParallelOldGC || UseParNewGC ||
+ SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages));
+
+ if (cannot_share) {
+ // Either force sharing on by forcing the other options off, or
+ // force sharing off.
+ if (DumpSharedSpaces || ForceSharedSpaces) {
+ set_serial_gc_flags();
+ FLAG_SET_DEFAULT(SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages), false);
+ } else {
+ no_shared_spaces();
+ }
+ }
+
+ status = status && check_gc_consistency();
+
if (_has_alloc_profile) {
if (UseParallelGC || UseParallelOldGC) {
jio_fprintf(defaultStream::error_stream(),
@@ -1451,15 +1443,15 @@ bool Arguments::check_vm_args_consistenc
"allocation buffers\n(-XX:+UseTLAB).\n");
status = false;
} else {
- status &= verify_percentage(CMSIncrementalDutyCycle,
+ status = status && verify_percentage(CMSIncrementalDutyCycle,
"CMSIncrementalDutyCycle");
- status &= verify_percentage(CMSIncrementalDutyCycleMin,
+ status = status && verify_percentage(CMSIncrementalDutyCycleMin,
"CMSIncrementalDutyCycleMin");
- status &= verify_percentage(CMSIncrementalSafetyFactor,
+ status = status && verify_percentage(CMSIncrementalSafetyFactor,
"CMSIncrementalSafetyFactor");
- status &= verify_percentage(CMSIncrementalOffset,
+ status = status && verify_percentage(CMSIncrementalOffset,
"CMSIncrementalOffset");
- status &= verify_percentage(CMSExpAvgFactor,
+ status = status && verify_percentage(CMSExpAvgFactor,
"CMSExpAvgFactor");
// If it was not set on the command line, set
// CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early.
@@ -2064,7 +2056,8 @@ jint Arguments::parse_each_vm_init_arg(c
// Enable parallel GC and adaptive generation sizing
FLAG_SET_CMDLINE(bool, UseParallelGC, true);
- FLAG_SET_DEFAULT(ParallelGCThreads, nof_parallel_gc_threads());
+ FLAG_SET_DEFAULT(ParallelGCThreads,
+ Abstract_VM_Version::parallel_worker_threads());
// Encourage steady state memory management
FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
@@ -2451,14 +2444,24 @@ jint Arguments::parse(const JavaVMInitAr
no_shared_spaces();
#endif // KERNEL
- // Set some flags for ParallelGC if needed.
- set_parallel_gc_flags();
-
- // Set some flags for CMS and/or ParNew collectors, as needed.
- set_cms_and_parnew_gc_flags();
-
// Set flags based on ergonomics.
set_ergonomics_flags();
+
+ // Check the GC selections again.
+ if (!check_gc_consistency()) {
+ return JNI_EINVAL;
+ }
+
+ if (UseParallelGC) {
+ // Set some flags for ParallelGC if needed.
+ set_parallel_gc_flags();
+ } else if (UseConcMarkSweepGC) {
+ // Set some flags for CMS
+ set_cms_and_parnew_gc_flags();
+ } else if (UseParNewGC) {
+ // Set some flags for ParNew
+ set_parnew_gc_flags();
+ }
#ifdef SERIALGC
assert(verify_serial_gc_flags(), "SerialGC unset");
@@ -2478,6 +2481,12 @@ jint Arguments::parse(const JavaVMInitAr
if (PrintCommandLineFlags) {
CommandLineFlags::printSetFlags();
}
+
+#ifdef ASSERT
+ if (PrintFlagsFinal) {
+ CommandLineFlags::printFlags();
+ }
+#endif
return JNI_OK;
}
--- a/src/share/vm/runtime/arguments.hpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/share/vm/runtime/arguments.hpp Fri Feb 22 17:17:14 2008 -0800
@@ -291,8 +291,6 @@ class Arguments : AllStatic {
static bool _CIDynamicCompilePriority;
static intx _Tier2CompileThreshold;
- // GC processing
- static int nof_parallel_gc_threads();
// CMS/ParNew garbage collectors
static void set_parnew_gc_flags();
static void set_cms_and_parnew_gc_flags();
@@ -385,6 +383,8 @@ class Arguments : AllStatic {
public:
// Parses the arguments
static jint parse(const JavaVMInitArgs* args);
+ // Check for consistency in the selection of the garbage collector.
+ static bool check_gc_consistency();
// Check consistecy or otherwise of VM argument settings
static bool check_vm_args_consistency();
// Used by os_solaris
--- a/src/share/vm/runtime/globals.hpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/share/vm/runtime/globals.hpp Fri Feb 22 17:17:14 2008 -0800
@@ -1794,6 +1794,9 @@ class CommandLineFlags {
"number of times a GC thread (minus the coordinator) " \
"will sleep while yielding before giving up and resuming GC") \
\
+ notproduct(bool, PrintFlagsFinal, false, \
+ "Print all command line flags after argument processing") \
+ \
/* gc tracing */ \
manageable(bool, PrintGC, false, \
"Print message at garbage collect") \
--- a/src/share/vm/runtime/vm_version.cpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/share/vm/runtime/vm_version.cpp Fri Feb 22 17:17:14 2008 -0800
@@ -52,6 +52,8 @@ int Abstract_VM_Version::_vm_minor_versi
int Abstract_VM_Version::_vm_minor_version = 0;
int Abstract_VM_Version::_vm_build_number = 0;
bool Abstract_VM_Version::_initialized = false;
+int Abstract_VM_Version::_parallel_worker_threads = 0;
+bool Abstract_VM_Version::_parallel_worker_threads_initialized = false;
void Abstract_VM_Version::initialize() {
if (_initialized) {
@@ -210,3 +212,43 @@ void VM_Version_init() {
}
#endif
}
+
+unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
+ unsigned int num,
+ unsigned int den,
+ unsigned int switch_pt) {
+ if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+ assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0");
+ // For very large machines, there are diminishing returns
+ // for large numbers of worker threads. Instead of
+ // hogging the whole system, use a fraction of the workers for every
+ // processor after the first 8. For example, on a 72 cpu machine
+ // and a chosen fraction of 5/8
+ // use 8 + (72 - 8) * (5/8) == 48 worker threads.
+ unsigned int ncpus = (unsigned int) os::active_processor_count();
+ return (ncpus <= switch_pt) ?
+ ncpus :
+ (switch_pt + ((ncpus - switch_pt) * num) / den);
+ } else {
+ return ParallelGCThreads;
+ }
+}
+
+unsigned int Abstract_VM_Version::calc_parallel_worker_threads() {
+ return nof_parallel_worker_threads(5, 8, 8);
+}
+
+
+// Does not set the _initialized flag since it is
+// a global flag.
+unsigned int Abstract_VM_Version::parallel_worker_threads() {
+ if (!_parallel_worker_threads_initialized) {
+ if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+ _parallel_worker_threads = VM_Version::calc_parallel_worker_threads();
+ } else {
+ _parallel_worker_threads = ParallelGCThreads;
+ }
+ _parallel_worker_threads_initialized = true;
+ }
+ return _parallel_worker_threads;
+}
--- a/src/share/vm/runtime/vm_version.hpp Thu Feb 21 11:03:54 2008 -0800
+++ b/src/share/vm/runtime/vm_version.hpp Fri Feb 22 17:17:14 2008 -0800
@@ -36,6 +36,12 @@ class Abstract_VM_Version: AllStatic {
static int _vm_minor_version;
static int _vm_build_number;
static bool _initialized;
+ static int _parallel_worker_threads;
+ static bool _parallel_worker_threads_initialized;
+
+ static unsigned int nof_parallel_worker_threads(unsigned int num,
+ unsigned int dem,
+ unsigned int switch_pt);
public:
static void initialize();
@@ -69,4 +75,13 @@ class Abstract_VM_Version: AllStatic {
// subclasses should define new versions to hide this one as needed. Note
// that the O/S may support more sizes, but at most this many are used.
static uint page_size_count() { return 2; }
+
+ // Returns the number of parallel threads to be used for VM
+ // work. If that number has not been calculated, do so and
+ // save it. Returns ParallelGCThreads if it is set on the
+ // command line.
+ static unsigned int parallel_worker_threads();
+ // Calculates and returns the number of parallel threads. May
+ // be VM version specific.
+ static unsigned int calc_parallel_worker_threads();
};