OpenJDK / bsd-port / jdk9 / hotspot
changeset 8861:5ca290fb5d6e
Merge
author | roland |
---|---|
date | Thu, 20 Aug 2015 09:31:28 +0200 |
parents | fe311de64c61 e9d225520e8c |
children | 585dd7e5e806 8bc4eb358829 |
files | |
diffstat | 51 files changed, 993 insertions(+), 1243 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/cpu/x86/vm/templateTable_x86.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/os/linux/vm/os_linux.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/classfile/systemDictionary.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/classfile/systemDictionary.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/cms/parNewGeneration.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/cms/yieldingWorkgroup.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/cms/yieldingWorkgroup.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/concurrentMark.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/concurrentMark.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/concurrentMark.inline.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/g1CollectedHeap.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/g1CollectorPolicy.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/g1RootProcessor.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/g1/g1RootProcessor.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/shared/collectorPolicy.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/shared/collectorPolicy.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/shared/genCollectedHeap.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/shared/workgroup.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/gc/shared/workgroup.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/oops/symbol.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/oops/symbol.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/arguments.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/arguments.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintList.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintList.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintsCompiler.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintsRuntime.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagConstraintsRuntime.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagRangeList.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/commandLineFlagRangeList.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/globals.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/globals.hpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/java.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/thread.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/src/share/vm/runtime/vmStructs.cpp Wed Jul 29 17:25:04 2015 +0200 +++ b/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/test/compiler/arguments/CheckCICompilerCount.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Wed Jul 29 17:25:04 2015 +0200 +++ b/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); } }