--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Thu Aug 20 09:31:28 2015 +0200
@@ -209,4 +209,7 @@
returns the result as an Address. Returns null if the result was
zero. */
public Address xorWithMask(long mask) throws UnsupportedOperationException;
+
+ // return address as long integer.
+ public long asLongValue();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java Thu Aug 20 09:31:28 2015 +0200
@@ -288,7 +288,7 @@
return new BsdAddress(debugger, value);
}
-
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Thu Aug 20 09:31:28 2015 +0200
@@ -275,6 +275,7 @@
return new DummyAddress(debugger, value);
}
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Thu Aug 20 09:31:28 2015 +0200
@@ -288,6 +288,7 @@
return new LinuxAddress(debugger, value);
}
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Thu Aug 20 09:31:28 2015 +0200
@@ -283,7 +283,7 @@
return new ProcAddress(debugger, value);
}
-
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Thu Aug 20 09:31:28 2015 +0200
@@ -281,7 +281,7 @@
return new RemoteAddress(debugger, value);
}
-
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Thu Aug 20 09:31:28 2015 +0200
@@ -292,6 +292,7 @@
return new WindbgAddress(debugger, value);
}
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Thu Aug 20 09:31:28 2015 +0200
@@ -80,10 +80,19 @@
public byte getByteAt(long index) {
return addr.getJByteAt(baseOffset + index);
}
-
+ // _identity_hash is a short
private static CIntegerField idHash;
- public int identityHash() { return (int)idHash.getValue(this.addr); }
+ public int identityHash() {
+ long addr_value = getAddress().asLongValue();
+ int addr_bits = (int)(addr_value >> (VM.getVM().getLogMinObjAlignmentInBytes() + 3));
+ int length = (int)getLength();
+ int byte0 = getByteAt(0);
+ int byte1 = getByteAt(1);
+ int id_hash = (int)(0xffff & idHash.getValue(this.addr));
+ return id_hash |
+ ((addr_bits ^ (length << 8) ^ ((byte0 << 8) | byte1)) << 16);
+ }
public boolean equals(byte[] modUTF8Chars) {
int l = (int) getLength();
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -2014,6 +2014,7 @@
__ pop(rcx);
__ pop(rdx);
__ movptr(rax, Address(rcx, Method::method_counters_offset()));
+ __ testptr(rax, rax);
__ jcc(Assembler::zero, dispatch);
__ bind(has_counters);
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -5785,9 +5785,11 @@
status = pthread_mutex_unlock(_mutex);
assert(status == 0, "invariant");
} else {
+ // must capture correct index before unlocking
+ int index = _cur_index;
status = pthread_mutex_unlock(_mutex);
assert(status == 0, "invariant");
- status = pthread_cond_signal(&_cond[_cur_index]);
+ status = pthread_cond_signal(&_cond[index]);
assert(status == 0, "invariant");
}
} else {
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -2680,187 +2680,3 @@
#endif // INCLUDE_TRACE
}
-#ifndef PRODUCT
-
-// statistics code
-class ClassStatistics: AllStatic {
- private:
- static int nclasses; // number of classes
- static int nmethods; // number of methods
- static int nmethoddata; // number of methodData
- static int class_size; // size of class objects in words
- static int method_size; // size of method objects in words
- static int debug_size; // size of debug info in methods
- static int methoddata_size; // size of methodData objects in words
-
- static void do_class(Klass* k) {
- nclasses++;
- class_size += k->size();
- if (k->oop_is_instance()) {
- InstanceKlass* ik = (InstanceKlass*)k;
- class_size += ik->methods()->size();
- class_size += ik->constants()->size();
- class_size += ik->local_interfaces()->size();
- class_size += ik->transitive_interfaces()->size();
- // We do not have to count implementors, since we only store one!
- // SSS: How should these be accounted now that they have moved?
- // class_size += ik->fields()->length();
- }
- }
-
- static void do_method(Method* m) {
- nmethods++;
- method_size += m->size();
- // class loader uses same objArray for empty vectors, so don't count these
- if (m->has_stackmap_table()) {
- method_size += m->stackmap_data()->size();
- }
-
- MethodData* mdo = m->method_data();
- if (mdo != NULL) {
- nmethoddata++;
- methoddata_size += mdo->size();
- }
- }
-
- public:
- static void print() {
- SystemDictionary::classes_do(do_class);
- SystemDictionary::methods_do(do_method);
- tty->print_cr("Class statistics:");
- tty->print_cr("%d classes (%d bytes)", nclasses, class_size * oopSize);
- tty->print_cr("%d methods (%d bytes = %d base + %d debug info)", nmethods,
- (method_size + debug_size) * oopSize, method_size * oopSize, debug_size * oopSize);
- tty->print_cr("%d methoddata (%d bytes)", nmethoddata, methoddata_size * oopSize);
- }
-};
-
-
-int ClassStatistics::nclasses = 0;
-int ClassStatistics::nmethods = 0;
-int ClassStatistics::nmethoddata = 0;
-int ClassStatistics::class_size = 0;
-int ClassStatistics::method_size = 0;
-int ClassStatistics::debug_size = 0;
-int ClassStatistics::methoddata_size = 0;
-
-void SystemDictionary::print_class_statistics() {
- ResourceMark rm;
- ClassStatistics::print();
-}
-
-
-class MethodStatistics: AllStatic {
- public:
- enum {
- max_parameter_size = 10
- };
- private:
-
- static int _number_of_methods;
- static int _number_of_final_methods;
- static int _number_of_static_methods;
- static int _number_of_native_methods;
- static int _number_of_synchronized_methods;
- static int _number_of_profiled_methods;
- static int _number_of_bytecodes;
- static int _parameter_size_profile[max_parameter_size];
- static int _bytecodes_profile[Bytecodes::number_of_java_codes];
-
- static void initialize() {
- _number_of_methods = 0;
- _number_of_final_methods = 0;
- _number_of_static_methods = 0;
- _number_of_native_methods = 0;
- _number_of_synchronized_methods = 0;
- _number_of_profiled_methods = 0;
- _number_of_bytecodes = 0;
- for (int i = 0; i < max_parameter_size ; i++) _parameter_size_profile[i] = 0;
- for (int j = 0; j < Bytecodes::number_of_java_codes; j++) _bytecodes_profile [j] = 0;
- };
-
- static void do_method(Method* m) {
- _number_of_methods++;
- // collect flag info
- if (m->is_final() ) _number_of_final_methods++;
- if (m->is_static() ) _number_of_static_methods++;
- if (m->is_native() ) _number_of_native_methods++;
- if (m->is_synchronized()) _number_of_synchronized_methods++;
- if (m->method_data() != NULL) _number_of_profiled_methods++;
- // collect parameter size info (add one for receiver, if any)
- _parameter_size_profile[MIN2(m->size_of_parameters() + (m->is_static() ? 0 : 1), max_parameter_size - 1)]++;
- // collect bytecodes info
- {
- Thread *thread = Thread::current();
- HandleMark hm(thread);
- BytecodeStream s(methodHandle(thread, m));
- Bytecodes::Code c;
- while ((c = s.next()) >= 0) {
- _number_of_bytecodes++;
- _bytecodes_profile[c]++;
- }
- }
- }
-
- public:
- static void print() {
- initialize();
- SystemDictionary::methods_do(do_method);
- // generate output
- tty->cr();
- tty->print_cr("Method statistics (static):");
- // flag distribution
- tty->cr();
- tty->print_cr("%6d final methods %6.1f%%", _number_of_final_methods , _number_of_final_methods * 100.0F / _number_of_methods);
- tty->print_cr("%6d static methods %6.1f%%", _number_of_static_methods , _number_of_static_methods * 100.0F / _number_of_methods);
- tty->print_cr("%6d native methods %6.1f%%", _number_of_native_methods , _number_of_native_methods * 100.0F / _number_of_methods);
- tty->print_cr("%6d synchronized methods %6.1f%%", _number_of_synchronized_methods, _number_of_synchronized_methods * 100.0F / _number_of_methods);
- tty->print_cr("%6d profiled methods %6.1f%%", _number_of_profiled_methods, _number_of_profiled_methods * 100.0F / _number_of_methods);
- // parameter size profile
- tty->cr();
- { int tot = 0;
- int avg = 0;
- for (int i = 0; i < max_parameter_size; i++) {
- int n = _parameter_size_profile[i];
- tot += n;
- avg += n*i;
- tty->print_cr("parameter size = %1d: %6d methods %5.1f%%", i, n, n * 100.0F / _number_of_methods);
- }
- assert(tot == _number_of_methods, "should be the same");
- tty->print_cr(" %6d methods 100.0%%", _number_of_methods);
- tty->print_cr("(average parameter size = %3.1f including receiver, if any)", (float)avg / _number_of_methods);
- }
- // bytecodes profile
- tty->cr();
- { int tot = 0;
- for (int i = 0; i < Bytecodes::number_of_java_codes; i++) {
- if (Bytecodes::is_defined(i)) {
- Bytecodes::Code c = Bytecodes::cast(i);
- int n = _bytecodes_profile[c];
- tot += n;
- tty->print_cr("%9d %7.3f%% %s", n, n * 100.0F / _number_of_bytecodes, Bytecodes::name(c));
- }
- }
- assert(tot == _number_of_bytecodes, "should be the same");
- tty->print_cr("%9d 100.000%%", _number_of_bytecodes);
- }
- tty->cr();
- }
-};
-
-int MethodStatistics::_number_of_methods;
-int MethodStatistics::_number_of_final_methods;
-int MethodStatistics::_number_of_static_methods;
-int MethodStatistics::_number_of_native_methods;
-int MethodStatistics::_number_of_synchronized_methods;
-int MethodStatistics::_number_of_profiled_methods;
-int MethodStatistics::_number_of_bytecodes;
-int MethodStatistics::_parameter_size_profile[MethodStatistics::max_parameter_size];
-int MethodStatistics::_bytecodes_profile[Bytecodes::number_of_java_codes];
-
-
-void SystemDictionary::print_method_statistics() {
- MethodStatistics::print();
-}
-
-#endif // PRODUCT
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -366,8 +366,6 @@
// Printing
static void print(bool details = true);
static void print_shared(bool details = true);
- static void print_class_statistics() PRODUCT_RETURN;
- static void print_method_statistics() PRODUCT_RETURN;
// Number of contained klasses
// This is both fully loaded classes and classes in the process
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -620,7 +620,7 @@
// Support for parallelizing survivor space rescan
if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
const size_t max_plab_samples =
- _young_gen->max_survivor_size() / (ThreadLocalAllocBuffer::min_size() * HeapWordSize);
+ _young_gen->max_survivor_size() / (PLAB::min_size() * HeapWordSize);
_survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC);
_survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples, mtGC);
@@ -3005,7 +3005,7 @@
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
if (CMSParallelInitialMarkEnabled) {
// The parallel version.
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
uint n_workers = workers->active_workers();
@@ -4488,7 +4488,7 @@
// workers to be taken from the active workers in the work gang.
CMSParRemarkTask(CMSCollector* collector,
CompactibleFreeListSpace* cms_space,
- uint n_workers, FlexibleWorkGang* workers,
+ uint n_workers, WorkGang* workers,
OopTaskQueueSet* task_queues,
StrongRootsScope* strong_roots_scope):
CMSParMarkTask("Rescan roots and grey objects in parallel",
@@ -5061,7 +5061,7 @@
// Parallel version of remark
void CMSCollector::do_remark_parallel() {
GenCollectedHeap* gch = GenCollectedHeap::heap();
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
// Choose to use the number of GC workers most recently set
// into "active_workers".
@@ -5236,6 +5236,16 @@
////////////////////////////////////////////////////////
// Parallel Reference Processing Task Proxy Class
////////////////////////////////////////////////////////
+class AbstractGangTaskWOopQueues : public AbstractGangTask {
+ OopTaskQueueSet* _queues;
+ ParallelTaskTerminator _terminator;
+ public:
+ AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues, uint n_threads) :
+ AbstractGangTask(name), _queues(queues), _terminator(n_threads, _queues) {}
+ ParallelTaskTerminator* terminator() { return &_terminator; }
+ OopTaskQueueSet* queues() { return _queues; }
+};
+
class CMSRefProcTaskProxy: public AbstractGangTaskWOopQueues {
typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
CMSCollector* _collector;
@@ -5372,7 +5382,7 @@
void CMSRefProcTaskExecutor::execute(ProcessTask& task)
{
GenCollectedHeap* gch = GenCollectedHeap::heap();
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
CMSRefProcTaskProxy rp_task(task, &_collector,
_collector.ref_processor()->span(),
@@ -5385,7 +5395,7 @@
{
GenCollectedHeap* gch = GenCollectedHeap::heap();
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
CMSRefEnqueueTaskProxy enq_task(task);
workers->run_task(&enq_task);
@@ -5419,7 +5429,7 @@
// balance_all_queues() and balance_queues()).
GenCollectedHeap* gch = GenCollectedHeap::heap();
uint active_workers = ParallelGCThreads;
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
if (workers != NULL) {
active_workers = workers->active_workers();
// The expectation is that active_workers will have already
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -803,7 +803,7 @@
void ParNewRefProcTaskExecutor::execute(ProcessTask& task)
{
GenCollectedHeap* gch = GenCollectedHeap::heap();
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
_state_set.reset(workers->active_workers(), _young_gen.promotion_failed());
ParNewRefProcTaskProxy rp_task(task, _young_gen, _old_gen,
@@ -816,7 +816,7 @@
void ParNewRefProcTaskExecutor::execute(EnqueueTask& task)
{
GenCollectedHeap* gch = GenCollectedHeap::heap();
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
ParNewRefEnqueueTaskProxy enq_task(task);
workers->run_task(&enq_task);
@@ -890,7 +890,7 @@
_gc_timer->register_gc_start();
AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
- FlexibleWorkGang* workers = gch->workers();
+ WorkGang* workers = gch->workers();
assert(workers != NULL, "Need workgang for parallel work");
uint active_workers =
AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
--- a/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -26,20 +26,45 @@
#include "gc/cms/yieldingWorkgroup.hpp"
#include "utilities/macros.hpp"
-// Forward declaration of classes declared here.
-
-class GangWorker;
-class WorkData;
+YieldingFlexibleGangWorker::YieldingFlexibleGangWorker(YieldingFlexibleWorkGang* gang, int id)
+ : AbstractGangWorker(gang, id) {}
YieldingFlexibleWorkGang::YieldingFlexibleWorkGang(
- const char* name, uint workers, bool are_GC_task_threads) :
- FlexibleWorkGang(name, workers, are_GC_task_threads, false),
- _yielded_workers(0) {}
+ const char* name, uint workers, bool are_GC_task_threads) :
+ AbstractWorkGang(name, workers, are_GC_task_threads, false),
+ _yielded_workers(0),
+ _started_workers(0),
+ _finished_workers(0),
+ _sequence_number(0),
+ _task(NULL) {
+
+ // Other initialization.
+ _monitor = new Monitor(/* priority */ Mutex::leaf,
+ /* name */ "WorkGroup monitor",
+ /* allow_vm_block */ are_GC_task_threads,
+ Monitor::_safepoint_check_sometimes);
+
+ assert(monitor() != NULL, "Failed to allocate monitor");
+}
-GangWorker* YieldingFlexibleWorkGang::allocate_worker(uint which) {
- YieldingFlexibleGangWorker* new_member =
- new YieldingFlexibleGangWorker(this, which);
- return (YieldingFlexibleGangWorker*) new_member;
+AbstractGangWorker* YieldingFlexibleWorkGang::allocate_worker(uint which) {
+ return new YieldingFlexibleGangWorker(this, which);
+}
+
+void YieldingFlexibleWorkGang::internal_worker_poll(YieldingWorkData* data) const {
+ assert(data != NULL, "worker data is null");
+ data->set_task(task());
+ data->set_sequence_number(sequence_number());
+}
+
+void YieldingFlexibleWorkGang::internal_note_start() {
+ assert(monitor()->owned_by_self(), "note_finish is an internal method");
+ _started_workers += 1;
+}
+
+void YieldingFlexibleWorkGang::internal_note_finish() {
+ assert(monitor()->owned_by_self(), "note_finish is an internal method");
+ _finished_workers += 1;
}
// Run a task; returns when the task is done, or the workers yield,
@@ -292,37 +317,37 @@
///////////////////////////////
void YieldingFlexibleGangWorker::loop() {
int previous_sequence_number = 0;
- Monitor* gang_monitor = gang()->monitor();
+ Monitor* gang_monitor = yf_gang()->monitor();
MutexLockerEx ml(gang_monitor, Mutex::_no_safepoint_check_flag);
- WorkData data;
+ YieldingWorkData data;
int id;
while (true) {
// Check if there is work to do.
- gang()->internal_worker_poll(&data);
+ yf_gang()->internal_worker_poll(&data);
if (data.task() != NULL && data.sequence_number() != previous_sequence_number) {
// There is work to be done.
// First check if we need to become active or if there
// are already the requisite number of workers
- if (gang()->started_workers() == yf_gang()->active_workers()) {
+ if (yf_gang()->started_workers() == yf_gang()->active_workers()) {
// There are already enough workers, we do not need to
// to run; fall through and wait on monitor.
} else {
// We need to pitch in and do the work.
- assert(gang()->started_workers() < yf_gang()->active_workers(),
+ assert(yf_gang()->started_workers() < yf_gang()->active_workers(),
"Unexpected state");
- id = gang()->started_workers();
- gang()->internal_note_start();
+ id = yf_gang()->started_workers();
+ yf_gang()->internal_note_start();
// Now, release the gang mutex and do the work.
{
MutexUnlockerEx mul(gang_monitor, Mutex::_no_safepoint_check_flag);
data.task()->work(id); // This might include yielding
}
// Reacquire monitor and note completion of this worker
- gang()->internal_note_finish();
+ yf_gang()->internal_note_finish();
// Update status of task based on whether all workers have
// finished or some have yielded
- assert(data.task() == gang()->task(), "Confused task binding");
- if (gang()->finished_workers() == yf_gang()->active_workers()) {
+ assert(data.task() == yf_gang()->task(), "Confused task binding");
+ if (yf_gang()->finished_workers() == yf_gang()->active_workers()) {
switch (data.yf_task()->status()) {
case ABORTING: {
data.yf_task()->set_status(ABORTED);
@@ -338,7 +363,7 @@
}
gang_monitor->notify_all(); // Notify overseer
} else { // at least one worker is still working or yielded
- assert(gang()->finished_workers() < yf_gang()->active_workers(),
+ assert(yf_gang()->finished_workers() < yf_gang()->active_workers(),
"Counts inconsistent");
switch (data.yf_task()->status()) {
case ACTIVE: {
@@ -347,7 +372,7 @@
break;
}
case YIELDING: {
- if (gang()->finished_workers() + yf_gang()->yielded_workers()
+ if (yf_gang()->finished_workers() + yf_gang()->yielded_workers()
== yf_gang()->active_workers()) {
data.yf_task()->set_status(YIELDED);
gang_monitor->notify_all(); // notify overseer
--- a/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/cms/yieldingWorkgroup.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -29,6 +29,7 @@
#include "utilities/macros.hpp"
// Forward declarations
+class YieldingFlexibleGangTask;
class YieldingFlexibleWorkGang;
// Status of tasks
@@ -43,13 +44,32 @@
COMPLETED
};
+class YieldingWorkData: public StackObj {
+ // This would be a struct, but I want accessor methods.
+private:
+ AbstractGangTask* _task;
+ int _sequence_number;
+public:
+ // Constructor and destructor
+ YieldingWorkData() : _task(NULL), _sequence_number(0) {}
+ ~YieldingWorkData() {}
+
+ // Accessors and modifiers
+ AbstractGangTask* task() const { return _task; }
+ void set_task(AbstractGangTask* value) { _task = value; }
+ int sequence_number() const { return _sequence_number; }
+ void set_sequence_number(int value) { _sequence_number = value; }
+
+ YieldingFlexibleGangTask* yf_task() const {
+ return (YieldingFlexibleGangTask*)_task;
+ }
+};
+
// Class YieldingFlexibleGangWorker:
// Several instances of this class run in parallel as workers for a gang.
-class YieldingFlexibleGangWorker: public GangWorker {
+class YieldingFlexibleGangWorker: public AbstractGangWorker {
public:
- // Ctor
- YieldingFlexibleGangWorker(AbstractWorkGang* gang, int id) :
- GangWorker(gang, id) { }
+ YieldingFlexibleGangWorker(YieldingFlexibleWorkGang* gang, int id);
public:
YieldingFlexibleWorkGang* yf_gang() const
@@ -108,9 +128,6 @@
friend class YieldingFlexibleWorkGang;
friend class YieldingFlexibleGangWorker;
- NOT_PRODUCT(virtual bool is_YieldingFlexibleGang_task() const {
- return true;
- })
void set_status(Status s) {
_status = s;
@@ -160,7 +177,7 @@
// YieldingGangWorkers, and provides infrastructure
// supporting yielding to the "GangOverseer",
// being the thread that orchestrates the WorkGang via run_task().
-class YieldingFlexibleWorkGang: public FlexibleWorkGang {
+class YieldingFlexibleWorkGang: public AbstractWorkGang {
// Here's the public interface to this class.
public:
// Constructor and destructor.
@@ -168,12 +185,10 @@
bool are_GC_task_threads);
YieldingFlexibleGangTask* yielding_task() const {
- assert(task() == NULL || task()->is_YieldingFlexibleGang_task(),
- "Incorrect cast");
- return (YieldingFlexibleGangTask*)task();
+ return task();
}
// Allocate a worker and return a pointer to it.
- GangWorker* allocate_worker(uint which);
+ AbstractGangWorker* allocate_worker(uint which);
// Run a task; returns when the task is done, or the workers yield,
// or the task is aborted.
@@ -216,6 +231,42 @@
private:
friend class YieldingFlexibleGangWorker;
void reset(); // NYI
+
+
+ // The monitor which protects these data,
+ // and notifies of changes in it.
+ Monitor* _monitor;
+ // Accessors for fields
+ Monitor* monitor() const {
+ return _monitor;
+ }
+
+ // The number of started workers.
+ uint _started_workers;
+ // The number of finished workers.
+ uint _finished_workers;
+
+ uint started_workers() const {
+ return _started_workers;
+ }
+ uint finished_workers() const {
+ return _finished_workers;
+ }
+
+ // A sequence number for the current task.
+ int _sequence_number;
+ int sequence_number() const {
+ return _sequence_number;
+ }
+
+ YieldingFlexibleGangTask* _task;
+ YieldingFlexibleGangTask* task() const {
+ return _task;
+ }
+
+ void internal_worker_poll(YieldingWorkData* data) const;
+ void internal_note_start();
+ void internal_note_finish();
};
#endif // SHARE_VM_GC_CMS_YIELDINGWORKGROUP_HPP
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -629,7 +629,7 @@
gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor());
#endif
- _parallel_workers = new FlexibleWorkGang("G1 Marker",
+ _parallel_workers = new WorkGang("G1 Marker",
_max_parallel_marking_threads, false, true);
if (_parallel_workers == NULL) {
vm_exit_during_initialization("Failed necessary allocation.");
@@ -3088,29 +3088,6 @@
}
#endif
-template<bool scan>
-inline void CMTask::process_grey_object(oop obj) {
- assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
- assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
-
- if (_cm->verbose_high()) {
- gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT,
- _worker_id, p2i((void*) obj));
- }
-
- size_t obj_size = obj->size();
- _words_scanned += obj_size;
-
- if (scan) {
- obj->oop_iterate(_cm_oop_closure);
- }
- statsOnly( ++_objs_scanned );
- check_limits();
-}
-
-template void CMTask::process_grey_object<true>(oop);
-template void CMTask::process_grey_object<false>(oop);
-
// Closure for iteration over bitmaps
class CMBitMapClosure : public BitMapClosure {
private:
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -451,7 +451,7 @@
double* _accum_task_vtime; // Accumulated task vtime
- FlexibleWorkGang* _parallel_workers;
+ WorkGang* _parallel_workers;
ForceOverflowSettings _force_overflow_conc;
ForceOverflowSettings _force_overflow_stw;
@@ -1126,7 +1126,7 @@
inline void deal_with_reference(oop obj);
// It scans an object and visits its children.
- void scan_object(oop obj) { process_grey_object<true>(obj); }
+ inline void scan_object(oop obj);
// It pushes an object on the local queue.
inline void push(oop obj);
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -232,6 +232,9 @@
}
}
+// It scans an object and visits its children.
+inline void CMTask::scan_object(oop obj) { process_grey_object<true>(obj); }
+
inline void CMTask::push(oop obj) {
HeapWord* objAddr = (HeapWord*) obj;
assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
@@ -299,6 +302,28 @@
return objAddr < global_finger;
}
+template<bool scan>
+inline void CMTask::process_grey_object(oop obj) {
+ assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
+ assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
+
+ if (_cm->verbose_high()) {
+ gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT,
+ _worker_id, p2i((void*) obj));
+ }
+
+ size_t obj_size = obj->size();
+ _words_scanned += obj_size;
+
+ if (scan) {
+ obj->oop_iterate(_cm_oop_closure);
+ }
+ statsOnly( ++_objs_scanned );
+ check_limits();
+}
+
+
+
inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -1960,7 +1960,7 @@
_gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
_gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
- _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
+ _workers = new WorkGang("GC Thread", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);
_workers->initialize_workers();
@@ -5127,12 +5127,12 @@
private:
G1CollectedHeap* _g1h;
RefToScanQueueSet* _queues;
- FlexibleWorkGang* _workers;
+ WorkGang* _workers;
uint _active_workers;
public:
G1STWRefProcTaskExecutor(G1CollectedHeap* g1h,
- FlexibleWorkGang* workers,
+ WorkGang* workers,
RefToScanQueueSet *task_queues,
uint n_workers) :
_g1h(g1h),
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -75,7 +75,7 @@
class EvacuationFailedInfo;
class nmethod;
class Ticks;
-class FlexibleWorkGang;
+class WorkGang;
typedef OverflowTaskQueue<StarTask, mtGC> RefToScanQueue;
typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -200,7 +200,7 @@
friend class G1CheckCSetFastTableClosure;
private:
- FlexibleWorkGang* _workers;
+ WorkGang* _workers;
static size_t _humongous_object_threshold_in_words;
@@ -588,7 +588,7 @@
void enqueue_discovered_references();
public:
- FlexibleWorkGang* workers() const { return _workers; }
+ WorkGang* workers() const { return _workers; }
G1Allocator* allocator() {
return _allocator;
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -1582,7 +1582,7 @@
G1CollectorPolicy::record_concurrent_mark_cleanup_end() {
_collectionSetChooser->clear();
- FlexibleWorkGang* workers = _g1->workers();
+ WorkGang* workers = _g1->workers();
uint n_workers = workers->active_workers();
uint n_regions = _g1->num_regions();
--- a/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -115,7 +115,7 @@
G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
_g1h(g1h),
- _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
+ _process_strong_tasks(G1RP_PS_NumElements),
_srs(n_workers),
_lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
_n_workers_discovered_strong_classes(0) {}
@@ -158,7 +158,7 @@
{
// Now the CM ref_processor roots.
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
// We need to treat the discovered reference lists of the
// concurrent mark ref processor as roots and keep entries
// (which are added by the marking threads) on them live
@@ -201,12 +201,12 @@
// as implicitly live).
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_in_progress()) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_in_progress()) {
JavaThread::satb_mark_queue_set().filter_thread_buffers();
}
}
- _process_strong_tasks->all_tasks_completed(n_workers());
+ _process_strong_tasks.all_tasks_completed(n_workers());
}
void G1RootProcessor::process_strong_roots(OopClosure* oops,
@@ -216,7 +216,7 @@
process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0);
process_vm_roots(oops, NULL, NULL, 0);
- _process_strong_tasks->all_tasks_completed(n_workers());
+ _process_strong_tasks.all_tasks_completed(n_workers());
}
void G1RootProcessor::process_all_roots(OopClosure* oops,
@@ -226,11 +226,11 @@
process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0);
process_vm_roots(oops, oops, NULL, 0);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
CodeCache::blobs_do(blobs);
}
- _process_strong_tasks->all_tasks_completed(n_workers());
+ _process_strong_tasks.all_tasks_completed(n_workers());
}
void G1RootProcessor::process_java_roots(OopClosure* strong_roots,
@@ -246,7 +246,7 @@
// let the thread process the weak CLDs and nmethods.
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
}
}
@@ -264,49 +264,49 @@
uint worker_i) {
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_Universe_oops_do)) {
Universe::oops_do(strong_roots);
}
}
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_JNIHandles_oops_do)) {
JNIHandles::oops_do(strong_roots);
}
}
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_i);
- if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) {
ObjectSynchronizer::oops_do(strong_roots);
}
}
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::FlatProfilerRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) {
FlatProfiler::oops_do(strong_roots);
}
}
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_Management_oops_do)) {
Management::oops_do(strong_roots);
}
}
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_jvmti_oops_do)) {
JvmtiExport::oops_do(strong_roots);
}
}
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
- if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
+ if (!_process_strong_tasks.is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
SystemDictionary::roots_oops_do(strong_roots, weak_roots);
}
}
--- a/hotspot/src/share/vm/gc/g1/g1RootProcessor.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RootProcessor.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -45,7 +45,7 @@
// worker thread call the process_roots methods.
class G1RootProcessor : public StackObj {
G1CollectedHeap* _g1h;
- SubTasksDone* _process_strong_tasks;
+ SubTasksDone _process_strong_tasks;
StrongRootsScope _srs;
// Used to implement the Thread work barrier.
--- a/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -225,6 +225,10 @@
return align_size_up(3 * _space_alignment, _gen_alignment);
}
+size_t GenCollectorPolicy::old_gen_size_lower_bound() {
+ return align_size_up(_space_alignment, _gen_alignment);
+}
+
#ifdef ASSERT
void GenCollectorPolicy::assert_flags() {
CollectorPolicy::assert_flags();
@@ -284,7 +288,7 @@
// Make sure the heap is large enough for two generations
size_t smallest_new_size = young_gen_size_lower_bound();
- size_t smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),
+ size_t smallest_heap_size = align_size_up(smallest_new_size + old_gen_size_lower_bound(),
_heap_alignment);
if (MaxHeapSize < smallest_heap_size) {
FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
@@ -356,6 +360,7 @@
vm_exit_during_initialization("Invalid young gen ratio specified");
}
+ OldSize = MAX2(OldSize, old_gen_size_lower_bound());
if (!is_size_aligned(OldSize, _gen_alignment)) {
// Setting OldSize directly to preserve information about the possible
// setting of OldSize on the command line.
--- a/hotspot/src/share/vm/gc/shared/collectorPolicy.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectorPolicy.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -282,6 +282,8 @@
size_t young_gen_size_lower_bound();
+ size_t old_gen_size_lower_bound();
+
HeapWord* mem_allocate_work(size_t size,
bool is_tlab,
bool* gc_overhead_limit_was_exceeded);
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -86,7 +86,7 @@
{
assert(policy != NULL, "Sanity check");
if (UseConcMarkSweepGC) {
- _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
+ _workers = new WorkGang("GC Thread", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);
_workers->initialize_workers();
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -30,9 +30,9 @@
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/generation.hpp"
-class FlexibleWorkGang;
class StrongRootsScope;
class SubTasksDone;
+class WorkGang;
// A "GenCollectedHeap" is a CollectedHeap that uses generational
// collection. It has two generations, young and old.
@@ -90,7 +90,7 @@
// In block contents verification, the number of header words to skip
NOT_PRODUCT(static size_t _skip_header_HeapWords;)
- FlexibleWorkGang* _workers;
+ WorkGang* _workers;
protected:
// Helper functions for allocation
@@ -124,7 +124,7 @@
public:
GenCollectedHeap(GenCollectorPolicy *policy);
- FlexibleWorkGang* workers() const { return _workers; }
+ WorkGang* workers() const { return _workers; }
GCStats* gc_stats(Generation* generation) const;
--- a/hotspot/src/share/vm/gc/shared/workgroup.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -28,58 +28,25 @@
#include "memory/allocation.inline.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
+#include "runtime/semaphore.hpp"
+#include "runtime/thread.inline.hpp"
// Definitions of WorkGang methods.
-AbstractWorkGang::AbstractWorkGang(const char* name,
- bool are_GC_task_threads,
- bool are_ConcurrentGC_threads) :
- _name(name),
- _are_GC_task_threads(are_GC_task_threads),
- _are_ConcurrentGC_threads(are_ConcurrentGC_threads) {
-
- assert(!(are_GC_task_threads && are_ConcurrentGC_threads),
- "They cannot both be STW GC and Concurrent threads" );
-
- // Other initialization.
- _monitor = new Monitor(/* priority */ Mutex::leaf,
- /* name */ "WorkGroup monitor",
- /* allow_vm_block */ are_GC_task_threads,
- Monitor::_safepoint_check_sometimes);
- assert(monitor() != NULL, "Failed to allocate monitor");
- _task = NULL;
- _sequence_number = 0;
- _started_workers = 0;
- _finished_workers = 0;
-}
-
-WorkGang::WorkGang(const char* name,
- uint workers,
- bool are_GC_task_threads,
- bool are_ConcurrentGC_threads) :
- AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) {
- _total_workers = workers;
-}
-
-GangWorker* WorkGang::allocate_worker(uint which) {
- GangWorker* new_worker = new GangWorker(this, which);
- return new_worker;
-}
-
// The current implementation will exit if the allocation
// of any worker fails. Still, return a boolean so that
// a future implementation can possibly do a partial
// initialization of the workers and report such to the
// caller.
-bool WorkGang::initialize_workers() {
+bool AbstractWorkGang::initialize_workers() {
if (TraceWorkGang) {
tty->print_cr("Constructing work gang %s with %d threads",
name(),
total_workers());
}
- _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers(), mtInternal);
- if (gang_workers() == NULL) {
+ _workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
+ if (_workers == NULL) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
return false;
}
@@ -90,9 +57,9 @@
worker_type = os::pgc_thread;
}
for (uint worker = 0; worker < total_workers(); worker += 1) {
- GangWorker* new_worker = allocate_worker(worker);
+ AbstractGangWorker* new_worker = allocate_worker(worker);
assert(new_worker != NULL, "Failed to allocate GangWorker");
- _gang_workers[worker] = new_worker;
+ _workers[worker] = new_worker;
if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
"Cannot create worker GC thread. Out of system resources.");
@@ -105,110 +72,208 @@
return true;
}
-GangWorker* AbstractWorkGang::gang_worker(uint i) const {
+AbstractGangWorker* AbstractWorkGang::worker(uint i) const {
// Array index bounds checking.
- GangWorker* result = NULL;
- assert(gang_workers() != NULL, "No workers for indexing");
+ AbstractGangWorker* result = NULL;
+ assert(_workers != NULL, "No workers for indexing");
assert(i < total_workers(), "Worker index out of bounds");
- result = _gang_workers[i];
+ result = _workers[i];
assert(result != NULL, "Indexing to null worker");
return result;
}
-void WorkGang::run_task(AbstractGangTask* task) {
- run_task(task, total_workers());
-}
-
-void WorkGang::run_task(AbstractGangTask* task, uint no_of_parallel_workers) {
- // This thread is executed by the VM thread which does not block
- // on ordinary MutexLocker's.
- MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
- if (TraceWorkGang) {
- tty->print_cr("Running work gang %s task %s", name(), task->name());
- }
- // Tell all the workers to run a task.
- assert(task != NULL, "Running a null task");
- // Initialize.
- _task = task;
- _sequence_number += 1;
- _started_workers = 0;
- _finished_workers = 0;
- // Tell the workers to get to work.
- monitor()->notify_all();
- // Wait for them to be finished
- while (finished_workers() < no_of_parallel_workers) {
- if (TraceWorkGang) {
- tty->print_cr("Waiting in work gang %s: %u/%u finished sequence %d",
- name(), finished_workers(), no_of_parallel_workers,
- _sequence_number);
- }
- monitor()->wait(/* no_safepoint_check */ true);
- }
- _task = NULL;
- if (TraceWorkGang) {
- tty->print_cr("\nFinished work gang %s: %u/%u sequence %d",
- name(), finished_workers(), no_of_parallel_workers,
- _sequence_number);
- Thread* me = Thread::current();
- tty->print_cr(" T: " PTR_FORMAT " VM_thread: %d", p2i(me), me->is_VM_thread());
- }
-}
-
-void FlexibleWorkGang::run_task(AbstractGangTask* task) {
- // If active_workers() is passed, _finished_workers
- // must only be incremented for workers that find non_null
- // work (as opposed to all those that just check that the
- // task is not null).
- WorkGang::run_task(task, (uint) active_workers());
-}
-
-void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
- assert(monitor()->owned_by_self(), "worker_poll is an internal method");
- assert(data != NULL, "worker data is null");
- data->set_task(task());
- data->set_sequence_number(sequence_number());
-}
-
-void AbstractWorkGang::internal_note_start() {
- assert(monitor()->owned_by_self(), "note_finish is an internal method");
- _started_workers += 1;
-}
-
-void AbstractWorkGang::internal_note_finish() {
- assert(monitor()->owned_by_self(), "note_finish is an internal method");
- _finished_workers += 1;
-}
-
void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
- uint num_thr = total_workers();
- for (uint i = 0; i < num_thr; i++) {
- gang_worker(i)->print_on(st);
+ uint workers = total_workers();
+ for (uint i = 0; i < workers; i++) {
+ worker(i)->print_on(st);
st->cr();
}
}
void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
assert(tc != NULL, "Null ThreadClosure");
- uint num_thr = total_workers();
- for (uint i = 0; i < num_thr; i++) {
- tc->do_thread(gang_worker(i));
+ uint workers = total_workers();
+ for (uint i = 0; i < workers; i++) {
+ tc->do_thread(worker(i));
}
}
-// GangWorker methods.
+// WorkGang dispatcher implemented with semaphores.
+//
+// Semaphores don't require the worker threads to re-claim the lock when they wake up.
+// This helps lowering the latency when starting and stopping the worker threads.
+class SemaphoreGangTaskDispatcher : public GangTaskDispatcher {
+ // The task currently being dispatched to the GangWorkers.
+ AbstractGangTask* _task;
+
+ volatile uint _started;
+ volatile uint _not_finished;
+
+ // Semaphore used to start the GangWorkers.
+ Semaphore* _start_semaphore;
+ // Semaphore used to notify the coordinator that all workers are done.
+ Semaphore* _end_semaphore;
+
+public:
+ SemaphoreGangTaskDispatcher() :
+ _task(NULL),
+ _started(0),
+ _not_finished(0),
+ _start_semaphore(new Semaphore()),
+ _end_semaphore(new Semaphore())
+{ }
+
+ ~SemaphoreGangTaskDispatcher() {
+ delete _start_semaphore;
+ delete _end_semaphore;
+ }
+
+ void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers) {
+ // No workers are allowed to read the state variables until they have been signaled.
+ _task = task;
+ _not_finished = num_workers;
+
+ // Dispatch 'num_workers' number of tasks.
+ _start_semaphore->signal(num_workers);
+
+ // Wait for the last worker to signal the coordinator.
+ _end_semaphore->wait();
+
+ // No workers are allowed to read the state variables after the coordinator has been signaled.
+ assert(_not_finished == 0, err_msg("%d not finished workers?", _not_finished));
+ _task = NULL;
+ _started = 0;
+
+ }
+
+ WorkData worker_wait_for_task() {
+ // Wait for the coordinator to dispatch a task.
+ _start_semaphore->wait();
+
+ uint num_started = (uint) Atomic::add(1, (volatile jint*)&_started);
+
+ // Subtract one to get a zero-indexed worker id.
+ uint worker_id = num_started - 1;
+
+ return WorkData(_task, worker_id);
+ }
+
+ void worker_done_with_task() {
+ // Mark that the worker is done with the task.
+ // The worker is not allowed to read the state variables after this line.
+ uint not_finished = (uint) Atomic::add(-1, (volatile jint*)&_not_finished);
+
+ // The last worker signals to the coordinator that all work is completed.
+ if (not_finished == 0) {
+ _end_semaphore->signal();
+ }
+ }
+};
+
+class MutexGangTaskDispatcher : public GangTaskDispatcher {
+ AbstractGangTask* _task;
+
+ volatile uint _started;
+ volatile uint _finished;
+ volatile uint _num_workers;
+
+ Monitor* _monitor;
-GangWorker::GangWorker(AbstractWorkGang* gang, uint id) {
+ public:
+ MutexGangTaskDispatcher()
+ : _task(NULL),
+ _monitor(new Monitor(Monitor::leaf, "WorkGang dispatcher lock", false, Monitor::_safepoint_check_never)),
+ _started(0),
+ _finished(0),
+ _num_workers(0) {}
+
+ ~MutexGangTaskDispatcher() {
+ delete _monitor;
+ }
+
+ void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers) {
+ MutexLockerEx ml(_monitor, Mutex::_no_safepoint_check_flag);
+
+ _task = task;
+ _num_workers = num_workers;
+
+ // Tell the workers to get to work.
+ _monitor->notify_all();
+
+ // Wait for them to finish.
+ while (_finished < _num_workers) {
+ _monitor->wait(/* no_safepoint_check */ true);
+ }
+
+ _task = NULL;
+ _num_workers = 0;
+ _started = 0;
+ _finished = 0;
+ }
+
+ WorkData worker_wait_for_task() {
+ MonitorLockerEx ml(_monitor, Mutex::_no_safepoint_check_flag);
+
+ while (_num_workers == 0 || _started == _num_workers) {
+ _monitor->wait(/* no_safepoint_check */ true);
+ }
+
+ _started++;
+
+ // Subtract one to get a zero-indexed worker id.
+ uint worker_id = _started - 1;
+
+ return WorkData(_task, worker_id);
+ }
+
+ void worker_done_with_task() {
+ MonitorLockerEx ml(_monitor, Mutex::_no_safepoint_check_flag);
+
+ _finished++;
+
+ if (_finished == _num_workers) {
+ // This will wake up all workers and not only the coordinator.
+ _monitor->notify_all();
+ }
+ }
+};
+
+static GangTaskDispatcher* create_dispatcher() {
+ if (UseSemaphoreGCThreadsSynchronization) {
+ return new SemaphoreGangTaskDispatcher();
+ }
+
+ return new MutexGangTaskDispatcher();
+}
+
+WorkGang::WorkGang(const char* name,
+ uint workers,
+ bool are_GC_task_threads,
+ bool are_ConcurrentGC_threads) :
+ AbstractWorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
+ _dispatcher(create_dispatcher())
+{ }
+
+AbstractGangWorker* WorkGang::allocate_worker(uint worker_id) {
+ return new GangWorker(this, worker_id);
+}
+
+void WorkGang::run_task(AbstractGangTask* task) {
+ _dispatcher->coordinator_execute_on_workers(task, active_workers());
+}
+
+AbstractGangWorker::AbstractGangWorker(AbstractWorkGang* gang, uint id) {
_gang = gang;
set_id(id);
set_name("%s#%d", gang->name(), id);
}
-void GangWorker::run() {
+void AbstractGangWorker::run() {
initialize();
loop();
}
-void GangWorker::initialize() {
+void AbstractGangWorker::initialize() {
this->initialize_thread_local_storage();
this->record_stack_base_and_size();
this->initialize_named_thread();
@@ -224,112 +289,59 @@
" of a work gang");
}
-void GangWorker::loop() {
- int previous_sequence_number = 0;
- Monitor* gang_monitor = gang()->monitor();
- for ( ; ; ) {
- WorkData data;
- int part; // Initialized below.
- {
- // Grab the gang mutex.
- MutexLocker ml(gang_monitor);
- // Wait for something to do.
- // Polling outside the while { wait } avoids missed notifies
- // in the outer loop.
- gang()->internal_worker_poll(&data);
- if (TraceWorkGang) {
- tty->print("Polled outside for work in gang %s worker %u",
- gang()->name(), id());
- tty->print(" sequence: %d (prev: %d)",
- data.sequence_number(), previous_sequence_number);
- if (data.task() != NULL) {
- tty->print(" task: %s", data.task()->name());
- } else {
- tty->print(" task: NULL");
- }
- tty->cr();
- }
- for ( ; /* break */; ) {
- // Check for new work.
- if ((data.task() != NULL) &&
- (data.sequence_number() != previous_sequence_number)) {
- if (gang()->needs_more_workers()) {
- gang()->internal_note_start();
- gang_monitor->notify_all();
- part = gang()->started_workers() - 1;
- break;
- }
- }
- // Nothing to do.
- gang_monitor->wait(/* no_safepoint_check */ true);
- gang()->internal_worker_poll(&data);
- if (TraceWorkGang) {
- tty->print("Polled inside for work in gang %s worker %u",
- gang()->name(), id());
- tty->print(" sequence: %d (prev: %d)",
- data.sequence_number(), previous_sequence_number);
- if (data.task() != NULL) {
- tty->print(" task: %s", data.task()->name());
- } else {
- tty->print(" task: NULL");
- }
- tty->cr();
- }
- }
- // Drop gang mutex.
- }
- if (TraceWorkGang) {
- tty->print("Work for work gang %s id %u task %s part %d",
- gang()->name(), id(), data.task()->name(), part);
- }
- assert(data.task() != NULL, "Got null task");
- data.task()->work(part);
- {
- if (TraceWorkGang) {
- tty->print("Finish for work gang %s id %u task %s part %d",
- gang()->name(), id(), data.task()->name(), part);
- }
- // Grab the gang mutex.
- MutexLocker ml(gang_monitor);
- gang()->internal_note_finish();
- // Tell the gang you are done.
- gang_monitor->notify_all();
- // Drop the gang mutex.
- }
- previous_sequence_number = data.sequence_number();
- }
-}
-
-bool GangWorker::is_GC_task_thread() const {
+bool AbstractGangWorker::is_GC_task_thread() const {
return gang()->are_GC_task_threads();
}
-bool GangWorker::is_ConcurrentGC_thread() const {
+bool AbstractGangWorker::is_ConcurrentGC_thread() const {
return gang()->are_ConcurrentGC_threads();
}
-void GangWorker::print_on(outputStream* st) const {
+void AbstractGangWorker::print_on(outputStream* st) const {
st->print("\"%s\" ", name());
Thread::print_on(st);
st->cr();
}
-// Printing methods
+WorkData GangWorker::wait_for_task() {
+ return gang()->dispatcher()->worker_wait_for_task();
+}
-const char* AbstractWorkGang::name() const {
- return _name;
+void GangWorker::signal_task_done() {
+ gang()->dispatcher()->worker_done_with_task();
+}
+
+void GangWorker::print_task_started(WorkData data) {
+ if (TraceWorkGang) {
+ tty->print_cr("Running work gang %s task %s worker %u", name(), data._task->name(), data._worker_id);
+ }
}
-#ifndef PRODUCT
-
-const char* AbstractGangTask::name() const {
- return _name;
+void GangWorker::print_task_done(WorkData data) {
+ if (TraceWorkGang) {
+ tty->print_cr("\nFinished work gang %s task %s worker %u", name(), data._task->name(), data._worker_id);
+ Thread* me = Thread::current();
+ tty->print_cr(" T: " PTR_FORMAT " VM_thread: %d", p2i(me), me->is_VM_thread());
+ }
}
-#endif /* PRODUCT */
+void GangWorker::run_task(WorkData data) {
+ print_task_started(data);
+
+ data._task->work(data._worker_id);
+
+ print_task_done(data);
+}
-// FlexibleWorkGang
+void GangWorker::loop() {
+ while (true) {
+ WorkData data = wait_for_task();
+ run_task(data);
+
+ signal_task_done();
+ }
+}
// *** WorkGangBarrierSync
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -25,282 +25,111 @@
#ifndef SHARE_VM_GC_SHARED_WORKGROUP_HPP
#define SHARE_VM_GC_SHARED_WORKGROUP_HPP
-#include "gc/shared/taskqueue.hpp"
-#include "runtime/thread.inline.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
// Task class hierarchy:
// AbstractGangTask
-// AbstractGangTaskWOopQueues
//
// Gang/Group class hierarchy:
// AbstractWorkGang
// WorkGang
-// FlexibleWorkGang
-// YieldingFlexibleWorkGang (defined in another file)
+// YieldingFlexibleWorkGang (defined in another file)
//
// Worker class hierarchy:
-// GangWorker (subclass of WorkerThread)
+// AbstractGangWorker (subclass of WorkerThread)
+// GangWorker
// YieldingFlexibleGangWorker (defined in another file)
// Forward declarations of classes defined here
+class AbstractGangWorker;
+class Semaphore;
class WorkGang;
-class GangWorker;
-class YieldingFlexibleGangWorker;
-class YieldingFlexibleGangTask;
-class WorkData;
-class AbstractWorkGang;
// An abstract task to be worked on by a gang.
// You subclass this to supply your own work() method
class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
-public:
+ const char* _name;
+
+ public:
+ AbstractGangTask(const char* name) : _name(name) {}
+
// The abstract work method.
// The argument tells you which member of the gang you are.
virtual void work(uint worker_id) = 0;
// Debugging accessor for the name.
- const char* name() const PRODUCT_RETURN_(return NULL;);
- int counter() { return _counter; }
- void set_counter(int value) { _counter = value; }
- int *address_of_counter() { return &_counter; }
-
- // RTTI
- NOT_PRODUCT(virtual bool is_YieldingFlexibleGang_task() const {
- return false;
- })
+ const char* name() const { return _name; }
+};
-private:
- NOT_PRODUCT(const char* _name;)
- // ??? Should a task have a priority associated with it?
- // ??? Or can the run method adjust priority as needed?
- int _counter;
-
-protected:
- // Constructor and desctructor: only construct subclasses.
- AbstractGangTask(const char* name)
- {
- NOT_PRODUCT(_name = name);
- _counter = 0;
- }
- ~AbstractGangTask() { }
-
-public:
+struct WorkData {
+ AbstractGangTask* _task;
+ uint _worker_id;
+ WorkData(AbstractGangTask* task, uint worker_id) : _task(task), _worker_id(worker_id) {}
};
-class AbstractGangTaskWOopQueues : public AbstractGangTask {
- OopTaskQueueSet* _queues;
- ParallelTaskTerminator _terminator;
+// Interface to handle the synchronization between the coordinator thread and the worker threads,
+// when a task is dispatched out to the worker threads.
+class GangTaskDispatcher : public CHeapObj<mtGC> {
public:
- AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues, uint n_threads) :
- AbstractGangTask(name), _queues(queues), _terminator(n_threads, _queues) {}
- ParallelTaskTerminator* terminator() { return &_terminator; }
- OopTaskQueueSet* queues() { return _queues; }
+ virtual ~GangTaskDispatcher() {}
+
+ // Coordinator API.
+
+ // Distributes the task out to num_workers workers.
+ // Returns when the task has been completed by all workers.
+ virtual void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers) = 0;
+
+ // Worker API.
+
+ // Waits for a task to become available to the worker.
+ // Returns when the worker has been assigned a task.
+ virtual WorkData worker_wait_for_task() = 0;
+
+ // Signal to the coordinator that the worker is done with the assigned task.
+ virtual void worker_done_with_task() = 0;
};
+// The work gang is the collection of workers to execute tasks.
+// The number of workers run for a task is "_active_workers"
+// while "_total_workers" is the number of available of workers.
+class AbstractWorkGang : public CHeapObj<mtInternal> {
+ protected:
+ // The array of worker threads for this gang.
+ AbstractGangWorker** _workers;
+ // The count of the number of workers in the gang.
+ uint _total_workers;
+ // The currently active workers in this gang.
+ uint _active_workers;
+ // Printing support.
+ const char* _name;
-// Class AbstractWorkGang:
-// An abstract class representing a gang of workers.
-// You subclass this to supply an implementation of run_task().
-class AbstractWorkGang: public CHeapObj<mtInternal> {
-protected:
- // Work gangs are never deleted, so no need to cleanup.
- ~AbstractWorkGang() { ShouldNotReachHere(); }
-public:
- // Constructor.
- AbstractWorkGang(const char* name, bool are_GC_task_threads,
- bool are_ConcurrentGC_threads);
- // Run a task, returns when the task is done (or terminated).
- virtual void run_task(AbstractGangTask* task) = 0;
- // Return true if more workers should be applied to the task.
- virtual bool needs_more_workers() const { return true; }
-public:
- // Debugging.
- const char* name() const;
-protected:
+ private:
// Initialize only instance data.
const bool _are_GC_task_threads;
const bool _are_ConcurrentGC_threads;
- // Printing support.
- const char* _name;
- // The monitor which protects these data,
- // and notifies of changes in it.
- Monitor* _monitor;
- // The count of the number of workers in the gang.
- uint _total_workers;
- // The array of worker threads for this gang.
- // This is only needed for cleaning up.
- GangWorker** _gang_workers;
- // The task for this gang.
- AbstractGangTask* _task;
- // A sequence number for the current task.
- int _sequence_number;
- // The number of started workers.
- uint _started_workers;
- // The number of finished workers.
- uint _finished_workers;
-public:
- // Accessors for fields
- Monitor* monitor() const {
- return _monitor;
- }
- uint total_workers() const {
- return _total_workers;
- }
- virtual uint active_workers() const {
- return _total_workers;
- }
- GangWorker** gang_workers() const {
- return _gang_workers;
- }
- AbstractGangTask* task() const {
- return _task;
- }
- int sequence_number() const {
- return _sequence_number;
- }
- uint started_workers() const {
- return _started_workers;
- }
- uint finished_workers() const {
- return _finished_workers;
- }
- bool are_GC_task_threads() const {
- return _are_GC_task_threads;
- }
- bool are_ConcurrentGC_threads() const {
- return _are_ConcurrentGC_threads;
- }
- // Predicates.
- bool is_idle() const {
- return (task() == NULL);
- }
- // Return the Ith gang worker.
- GangWorker* gang_worker(uint i) const;
-
- void threads_do(ThreadClosure* tc) const;
-
- // Printing
- void print_worker_threads_on(outputStream *st) const;
- void print_worker_threads() const {
- print_worker_threads_on(tty);
- }
-
-protected:
- friend class GangWorker;
- friend class YieldingFlexibleGangWorker;
- // Note activation and deactivation of workers.
- // These methods should only be called with the mutex held.
- void internal_worker_poll(WorkData* data) const;
- void internal_note_start();
- void internal_note_finish();
-};
-class WorkData: public StackObj {
- // This would be a struct, but I want accessor methods.
-private:
- AbstractGangTask* _task;
- int _sequence_number;
-public:
- // Constructor and destructor
- WorkData() {
- _task = NULL;
- _sequence_number = 0;
- }
- ~WorkData() {
- }
- AbstractGangTask* task() const { return _task; }
- void set_task(AbstractGangTask* value) { _task = value; }
- int sequence_number() const { return _sequence_number; }
- void set_sequence_number(int value) { _sequence_number = value; }
-
- YieldingFlexibleGangTask* yf_task() const {
- return (YieldingFlexibleGangTask*)_task;
- }
-};
-
-// Class WorkGang:
-class WorkGang: public AbstractWorkGang {
-public:
- // Constructor
- WorkGang(const char* name, uint workers,
- bool are_GC_task_threads, bool are_ConcurrentGC_threads);
- // Run a task, returns when the task is done (or terminated).
- virtual void run_task(AbstractGangTask* task);
- void run_task(AbstractGangTask* task, uint no_of_parallel_workers);
- // Allocate a worker and return a pointer to it.
- virtual GangWorker* allocate_worker(uint which);
- // Initialize workers in the gang. Return true if initialization
- // succeeded. The type of the worker can be overridden in a derived
- // class with the appropriate implementation of allocate_worker().
- bool initialize_workers();
-};
-
-// Class GangWorker:
-// Several instances of this class run in parallel as workers for a gang.
-class GangWorker: public WorkerThread {
-public:
- // Constructors and destructor.
- GangWorker(AbstractWorkGang* gang, uint id);
+ public:
+ AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
+ _name(name),
+ _total_workers(workers),
+ _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),
+ _are_GC_task_threads(are_GC_task_threads),
+ _are_ConcurrentGC_threads(are_ConcurrentGC_threads)
+ { }
- // The only real method: run a task for the gang.
- virtual void run();
- // Predicate for Thread
- virtual bool is_GC_task_thread() const;
- virtual bool is_ConcurrentGC_thread() const;
- // Printing
- void print_on(outputStream* st) const;
- virtual void print() const { print_on(tty); }
-protected:
- AbstractWorkGang* _gang;
-
- virtual void initialize();
- virtual void loop();
-
-public:
- AbstractWorkGang* gang() const { return _gang; }
-};
+ // Initialize workers in the gang. Return true if initialization succeeded.
+ bool initialize_workers();
-// Dynamic number of worker threads
-//
-// This type of work gang is used to run different numbers of
-// worker threads at different times. The
-// number of workers run for a task is "_active_workers"
-// instead of "_total_workers" in a WorkGang. The method
-// "needs_more_workers()" returns true until "_active_workers"
-// have been started and returns false afterwards. The
-// implementation of "needs_more_workers()" in WorkGang always
-// returns true so that all workers are started. The method
-// "loop()" in GangWorker was modified to ask "needs_more_workers()"
-// in its loop to decide if it should start working on a task.
-// A worker in "loop()" waits for notification on the WorkGang
-// monitor and execution of each worker as it checks for work
-// is serialized via the same monitor. The "needs_more_workers()"
-// call is serialized and additionally the calculation for the
-// "part" (effectively the worker id for executing the task) is
-// serialized to give each worker a unique "part". Workers that
-// are not needed for this tasks (i.e., "_active_workers" have
-// been started before it, continue to wait for work.
+ bool are_GC_task_threads() const { return _are_GC_task_threads; }
+ bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
-class FlexibleWorkGang: public WorkGang {
- // The currently active workers in this gang.
- // This is a number that is dynamically adjusted
- // and checked in the run_task() method at each invocation.
- // As described above _active_workers determines the number
- // of threads started on a task. It must also be used to
- // determine completion.
+ uint total_workers() const { return _total_workers; }
- protected:
- uint _active_workers;
- public:
- // Constructor and destructor.
- FlexibleWorkGang(const char* name, uint workers,
- bool are_GC_task_threads,
- bool are_ConcurrentGC_threads) :
- WorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
- _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers) {}
-
- // Accessors for fields.
virtual uint active_workers() const {
assert(_active_workers <= _total_workers,
err_msg("_active_workers: %u > _total_workers: %u", _active_workers, _total_workers));
@@ -317,10 +146,90 @@
assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
"Unless dynamic should use total workers");
}
+
+ // Return the Ith worker.
+ AbstractGangWorker* worker(uint i) const;
+
+ void threads_do(ThreadClosure* tc) const;
+
+ // Debugging.
+ const char* name() const { return _name; }
+
+ // Printing
+ void print_worker_threads_on(outputStream *st) const;
+ void print_worker_threads() const {
+ print_worker_threads_on(tty);
+ }
+
+ protected:
+ virtual AbstractGangWorker* allocate_worker(uint which) = 0;
+};
+
+// An class representing a gang of workers.
+class WorkGang: public AbstractWorkGang {
+ // To get access to the GangTaskDispatcher instance.
+ friend class GangWorker;
+
+ // Never deleted.
+ ~WorkGang();
+
+ GangTaskDispatcher* const _dispatcher;
+ GangTaskDispatcher* dispatcher() const {
+ return _dispatcher;
+ }
+
+public:
+ WorkGang(const char* name,
+ uint workers,
+ bool are_GC_task_threads,
+ bool are_ConcurrentGC_threads);
+
+ // Run a task, returns when the task is done.
virtual void run_task(AbstractGangTask* task);
- virtual bool needs_more_workers() const {
- return _started_workers < _active_workers;
- }
+
+protected:
+ virtual AbstractGangWorker* allocate_worker(uint which);
+};
+
+// Several instances of this class run in parallel as workers for a gang.
+class AbstractGangWorker: public WorkerThread {
+public:
+ AbstractGangWorker(AbstractWorkGang* gang, uint id);
+
+ // The only real method: run a task for the gang.
+ virtual void run();
+ // Predicate for Thread
+ virtual bool is_GC_task_thread() const;
+ virtual bool is_ConcurrentGC_thread() const;
+ // Printing
+ void print_on(outputStream* st) const;
+ virtual void print() const { print_on(tty); }
+
+protected:
+ AbstractWorkGang* _gang;
+
+ virtual void initialize();
+ virtual void loop() = 0;
+
+ AbstractWorkGang* gang() const { return _gang; }
+};
+
+class GangWorker: public AbstractGangWorker {
+public:
+ GangWorker(WorkGang* gang, uint id) : AbstractGangWorker(gang, id) {}
+
+protected:
+ virtual void loop();
+
+private:
+ WorkData wait_for_task();
+ void run_task(WorkData work);
+ void signal_task_done();
+
+ void print_task_started(WorkData data);
+ void print_task_done(WorkData data);
+
+ WorkGang* gang() const { return (WorkGang*)_gang; }
};
// A class that acts as a synchronisation barrier. Workers enter
--- a/hotspot/src/share/vm/oops/symbol.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/oops/symbol.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -35,7 +35,7 @@
Symbol::Symbol(const u1* name, int length, int refcount) {
_refcount = refcount;
_length = length;
- _identity_hash = os::random();
+ _identity_hash = (short)os::random();
for (int i = 0; i < _length; i++) {
byte_at_put(i, name[i]);
}
--- a/hotspot/src/share/vm/oops/symbol.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/oops/symbol.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -106,23 +106,18 @@
#define PERM_REFCOUNT -1
#endif
-// We separate the fields in SymbolBase from Symbol::_body so that
-// Symbol::size(int) can correctly calculate the space needed.
-class SymbolBase : public MetaspaceObj {
- public:
+class Symbol : public MetaspaceObj {
+ friend class VMStructs;
+ friend class SymbolTable;
+ friend class MoveSymbols;
+
+ private:
ATOMIC_SHORT_PAIR(
volatile short _refcount, // needs atomic operation
unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op)
);
- int _identity_hash;
-};
-
-class Symbol : private SymbolBase {
- friend class VMStructs;
- friend class SymbolTable;
- friend class MoveSymbols;
- private:
- jbyte _body[1];
+ short _identity_hash;
+ jbyte _body[2];
enum {
// max_symbol_length is constrained by type of _length
@@ -130,7 +125,7 @@
};
static int size(int length) {
- size_t sz = heap_word_size(sizeof(SymbolBase) + (length > 0 ? length : 0));
+ size_t sz = heap_word_size(sizeof(Symbol) + (length > 2 ? length - 2 : 0));
return align_object_size(sz);
}
@@ -154,8 +149,11 @@
// Returns the largest size symbol we can safely hold.
static int max_length() { return max_symbol_length; }
-
- int identity_hash() { return _identity_hash; }
+ unsigned identity_hash() {
+ unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3));
+ return ((unsigned)_identity_hash & 0xffff) |
+ ((addr_bits ^ (_length << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
+ }
// For symbol table alternate hashing
unsigned int new_hash(juint seed);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -81,8 +81,6 @@
bool Arguments::_has_profile = false;
size_t Arguments::_conservative_max_heap_alignment = 0;
size_t Arguments::_min_heap_size = 0;
-uintx Arguments::_min_heap_free_ratio = 0;
-uintx Arguments::_max_heap_free_ratio = 0;
Arguments::Mode Arguments::_mode = _mixed;
bool Arguments::_java_compiler = false;
bool Arguments::_xdebug_mode = false;
@@ -1614,11 +1612,9 @@
// unless the user actually sets these flags.
if (FLAG_IS_DEFAULT(MinHeapFreeRatio)) {
FLAG_SET_DEFAULT(MinHeapFreeRatio, 0);
- _min_heap_free_ratio = MinHeapFreeRatio;
}
if (FLAG_IS_DEFAULT(MaxHeapFreeRatio)) {
FLAG_SET_DEFAULT(MaxHeapFreeRatio, 100);
- _max_heap_free_ratio = MaxHeapFreeRatio;
}
}
@@ -3978,15 +3974,6 @@
return JNI_OK;
}
-// Any custom code post the 'CommandLineFlagConstraint::AfterErgo' constraint check
-// can be done here. We pass a flag that specifies whether
-// the check passed successfully
-void Arguments::post_after_ergo_constraint_check(bool check_passed) {
- // This does not set the flag itself, but stores the value in a safe place for later usage.
- _min_heap_free_ratio = MinHeapFreeRatio;
- _max_heap_free_ratio = MaxHeapFreeRatio;
-}
-
int Arguments::PropertyList_count(SystemProperty* pl) {
int count = 0;
while(pl != NULL) {
--- a/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -288,10 +288,6 @@
static uintx _min_heap_size;
- // Used to store original flag values
- static uintx _min_heap_free_ratio;
- static uintx _max_heap_free_ratio;
-
// -Xrun arguments
static AgentLibraryList _libraryList;
static void add_init_library(const char* name, char* options)
@@ -463,8 +459,6 @@
static jint apply_ergo();
// Adjusts the arguments after the OS have adjusted the arguments
static jint adjust_after_os();
- // Set any arguments that need to be set after the 'CommandLineFlagConstraint::AfterErgo' constraint check
- static void post_after_ergo_constraint_check(bool check_passed);
static void set_gc_specific_flags();
static inline bool gc_selected(); // whether a gc has been selected
@@ -526,10 +520,6 @@
static size_t min_heap_size() { return _min_heap_size; }
static void set_min_heap_size(size_t v) { _min_heap_size = v; }
- // Returns the original values of -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio
- static uintx min_heap_free_ratio() { return _min_heap_free_ratio; }
- static uintx max_heap_free_ratio() { return _max_heap_free_ratio; }
-
// -Xrun
static AgentLibrary* libraries() { return _libraryList.first(); }
static bool init_libraries_at_startup() { return !_libraryList.is_empty(); }
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -45,8 +45,8 @@
_constraint=func;
}
- Flag::Error apply_bool(bool* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_bool(bool value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -61,8 +61,8 @@
_constraint=func;
}
- Flag::Error apply_int(int* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_int(int value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -77,8 +77,8 @@
_constraint=func;
}
- Flag::Error apply_intx(intx* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_intx(intx value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -93,8 +93,8 @@
_constraint=func;
}
- Flag::Error apply_uint(uint* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_uint(uint value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -109,8 +109,8 @@
_constraint=func;
}
- Flag::Error apply_uintx(uintx* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_uintx(uintx value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -125,8 +125,8 @@
_constraint=func;
}
- Flag::Error apply_uint64_t(uint64_t* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_uint64_t(uint64_t value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -141,8 +141,8 @@
_constraint=func;
}
- Flag::Error apply_size_t(size_t* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_size_t(size_t value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -157,8 +157,8 @@
_constraint=func;
}
- Flag::Error apply_double(double* value, bool verbose) {
- return _constraint(verbose, value);
+ Flag::Error apply_double(double value, bool verbose) {
+ return _constraint(value, verbose);
}
};
@@ -226,7 +226,6 @@
// Check the ranges of all flags that have them or print them out and exit if requested
void CommandLineFlagConstraintList::init(void) {
-
_constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
@@ -306,40 +305,6 @@
// Check constraints for specific constraint type.
bool CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::ConstraintType type) {
-//#define PRINT_CONSTRAINTS_SIZES
-#ifdef PRINT_CONSTRAINTS_SIZES
- {
- size_t size_constraints = sizeof(CommandLineFlagConstraintList);
- for (int i=0; i<length(); i++) {
- size_constraints += sizeof(CommandLineFlagConstraint);
- CommandLineFlagConstraint* constraint = at(i);
- const char* name = constraint->name();
- Flag* flag = Flag::find_flag(name, strlen(name), true, true);
- if (flag->is_bool()) {
- size_constraints += sizeof(CommandLineFlagConstraintFunc_bool);
- size_constraints += sizeof(CommandLineFlagConstraint*);
- } else if (flag->is_intx()) {
- size_constraints += sizeof(CommandLineFlagConstraintFunc_intx);
- size_constraints += sizeof(CommandLineFlagConstraint*);
- } else if (flag->is_uintx()) {
- size_constraints += sizeof(CommandLineFlagConstraintFunc_uintx);
- size_constraints += sizeof(CommandLineFlagConstraint*);
- } else if (flag->is_uint64_t()) {
- size_constraints += sizeof(CommandLineFlagConstraintFunc_uint64_t);
- size_constraints += sizeof(CommandLineFlagConstraint*);
- } else if (flag->is_size_t()) {
- size_constraints += sizeof(CommandLineFlagConstraintFunc_size_t);
- size_constraints += sizeof(CommandLineFlagConstraint*);
- } else if (flag->is_double()) {
- size_constraints += sizeof(CommandLineFlagConstraintFunc_double);
- size_constraints += sizeof(CommandLineFlagConstraint*);
- }
- }
- fprintf(stderr, "Size of %d constraints: " SIZE_FORMAT " bytes\n",
- length(), size_constraints);
- }
-#endif // PRINT_CONSTRAINTS_SIZES
-
// Skip if we already checked.
if (type < _validating_type) {
return true;
@@ -350,27 +315,36 @@
for (int i=0; i<length(); i++) {
CommandLineFlagConstraint* constraint = at(i);
if (type != constraint->type()) continue;
- const char*name = constraint->name();
+ const char* name = constraint->name();
Flag* flag = Flag::find_flag(name, strlen(name), true, true);
+ // We must check for NULL here as lp64_product flags on 32 bit architecture
+ // can generate constraint check (despite that they are declared as constants),
+ // but they will not be returned by Flag::find_flag()
if (flag != NULL) {
if (flag->is_bool()) {
bool value = flag->get_bool();
- if (constraint->apply_bool(&value, true) != Flag::SUCCESS) status = false;
+ if (constraint->apply_bool(value, true) != Flag::SUCCESS) status = false;
+ } else if (flag->is_int()) {
+ int value = flag->get_int();
+ if (constraint->apply_int(value, true) != Flag::SUCCESS) status = false;
+ } else if (flag->is_uint()) {
+ uint value = flag->get_uint();
+ if (constraint->apply_uint(value, true) != Flag::SUCCESS) status = false;
} else if (flag->is_intx()) {
intx value = flag->get_intx();
- if (constraint->apply_intx(&value, true) != Flag::SUCCESS) status = false;
+ if (constraint->apply_intx(value, true) != Flag::SUCCESS) status = false;
} else if (flag->is_uintx()) {
uintx value = flag->get_uintx();
- if (constraint->apply_uintx(&value, true) != Flag::SUCCESS) status = false;
+ if (constraint->apply_uintx(value, true) != Flag::SUCCESS) status = false;
} else if (flag->is_uint64_t()) {
uint64_t value = flag->get_uint64_t();
- if (constraint->apply_uint64_t(&value, true) != Flag::SUCCESS) status = false;
+ if (constraint->apply_uint64_t(value, true) != Flag::SUCCESS) status = false;
} else if (flag->is_size_t()) {
size_t value = flag->get_size_t();
- if (constraint->apply_size_t(&value, true) != Flag::SUCCESS) status = false;
+ if (constraint->apply_size_t(value, true) != Flag::SUCCESS) status = false;
} else if (flag->is_double()) {
double value = flag->get_double();
- if (constraint->apply_double(&value, true) != Flag::SUCCESS) status = false;
+ if (constraint->apply_double(value, true) != Flag::SUCCESS) status = false;
}
}
}
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -39,14 +39,14 @@
* "runtime/commandLineFlagConstraintsRuntime.hpp" for the functions themselves.
*/
-typedef Flag::Error (*CommandLineFlagConstraintFunc_bool)(bool verbose, bool* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_int)(bool verbose, int* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_intx)(bool verbose, intx* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_uint)(bool verbose, uint* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_uintx)(bool verbose, uintx* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_uint64_t)(bool verbose, uint64_t* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_size_t)(bool verbose, size_t* value);
-typedef Flag::Error (*CommandLineFlagConstraintFunc_double)(bool verbose, double* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_bool)(bool value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_int)(int value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_intx)(intx value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_uint)(uint value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_uintx)(uintx value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_uint64_t)(uint64_t value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_size_t)(size_t value, bool verbose);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_double)(double value, bool verbose);
class CommandLineFlagConstraint : public CHeapObj<mtInternal> {
public:
@@ -70,14 +70,14 @@
~CommandLineFlagConstraint() {};
const char* name() const { return _name; }
ConstraintType type() const { return _validate_type; }
- virtual Flag::Error apply_bool(bool* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_int(int* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_intx(intx* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_uint(uint* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_uintx(uintx* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_uint64_t(uint64_t* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_size_t(size_t* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
- virtual Flag::Error apply_double(double* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_bool(bool value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_int(int value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_intx(intx value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_uint(uint value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_uintx(uintx value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_uint64_t(uint64_t value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_size_t(size_t value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+ virtual Flag::Error apply_double(double value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
};
class CommandLineFlagConstraintList : public AllStatic {
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -25,17 +25,16 @@
#include "precompiled.hpp"
#include "runtime/arguments.hpp"
#include "runtime/commandLineFlagConstraintsCompiler.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
#include "runtime/globals.hpp"
#include "utilities/defaultStream.hpp"
-Flag::Error AliasLevelConstraintFunc(bool verbose, intx* value) {
- if ((*value <= 1) && (Arguments::mode() == Arguments::_comp)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "AliasLevel (" INTX_FORMAT ") is not compatible "
- "with -Xcomp \n",
- *value);
- }
+Flag::Error AliasLevelConstraintFunc(intx value, bool verbose) {
+ if ((value <= 1) && (Arguments::mode() == Arguments::_comp)) {
+ CommandLineError::print(verbose,
+ "AliasLevel (" INTX_FORMAT ") is not "
+ "compatible with -Xcomp \n",
+ value);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
@@ -57,7 +56,7 @@
* 'TieredStopAtLevel = CompLevel_full_optimization' (the default value). As a result,
* the minimum number of compiler threads is 2.
*/
-Flag::Error CICompilerCountConstraintFunc(bool verbose, intx* value) {
+Flag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
int min_number_of_compiler_threads = 0;
#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
// case 1
@@ -75,12 +74,11 @@
// min_number_of_compiler_threads to exceed CI_COMPILER_COUNT.
min_number_of_compiler_threads = MIN2(min_number_of_compiler_threads, CI_COMPILER_COUNT);
- if (*value < (intx)min_number_of_compiler_threads) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "CICompilerCount=" INTX_FORMAT " must be at least %d \n",
- *value, min_number_of_compiler_threads);
- }
+ if (value < (intx)min_number_of_compiler_threads) {
+ CommandLineError::print(verbose,
+ "CICompilerCount (" INTX_FORMAT ") must be "
+ "at least %d \n",
+ value, min_number_of_compiler_threads);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -34,8 +34,8 @@
* an appropriate error value.
*/
-Flag::Error AliasLevelConstraintFunc(bool verbose, intx* value);
+Flag::Error AliasLevelConstraintFunc(intx value, bool verbose);
-Flag::Error CICompilerCountConstraintFunc(bool verbose, intx* value);
+Flag::Error CICompilerCountConstraintFunc(intx value, bool verbose);
#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSCOMPILER_HPP */
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "runtime/arguments.hpp"
#include "runtime/commandLineFlagConstraintsGC.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
#include "runtime/globals.hpp"
#include "utilities/defaultStream.hpp"
@@ -41,97 +42,85 @@
#include "opto/c2_globals.hpp"
#endif // COMPILER2
-static Flag::Error MinPLABSizeBounds(const char* name, bool verbose, size_t* value) {
+static Flag::Error MinPLABSizeBounds(const char* name, size_t value, bool verbose) {
#if INCLUDE_ALL_GCS
- if ((UseConcMarkSweepGC || UseG1GC) && (*value < PLAB::min_size())) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "%s (" SIZE_FORMAT ") must be greater than "
- "ergonomic PLAB minimum size (" SIZE_FORMAT ")\n",
- name, *value, PLAB::min_size());
- }
+ if ((UseConcMarkSweepGC || UseG1GC) && (value < PLAB::min_size())) {
+ CommandLineError::print(verbose,
+ "%s (" SIZE_FORMAT ") must be "
+ "greater than or equal to ergonomic PLAB minimum size (" SIZE_FORMAT ")\n",
+ name, value, PLAB::min_size());
return Flag::VIOLATES_CONSTRAINT;
}
#endif // INCLUDE_ALL_GCS
return Flag::SUCCESS;
}
-static Flag::Error MaxPLABSizeBounds(const char* name, bool verbose, size_t* value) {
+static Flag::Error MaxPLABSizeBounds(const char* name, size_t value, bool verbose) {
#if INCLUDE_ALL_GCS
- if ((UseConcMarkSweepGC || UseG1GC) && (*value > PLAB::max_size())) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "%s (" SIZE_FORMAT ") must be less than "
- "ergonomic PLAB maximum size (" SIZE_FORMAT ")\n",
- name, *value, PLAB::max_size());
- }
+ if ((UseConcMarkSweepGC || UseG1GC) && (value > PLAB::max_size())) {
+ CommandLineError::print(verbose,
+ "%s (" SIZE_FORMAT ") must be "
+ "less than ergonomic PLAB maximum size (" SIZE_FORMAT ")\n",
+ name, value, PLAB::min_size());
return Flag::VIOLATES_CONSTRAINT;
}
#endif // INCLUDE_ALL_GCS
return Flag::SUCCESS;
}
-static Flag::Error MinMaxPLABSizeBounds(const char* name, bool verbose, size_t* value) {
- if (MinPLABSizeBounds(name, verbose, value) == Flag::SUCCESS) {
- return MaxPLABSizeBounds(name, verbose, value);
+static Flag::Error MinMaxPLABSizeBounds(const char* name, size_t value, bool verbose) {
+ if (MinPLABSizeBounds(name, value, verbose) == Flag::SUCCESS) {
+ return MaxPLABSizeBounds(name, value, verbose);
}
return Flag::VIOLATES_CONSTRAINT;
}
-Flag::Error YoungPLABSizeConstraintFunc(bool verbose, size_t* value) {
- return MinMaxPLABSizeBounds("YoungPLABSize", verbose, value);
+Flag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose) {
+ return MinMaxPLABSizeBounds("YoungPLABSize", value, verbose);
}
-Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value) {
- if (*value > MaxHeapFreeRatio) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
- "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
- *value, MaxHeapFreeRatio);
- }
+Flag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) {
+ if (value > MaxHeapFreeRatio) {
+ CommandLineError::print(verbose,
+ "MinHeapFreeRatio (" UINTX_FORMAT ") must be "
+ "less than or equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
+ value, MaxHeapFreeRatio);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx* value) {
- if (*value < MinHeapFreeRatio) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or "
- "equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n",
- *value, MinHeapFreeRatio);
- }
+Flag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose) {
+ if (value < MinHeapFreeRatio) {
+ CommandLineError::print(verbose,
+ "MaxHeapFreeRatio (" UINTX_FORMAT ") must be "
+ "greater than or equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n",
+ value, MinHeapFreeRatio);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error MinMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value) {
- if (*value > MaxMetaspaceFreeRatio) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be less than or "
- "equal to MaxMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
- *value, MaxMetaspaceFreeRatio);
- }
+Flag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) {
+ if (value > MaxMetaspaceFreeRatio) {
+ CommandLineError::print(verbose,
+ "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be "
+ "less than or equal to MaxMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
+ value, MaxMetaspaceFreeRatio);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error MaxMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value) {
- if (*value < MinMetaspaceFreeRatio) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be greater than or "
- "equal to MinMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
- *value, MinMetaspaceFreeRatio);
- }
+Flag::Error MaxMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose) {
+ if (value < MinMetaspaceFreeRatio) {
+ CommandLineError::print(verbose,
+ "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be "
+ "greater than or equal to MinMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
+ value, MinMetaspaceFreeRatio);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
@@ -147,32 +136,28 @@
} \
}
-Flag::Error InitialTenuringThresholdConstraintFunc(bool verbose, uintx* value) {
- UseConcMarkSweepGCWorkaroundIfNeeded(*value, MaxTenuringThreshold);
+Flag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose) {
+ UseConcMarkSweepGCWorkaroundIfNeeded(value, MaxTenuringThreshold);
- if (*value > MaxTenuringThreshold) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "InitialTenuringThreshold (" UINTX_FORMAT ") must be less than or "
- "equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n",
- *value, MaxTenuringThreshold);
- }
+ if (value > MaxTenuringThreshold) {
+ CommandLineError::print(verbose,
+ "InitialTenuringThreshold (" UINTX_FORMAT ") must be "
+ "less than or equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n",
+ value, MaxTenuringThreshold);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error MaxTenuringThresholdConstraintFunc(bool verbose, uintx* value) {
- UseConcMarkSweepGCWorkaroundIfNeeded(InitialTenuringThreshold, *value);
+Flag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose) {
+ UseConcMarkSweepGCWorkaroundIfNeeded(InitialTenuringThreshold, value);
- if (*value < InitialTenuringThreshold) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "MaxTenuringThreshold (" UINTX_FORMAT ") must be greater than or "
- "equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n",
- *value, InitialTenuringThreshold);
- }
+ if (value < InitialTenuringThreshold) {
+ CommandLineError::print(verbose,
+ "MaxTenuringThreshold (" UINTX_FORMAT ") must be "
+ "greater than or equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n",
+ value, InitialTenuringThreshold);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
@@ -180,28 +165,24 @@
}
#if INCLUDE_ALL_GCS
-Flag::Error G1NewSizePercentConstraintFunc(bool verbose, uintx* value) {
- if (*value > G1MaxNewSizePercent) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "G1NewSizePercent (" UINTX_FORMAT ") must be less than or "
- "equal to G1MaxNewSizePercent (" UINTX_FORMAT ")\n",
- *value, G1MaxNewSizePercent);
- }
+Flag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose) {
+ if (value > G1MaxNewSizePercent) {
+ CommandLineError::print(verbose,
+ "G1NewSizePercent (" UINTX_FORMAT ") must be "
+ "less than or equal to G1MaxNewSizePercent (" UINTX_FORMAT ")\n",
+ value, G1MaxNewSizePercent);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error G1MaxNewSizePercentConstraintFunc(bool verbose, uintx* value) {
- if (*value < G1NewSizePercent) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "G1MaxNewSizePercent (" UINTX_FORMAT ") must be greater than or "
- "equal to G1NewSizePercent (" UINTX_FORMAT ")\n",
- *value, G1NewSizePercent);
- }
+Flag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose) {
+ if (value < G1NewSizePercent) {
+ CommandLineError::print(verbose,
+ "G1MaxNewSizePercent (" UINTX_FORMAT ") must be "
+ "greater than or equal to G1NewSizePercent (" UINTX_FORMAT ")\n",
+ value, G1NewSizePercent);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
@@ -210,65 +191,56 @@
#endif // INCLUDE_ALL_GCS
-Flag::Error CMSOldPLABMinConstraintFunc(bool verbose, size_t* value) {
- if (*value > CMSOldPLABMax) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "CMSOldPLABMin (" SIZE_FORMAT ") must be less than or "
- "equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
- *value, CMSOldPLABMax);
- }
+Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose) {
+ if (value > CMSOldPLABMax) {
+ CommandLineError::print(verbose,
+ "CMSOldPLABMin (" SIZE_FORMAT ") must be "
+ "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
+ value, CMSOldPLABMax);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error CMSPrecleanDenominatorConstraintFunc(bool verbose, uintx* value) {
- if (*value <= CMSPrecleanNumerator) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "CMSPrecleanDenominator (" UINTX_FORMAT ") must be strickly greater than "
- "CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
- *value, CMSPrecleanNumerator);
- }
+Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
+ if (value <= CMSPrecleanNumerator) {
+ CommandLineError::print(verbose,
+ "CMSPrecleanDenominator (" UINTX_FORMAT ") must be "
+ "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
+ value, CMSPrecleanNumerator);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error CMSPrecleanNumeratorConstraintFunc(bool verbose, uintx* value) {
- if (*value > (CMSPrecleanDenominator - 1)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "CMSPrecleanNumerator (" UINTX_FORMAT ") must be less than or "
- "equal to CMSPrecleanDenominator - 1 (" UINTX_FORMAT ")\n", *value,
- CMSPrecleanDenominator - 1);
- }
+Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) {
+ if (value > (CMSPrecleanDenominator - 1)) {
+ CommandLineError::print(verbose,
+ "CMSPrecleanNumerator (" UINTX_FORMAT ") must be "
+ "less than or equal to CMSPrecleanDenominator - 1 (" UINTX_FORMAT ")\n",
+ value, CMSPrecleanDenominator - 1);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
}
}
-Flag::Error SurvivorAlignmentInBytesConstraintFunc(bool verbose, intx* value) {
- if (*value != 0) {
- if (!is_power_of_2(*value)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be power of 2\n",
- *value);
- }
+Flag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose) {
+ if (value != 0) {
+ if (!is_power_of_2(value)) {
+ CommandLineError::print(verbose,
+ "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be "
+ "power of 2\n",
+ value);
return Flag::VIOLATES_CONSTRAINT;
}
- if (*value < ObjectAlignmentInBytes) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be greater than or "
- "equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n",
- *value, ObjectAlignmentInBytes);
- }
+ if (value < ObjectAlignmentInBytes) {
+ CommandLineError::print(verbose,
+ "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be "
+ "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n",
+ value, ObjectAlignmentInBytes);
return Flag::VIOLATES_CONSTRAINT;
}
}
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -34,27 +34,27 @@
* an appropriate error value.
*/
-Flag::Error YoungPLABSizeConstraintFunc(bool verbose, size_t* value);
+Flag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose);
-Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value);
-Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx* value);
+Flag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose);
+Flag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose);
-Flag::Error MinMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value);
-Flag::Error MaxMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value);
+Flag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose);
+Flag::Error MaxMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose);
-Flag::Error InitialTenuringThresholdConstraintFunc(bool verbose, uintx* value);
-Flag::Error MaxTenuringThresholdConstraintFunc(bool verbose, uintx* value);
+Flag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose);
+Flag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose);
#if INCLUDE_ALL_GCS
-Flag::Error G1NewSizePercentConstraintFunc(bool verbose, uintx* value);
-Flag::Error G1MaxNewSizePercentConstraintFunc(bool verbose, uintx* value);
+Flag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose);
+Flag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose);
#endif // INCLUDE_ALL_GCS
-Flag::Error CMSOldPLABMinConstraintFunc(bool verbose, size_t* value);
+Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose);
-Flag::Error CMSPrecleanDenominatorConstraintFunc(bool verbose, uintx* value);
-Flag::Error CMSPrecleanNumeratorConstraintFunc(bool verbose, uintx* value);
+Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose);
+Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose);
-Flag::Error SurvivorAlignmentInBytesConstraintFunc(bool verbose, intx* value);
+Flag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose);
#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSGC_HPP */
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsRuntime.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsRuntime.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -25,25 +25,24 @@
#include "precompiled.hpp"
#include "runtime/arguments.hpp"
#include "runtime/commandLineFlagConstraintsRuntime.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
#include "runtime/globals.hpp"
#include "utilities/defaultStream.hpp"
-Flag::Error ObjectAlignmentInBytesConstraintFunc(bool verbose, intx* value) {
- if (!is_power_of_2(*value)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "ObjectAlignmentInBytes=" INTX_FORMAT " must be power of 2\n",
- *value);
- }
+Flag::Error ObjectAlignmentInBytesConstraintFunc(intx value, bool verbose) {
+ if (!is_power_of_2(value)) {
+ CommandLineError::print(verbose,
+ "ObjectAlignmentInBytes (" INTX_FORMAT ") must be "
+ "power of 2\n",
+ value);
return Flag::VIOLATES_CONSTRAINT;
}
// In case page size is very small.
- if (*value >= (intx)os::vm_page_size()) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "ObjectAlignmentInBytes=" INTX_FORMAT " must be less than page size " INTX_FORMAT "\n",
- *value, (intx)os::vm_page_size());
- }
+ if (value >= (intx)os::vm_page_size()) {
+ CommandLineError::print(verbose,
+ "ObjectAlignmentInBytes (" INTX_FORMAT ") must be "
+ "less than page size " INTX_FORMAT "\n",
+ value, (intx)os::vm_page_size());
return Flag::VIOLATES_CONSTRAINT;
}
return Flag::SUCCESS;
@@ -51,13 +50,12 @@
// Need to enforce the padding not to break the existing field alignments.
// It is sufficient to check against the largest type size.
-Flag::Error ContendedPaddingWidthConstraintFunc(bool verbose, intx* value) {
- if ((*value != 0) && ((*value % BytesPerLong) != 0)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "ContendedPaddingWidth=" INTX_FORMAT " must be a multiple of %d\n",
- *value, BytesPerLong);
- }
+Flag::Error ContendedPaddingWidthConstraintFunc(intx value, bool verbose) {
+ if ((value != 0) && ((value % BytesPerLong) != 0)) {
+ CommandLineError::print(verbose,
+ "ContendedPaddingWidth (" INTX_FORMAT ") must be "
+ "a multiple of %d\n",
+ value, BytesPerLong);
return Flag::VIOLATES_CONSTRAINT;
} else {
return Flag::SUCCESS;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsRuntime.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsRuntime.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -34,8 +34,8 @@
* an appropriate error value.
*/
-Flag::Error ObjectAlignmentInBytesConstraintFunc(bool verbose, intx* value);
+Flag::Error ObjectAlignmentInBytesConstraintFunc(intx value, bool verbose);
-Flag::Error ContendedPaddingWidthConstraintFunc(bool verbose, intx* value);
+Flag::Error ContendedPaddingWidthConstraintFunc(intx value, bool verbose);
#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSRUNTIME_HPP */
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -32,6 +32,15 @@
#include "utilities/defaultStream.hpp"
#include "utilities/macros.hpp"
+void CommandLineError::print(bool verbose, const char* msg, ...) {
+ if (verbose) {
+ va_list listPointer;
+ va_start(listPointer, msg);
+ jio_vfprintf(defaultStream::error_stream(), msg, listPointer);
+ va_end(listPointer);
+ }
+}
+
class CommandLineFlagRange_int : public CommandLineFlagRange {
int _min;
int _max;
@@ -44,11 +53,10 @@
Flag::Error check_int(int value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "int %s=%d is outside the allowed range [ %d ... %d ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "int %s=%d is outside the allowed range "
+ "[ %d ... %d ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -72,11 +80,10 @@
Flag::Error check_intx(intx value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "intx %s=" INTX_FORMAT " is outside the allowed range [ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "intx %s=" INTX_FORMAT " is outside the allowed range "
+ "[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -100,11 +107,10 @@
Flag::Error check_uint(uint value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "uintx %s=%u is outside the allowed range [ %u ... %u ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "uint %s=%u is outside the allowed range "
+ "[ %u ... %u ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -128,11 +134,10 @@
Flag::Error check_uintx(uintx value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "uintx %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "uintx %s=" UINTX_FORMAT " is outside the allowed range "
+ "[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -156,11 +161,10 @@
Flag::Error check_uint64_t(uint64_t value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "uint64_t %s=" UINT64_FORMAT " is outside the allowed range [ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "uint64_t %s=" UINT64_FORMAT " is outside the allowed range "
+ "[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -184,11 +188,10 @@
Flag::Error check_size_t(size_t value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "size_t %s=" SIZE_FORMAT " is outside the allowed range [ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "size_t %s=" SIZE_FORMAT " is outside the allowed range "
+ "[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -212,11 +215,10 @@
Flag::Error check_double(double value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
- if (verbose == true) {
- jio_fprintf(defaultStream::error_stream(),
- "double %s=%f is outside the allowed range [ %f ... %f ]\n",
- name(), value, _min, _max);
- }
+ CommandLineError::print(verbose,
+ "double %s=%f is outside the allowed range "
+ "[ %f ... %f ]\n",
+ name(), value, _min, _max);
return Flag::OUT_OF_BOUNDS;
} else {
return Flag::SUCCESS;
@@ -300,48 +302,48 @@
EMIT_RANGES_FOR_GLOBALS_EXT
emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
- EMIT_RANGE_PRODUCT_FLAG,
- EMIT_RANGE_DIAGNOSTIC_FLAG,
- EMIT_RANGE_EXPERIMENTAL_FLAG,
- EMIT_RANGE_NOTPRODUCT_FLAG,
- EMIT_RANGE_CHECK,
- IGNORE_CONSTRAINT));
+ EMIT_RANGE_PRODUCT_FLAG,
+ EMIT_RANGE_DIAGNOSTIC_FLAG,
+ EMIT_RANGE_EXPERIMENTAL_FLAG,
+ EMIT_RANGE_NOTPRODUCT_FLAG,
+ EMIT_RANGE_CHECK,
+ IGNORE_CONSTRAINT));
#ifdef COMPILER1
emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
- EMIT_RANGE_PD_DEVELOPER_FLAG,
- EMIT_RANGE_PRODUCT_FLAG,
- EMIT_RANGE_PD_PRODUCT_FLAG,
- EMIT_RANGE_DIAGNOSTIC_FLAG,
- EMIT_RANGE_NOTPRODUCT_FLAG,
- EMIT_RANGE_CHECK,
- IGNORE_CONSTRAINT));
+ EMIT_RANGE_PD_DEVELOPER_FLAG,
+ EMIT_RANGE_PRODUCT_FLAG,
+ EMIT_RANGE_PD_PRODUCT_FLAG,
+ EMIT_RANGE_DIAGNOSTIC_FLAG,
+ EMIT_RANGE_NOTPRODUCT_FLAG,
+ EMIT_RANGE_CHECK,
+ IGNORE_CONSTRAINT));
#endif // COMPILER1
#ifdef COMPILER2
emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
- EMIT_RANGE_PD_DEVELOPER_FLAG,
- EMIT_RANGE_PRODUCT_FLAG,
- EMIT_RANGE_PD_PRODUCT_FLAG,
- EMIT_RANGE_DIAGNOSTIC_FLAG,
- EMIT_RANGE_EXPERIMENTAL_FLAG,
- EMIT_RANGE_NOTPRODUCT_FLAG,
- EMIT_RANGE_CHECK,
- IGNORE_CONSTRAINT));
+ EMIT_RANGE_PD_DEVELOPER_FLAG,
+ EMIT_RANGE_PRODUCT_FLAG,
+ EMIT_RANGE_PD_PRODUCT_FLAG,
+ EMIT_RANGE_DIAGNOSTIC_FLAG,
+ EMIT_RANGE_EXPERIMENTAL_FLAG,
+ EMIT_RANGE_NOTPRODUCT_FLAG,
+ EMIT_RANGE_CHECK,
+ IGNORE_CONSTRAINT));
#endif // COMPILER2
#if INCLUDE_ALL_GCS
emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
- EMIT_RANGE_PD_DEVELOPER_FLAG,
- EMIT_RANGE_PRODUCT_FLAG,
- EMIT_RANGE_PD_PRODUCT_FLAG,
- EMIT_RANGE_DIAGNOSTIC_FLAG,
- EMIT_RANGE_EXPERIMENTAL_FLAG,
- EMIT_RANGE_NOTPRODUCT_FLAG,
- EMIT_RANGE_MANAGEABLE_FLAG,
- EMIT_RANGE_PRODUCT_RW_FLAG,
- EMIT_RANGE_CHECK,
- IGNORE_CONSTRAINT));
+ EMIT_RANGE_PD_DEVELOPER_FLAG,
+ EMIT_RANGE_PRODUCT_FLAG,
+ EMIT_RANGE_PD_PRODUCT_FLAG,
+ EMIT_RANGE_DIAGNOSTIC_FLAG,
+ EMIT_RANGE_EXPERIMENTAL_FLAG,
+ EMIT_RANGE_NOTPRODUCT_FLAG,
+ EMIT_RANGE_MANAGEABLE_FLAG,
+ EMIT_RANGE_PRODUCT_RW_FLAG,
+ EMIT_RANGE_CHECK,
+ IGNORE_CONSTRAINT));
#endif // INCLUDE_ALL_GCS
}
@@ -367,45 +369,23 @@
}
bool CommandLineFlagRangeList::check_ranges() {
-//#define PRINT_RANGES_SIZES
-#ifdef PRINT_RANGES_SIZES
- {
- size_t size_ranges = sizeof(CommandLineFlagRangeList);
- for (int i=0; i<length(); i++) {
- size_ranges += sizeof(CommandLineFlagRange);
- CommandLineFlagRange* range = at(i);
- const char* name = range->name();
- Flag* flag = Flag::find_flag(name, strlen(name), true, true);
- if (flag->is_intx()) {
- size_ranges += 2*sizeof(intx);
- size_ranges += sizeof(CommandLineFlagRange*);
- } else if (flag->is_uintx()) {
- size_ranges += 2*sizeof(uintx);
- size_ranges += sizeof(CommandLineFlagRange*);
- } else if (flag->is_uint64_t()) {
- size_ranges += 2*sizeof(uint64_t);
- size_ranges += sizeof(CommandLineFlagRange*);
- } else if (flag->is_size_t()) {
- size_ranges += 2*sizeof(size_t);
- size_ranges += sizeof(CommandLineFlagRange*);
- } else if (flag->is_double()) {
- size_ranges += 2*sizeof(double);
- size_ranges += sizeof(CommandLineFlagRange*);
- }
- }
- fprintf(stderr, "Size of %d ranges: " SIZE_FORMAT " bytes\n",
- length(), size_ranges);
- }
-#endif // PRINT_RANGES_SIZES
-
// Check ranges.
bool status = true;
for (int i=0; i<length(); i++) {
CommandLineFlagRange* range = at(i);
const char* name = range->name();
Flag* flag = Flag::find_flag(name, strlen(name), true, true);
+ // We must check for NULL here as lp64_product flags on 32 bit architecture
+ // can generate range check (despite that they are declared as constants),
+ // but they will not be returned by Flag::find_flag()
if (flag != NULL) {
- if (flag->is_intx()) {
+ if (flag->is_int()) {
+ int value = flag->get_int();
+ if (range->check_int(value, true) != Flag::SUCCESS) status = false;
+ } else if (flag->is_uint()) {
+ uint value = flag->get_uint();
+ if (range->check_uint(value, true) != Flag::SUCCESS) status = false;
+ } else if (flag->is_intx()) {
intx value = flag->get_intx();
if (range->check_intx(value, true) != Flag::SUCCESS) status = false;
} else if (flag->is_uintx()) {
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -38,6 +38,11 @@
* then we need to use constraint instead.
*/
+class CommandLineError : public AllStatic {
+public:
+ static void print(bool verbose, const char* msg, ...);
+};
+
class CommandLineFlagRange : public CHeapObj<mtInternal> {
private:
const char* _name;
--- a/hotspot/src/share/vm/runtime/globals.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -515,6 +515,20 @@
}
}
+const char* Flag::flag_error_str(Flag::Error error) {
+ switch (error) {
+ case Flag::MISSING_NAME: return "MISSING_NAME";
+ case Flag::MISSING_VALUE: return "MISSING_VALUE";
+ case Flag::NON_WRITABLE: return "NON_WRITABLE";
+ case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS";
+ case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT";
+ case Flag::INVALID_FLAG: return "INVALID_FLAG";
+ case Flag::ERR_OTHER: return "ERR_OTHER";
+ case Flag::SUCCESS: return "SUCCESS";
+ default: ShouldNotReachHere(); return "NULL";
+ }
+}
+
// 4991491 do not "optimize out" the was_set false values: omitting them
// tickles a Microsoft compiler bug causing flagTable to be malformed
@@ -758,17 +772,7 @@
e.commit();
}
-static Flag::Error get_status_error(Flag::Error status_range, Flag::Error status_constraint) {
- if (status_range != Flag::SUCCESS) {
- return status_range;
- } else if (status_constraint != Flag::SUCCESS) {
- return status_constraint;
- } else {
- return Flag::SUCCESS;
- }
-}
-
-static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool* new_value, bool verbose = true) {
+static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose = true) {
Flag::Error status = Flag::SUCCESS;
CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
if (constraint != NULL) {
@@ -789,7 +793,7 @@
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_bool()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_bool(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_bool(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
bool old_value = result->get_bool();
trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
@@ -802,7 +806,7 @@
Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
- Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, &value);
+ Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, value);
if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
faddr->set_bool(value);
@@ -810,18 +814,19 @@
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_int(const char* name, int* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_int(*new_value, verbose);
+ status = range->check_int(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_int(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_int(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
@@ -836,7 +841,7 @@
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_int()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_int(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
int old_value = result->get_int();
trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
@@ -849,24 +854,27 @@
Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
+ Flag::Error check = apply_constraint_and_check_range_int(faddr->_name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
faddr->set_int(value);
faddr->set_origin(origin);
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_uint(*new_value, verbose);
+ status = range->check_uint(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_uint(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_uint(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
@@ -881,7 +889,7 @@
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_uint()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_uint(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
uint old_value = result->get_uint();
trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
@@ -894,6 +902,8 @@
Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
+ Flag::Error check = apply_constraint_and_check_range_uint(faddr->_name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
faddr->set_uint(value);
faddr->set_origin(origin);
@@ -908,25 +918,26 @@
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_intx(*new_value, verbose);
+ status = range->check_intx(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_intx(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_intx(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_intx()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_intx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
intx old_value = result->get_intx();
trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
@@ -939,7 +950,7 @@
Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
- Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, &value);
+ Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, value);
if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
faddr->set_intx(value);
@@ -955,25 +966,26 @@
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_uintx(*new_value, verbose);
+ status = range->check_uintx(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_uintx(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_uintx(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_uintx()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_uintx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
uintx old_value = result->get_uintx();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
@@ -986,7 +998,7 @@
Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
- Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, &value);
+ Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, value);
if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
faddr->set_uintx(value);
@@ -1002,25 +1014,26 @@
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_uint64_t(*new_value, verbose);
+ status = range->check_uint64_t(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_uint64_t(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_uint64_t(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
uint64_t old_value = result->get_uint64_t();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
@@ -1033,7 +1046,7 @@
Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
- Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, &value);
+ Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, value);
if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
faddr->set_uint64_t(value);
@@ -1049,25 +1062,26 @@
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_size_t(*new_value, verbose);
+ status = range->check_size_t(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_size_t(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_size_t(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_size_t()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_size_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
size_t old_value = result->get_size_t();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
@@ -1080,7 +1094,7 @@
Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
- Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, &value);
+ Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, value);
if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
faddr->set_size_t(value);
@@ -1096,25 +1110,26 @@
return Flag::SUCCESS;
}
-static Flag::Error apply_constraint_and_check_range_double(const char* name, double* new_value, bool verbose = true) {
- Flag::Error range_status = Flag::SUCCESS;
+static Flag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose = true) {
+ Flag::Error status = Flag::SUCCESS;
CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
if (range != NULL) {
- range_status = range->check_double(*new_value, verbose);
+ status = range->check_double(new_value, verbose);
}
- Flag::Error constraint_status = Flag::SUCCESS;
- CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
- if (constraint != NULL) {
- constraint_status = constraint->apply_double(new_value, verbose);
+ if (status == Flag::SUCCESS) {
+ CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name);
+ if (constraint != NULL) {
+ status = constraint->apply_double(new_value, verbose);
+ }
}
- return get_status_error(range_status, constraint_status);
+ return status;
}
Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return Flag::INVALID_FLAG;
if (!result->is_double()) return Flag::WRONG_FORMAT;
- Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlagConstraintList::validated_after_ergo());
+ Flag::Error check = apply_constraint_and_check_range_double(name, *value, !CommandLineFlagConstraintList::validated_after_ergo());
if (check != Flag::SUCCESS) return check;
double old_value = result->get_double();
trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
@@ -1127,7 +1142,7 @@
Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
- Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value);
+ Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, value);
if (check != Flag::SUCCESS) return check;
trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
faddr->set_double(value);
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Aug 20 09:31:28 2015 +0200
@@ -372,19 +372,7 @@
void print_kind(outputStream* st);
void print_as_flag(outputStream* st);
- static const char* flag_error_str(Flag::Error error) {
- switch (error) {
- case Flag::MISSING_NAME: return "MISSING_NAME";
- case Flag::MISSING_VALUE: return "MISSING_VALUE";
- case Flag::NON_WRITABLE: return "NON_WRITABLE";
- case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS";
- case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT";
- case Flag::INVALID_FLAG: return "INVALID_FLAG";
- case Flag::ERR_OTHER: return "ERR_OTHER";
- case Flag::SUCCESS: return "SUCCESS";
- default: return "NULL";
- }
- }
+ static const char* flag_error_str(Flag::Error error);
};
// debug flags control various aspects of the VM and are global accessible
@@ -1564,6 +1552,10 @@
product(uint, ParallelGCThreads, 0, \
"Number of parallel threads parallel gc will use") \
\
+ diagnostic(bool, UseSemaphoreGCThreadsSynchronization, true, \
+ "Use semaphore synchronization for the GC Threads, " \
+ "instead of synchronization based on mutexes") \
+ \
product(bool, UseDynamicNumberOfGCThreads, false, \
"Dynamically choose the number of parallel threads " \
"parallel gc will use") \
@@ -1575,7 +1567,7 @@
product(size_t, HeapSizePerGCThread, ScaleForWordSize(64*M), \
"Size of heap (bytes) per GC thread used in calculating the " \
"number of GC threads") \
- range((uintx)os::vm_page_size(), max_uintx) \
+ range((size_t)os::vm_page_size(), (size_t)max_uintx) \
\
product(bool, TraceDynamicGCThreads, false, \
"Trace the dynamic GC thread usage") \
@@ -1856,6 +1848,7 @@
product(size_t, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M), \
"Size of marking stack") \
\
+ /* where does the range max value of (max_jint - 1) come from? */ \
product(size_t, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M), \
"Maximum size of marking stack") \
range(1, (max_jint - 1)) \
@@ -2920,12 +2913,6 @@
notproduct(bool, ICMissHistogram, false, \
"Produce histogram of IC misses") \
\
- notproduct(bool, PrintClassStatistics, false, \
- "Print class statistics at end of run") \
- \
- notproduct(bool, PrintMethodStatistics, false, \
- "Print method statistics at end of run") \
- \
/* interpreter */ \
develop(bool, ClearInterpreterLocals, false, \
"Always clear local variables of interpreter activations upon " \
--- a/hotspot/src/share/vm/runtime/java.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/java.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -304,13 +304,6 @@
CodeCache::print_internals();
}
- if (PrintClassStatistics) {
- SystemDictionary::print_class_statistics();
- }
- if (PrintMethodStatistics) {
- SystemDictionary::print_method_statistics();
- }
-
if (PrintVtableStats) {
klassVtable::print_statistics();
klassItable::print_statistics();
--- a/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -3331,7 +3331,6 @@
// Final check of all 'AfterErgo' constraints after ergonomics which may change values.
bool constraint_result = CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::AfterErgo);
- Arguments::post_after_ergo_constraint_check(constraint_result);
if (!constraint_result) {
return JNI_EINVAL;
}
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Aug 20 09:31:28 2015 +0200
@@ -405,7 +405,7 @@
nonstatic_field(ObjArrayKlass, _element_klass, Klass*) \
nonstatic_field(ObjArrayKlass, _bottom_klass, Klass*) \
volatile_nonstatic_field(Symbol, _refcount, short) \
- nonstatic_field(Symbol, _identity_hash, int) \
+ nonstatic_field(Symbol, _identity_hash, short) \
nonstatic_field(Symbol, _length, unsigned short) \
unchecked_nonstatic_field(Symbol, _body, sizeof(jbyte)) /* NOTE: no type */ \
nonstatic_field(TypeArrayKlass, _max_length, int) \
--- a/hotspot/test/compiler/arguments/CheckCICompilerCount.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/test/compiler/arguments/CheckCICompilerCount.java Thu Aug 20 09:31:28 2015 +0200
@@ -68,7 +68,7 @@
private static final String[][] NON_TIERED_EXPECTED_OUTPUTS = {
{
- "CICompilerCount=0 must be at least 1",
+ "CICompilerCount (0) must be at least 1",
"Improperly specified VM option 'CICompilerCount=0'"
},
{
@@ -123,7 +123,7 @@
private static final String[][] TIERED_EXPECTED_OUTPUTS = {
{
- "CICompilerCount=1 must be at least 2",
+ "CICompilerCount (1) must be at least 2",
"Improperly specified VM option 'CICompilerCount=1'"
},
{
--- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Wed Jul 29 17:25:04 2015 +0200
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Thu Aug 20 09:31:28 2015 +0200
@@ -28,7 +28,6 @@
* when their age exceeded tenuring threshold are not aligned to
* SurvivorAlignmentInBytes value.
* @library /testlibrary /../../test/lib
- * @ignore 8130308
* @modules java.base/sun.misc
* java.management
* @build TestPromotionFromSurvivorToTenuredAfterMinorGC
@@ -99,11 +98,18 @@
.getActualMemoryUsage();
test.allocate();
- for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD;
- i++) {
+ for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD; i++) {
SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
}
+ // Sometimes we see that data unrelated to the test has been allocated during
+ // the loop. This data is included in the expectedMemoryUsage since we look
+ // through all threads to see what they allocated. If this data is still in
+ // the survivor area however, it should not be included in expectedMemoryUsage
+ // since the verification below only look at what's in tenured space.
+ expectedMemoryUsage -= SurvivorAlignmentTestMain.getAlignmentHelper(
+ SurvivorAlignmentTestMain.HeapSpace.SURVIVOR)
+ .getActualMemoryUsage();
test.verifyMemoryUsage(expectedMemoryUsage);
}
}