# HG changeset patch # User jmasa # Date 1457378886 28800 # Mon Mar 07 11:28:06 2016 -0800 # Node ID e1ae3a3980fb8399e08deb3fd744533f8d3bf76e # Parent 4aa1760ab75cf5c0c6b568e677e933419ab5ba5e 8149343: assert(rp->num_q() == no_of_gc_workers) failed: sanity diff --git a/src/share/vm/gc/g1/g1CollectedHeap.cpp b/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -4291,7 +4291,7 @@ _workers(workers), _active_workers(n_workers) { - assert(n_workers > 0, "shouldn't call this otherwise"); + g1h->ref_processor_stw()->set_active_mt_degree(n_workers); } // Executes the given task using concurrent marking worker threads. @@ -4412,7 +4412,9 @@ _queues(task_queues), _terminator(workers, _queues), _n_workers(workers) - { } + { + g1h->ref_processor_cm()->set_active_mt_degree(workers); + } void work(uint worker_id) { G1GCParPhaseTimesTracker x(_g1h->g1_policy()->phase_times(), G1GCPhaseTimes::PreserveCMReferents, worker_id); @@ -4555,8 +4557,9 @@ uint no_of_gc_workers = workers()->active_workers(); // Parallel reference processing - assert(rp->num_q() == no_of_gc_workers, "sanity"); - assert(no_of_gc_workers <= rp->max_num_q(), "sanity"); + assert(no_of_gc_workers <= rp->max_num_q(), + "Mismatch between the number of GC workers %u and the maximum number of Reference process queues %u", + no_of_gc_workers, rp->max_num_q()); G1STWRefProcTaskExecutor par_task_executor(this, per_thread_states, workers(), _task_queues, no_of_gc_workers); stats = rp->process_discovered_references(&is_alive, @@ -4592,8 +4595,9 @@ uint n_workers = workers()->active_workers(); - assert(rp->num_q() == n_workers, "sanity"); - assert(n_workers <= rp->max_num_q(), "sanity"); + assert(n_workers <= rp->max_num_q(), + "Mismatch between the number of GC workers %u and the maximum number of Reference process queues %u", + n_workers, rp->max_num_q()); G1STWRefProcTaskExecutor par_task_executor(this, per_thread_states, workers(), _task_queues, n_workers); rp->enqueue_discovered_references(&par_task_executor); diff --git a/src/share/vm/gc/shared/referenceProcessor.cpp b/src/share/vm/gc/shared/referenceProcessor.cpp --- a/src/share/vm/gc/shared/referenceProcessor.cpp +++ b/src/share/vm/gc/shared/referenceProcessor.cpp @@ -134,7 +134,7 @@ guarantee(!_discovering_refs, "Discovering refs?"); for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { guarantee(_discovered_refs[i].is_empty(), - "Found non-empty discovered list"); + "Found non-empty discovered list at %u", i); } } #endif @@ -683,13 +683,13 @@ }; #ifndef PRODUCT -void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], size_t total_refs) { +void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_refs) { if (!log_is_enabled(Trace, gc, ref)) { return; } stringStream st; - for (uint i = 0; i < _max_num_q; ++i) { + for (uint i = 0; i < active_length; ++i) { st.print(SIZE_FORMAT " ", ref_lists[i].length()); } log_develop_trace(gc, ref)("%s= " SIZE_FORMAT, st.as_string(), total_refs); @@ -709,7 +709,7 @@ for (uint i = 0; i < _max_num_q; ++i) { total_refs += ref_lists[i].length(); } - log_reflist_counts(ref_lists, total_refs); + log_reflist_counts(ref_lists, _max_num_q, total_refs); size_t avg_refs = total_refs / _num_q + 1; uint to_idx = 0; for (uint from_idx = 0; from_idx < _max_num_q; from_idx++) { @@ -771,10 +771,10 @@ } #ifdef ASSERT size_t balanced_total_refs = 0; - for (uint i = 0; i < _max_num_q; ++i) { + for (uint i = 0; i < _num_q; ++i) { balanced_total_refs += ref_lists[i].length(); } - log_reflist_counts(ref_lists, balanced_total_refs); + log_reflist_counts(ref_lists, _num_q, balanced_total_refs); assert(total_refs == balanced_total_refs, "Balancing was incomplete"); #endif } @@ -868,7 +868,7 @@ id = next_id(); } } - assert(id < _max_num_q, "Id is out-of-bounds (call Freud?)"); + assert(id < _max_num_q, "Id is out-of-bounds id %u and max id %u)", id, _max_num_q); // Get the discovered queue to which we will add DiscoveredList* list = NULL; diff --git a/src/share/vm/gc/shared/referenceProcessor.hpp b/src/share/vm/gc/shared/referenceProcessor.hpp --- a/src/share/vm/gc/shared/referenceProcessor.hpp +++ b/src/share/vm/gc/shared/referenceProcessor.hpp @@ -326,9 +326,11 @@ // round-robin mod _num_q (not: _not_ mode _max_num_q) uint next_id() { uint id = _next_id; - if (++_next_id == _num_q) { + assert(!_discovery_is_mt, "Round robin should only be used in serial discovery"); + if (++_next_id >= _num_q) { _next_id = 0; } + assert(_next_id < _num_q, "_next_id %u _num_q %u _max_num_q %u", _next_id, _num_q, _max_num_q); return id; } DiscoveredList* get_discovered_list(ReferenceType rt); @@ -340,7 +342,7 @@ // Calculate the number of jni handles. size_t count_jni_refs(); - void log_reflist_counts(DiscoveredList ref_lists[], size_t total_count) PRODUCT_RETURN; + void log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_count) PRODUCT_RETURN; // Balances reference queues. void balance_queues(DiscoveredList ref_lists[]); diff --git a/test/gc/ergonomics/TestDynamicNumberOfGCThreads.java b/test/gc/ergonomics/TestDynamicNumberOfGCThreads.java --- a/test/gc/ergonomics/TestDynamicNumberOfGCThreads.java +++ b/test/gc/ergonomics/TestDynamicNumberOfGCThreads.java @@ -63,6 +63,14 @@ System.arraycopy(baseArgs, 0, finalArgs, extraArgs.length, baseArgs.length); pb_enabled = ProcessTools.createJavaProcessBuilder(finalArgs); verifyDynamicNumberOfGCThreads(new OutputAnalyzer(pb_enabled.start())); + + // Turn on parallel reference processing + String[] parRefProcArg = {"-XX:+ParallelRefProcEnabled", "-XX:-ShowMessageBoxOnError"}; + String[] parRefArgs = new String[baseArgs.length + parRefProcArg.length]; + System.arraycopy(parRefProcArg, 0, parRefArgs, 0, parRefProcArg.length); + System.arraycopy(baseArgs, 0, parRefArgs, parRefProcArg.length, baseArgs.length); + pb_enabled = ProcessTools.createJavaProcessBuilder(parRefArgs); + verifyDynamicNumberOfGCThreads(new OutputAnalyzer(pb_enabled.start())); } static class GCTest { # HG changeset patch # User jmasa # Date 1458099891 25200 # Tue Mar 15 20:44:51 2016 -0700 # Node ID 1027302ed8d1e1ab04fb6a8c88283cbdd75146b0 # Parent e1ae3a3980fb8399e08deb3fd744533f8d3bf76e [mq]: initialize diff --git a/src/share/vm/gc/shared/referenceProcessor.cpp b/src/share/vm/gc/shared/referenceProcessor.cpp --- a/src/share/vm/gc/shared/referenceProcessor.cpp +++ b/src/share/vm/gc/shared/referenceProcessor.cpp @@ -696,6 +696,11 @@ } #endif +void ReferenceProcessor::set_active_mt_degree(uint v) { + _num_q = v; + _next_id = 0; +} + // Balances reference queues. // Move entries from all queues[0, 1, ..., _max_num_q-1] to // queues[0, 1, ..., _num_q-1] because only the first _num_q diff --git a/src/share/vm/gc/shared/referenceProcessor.hpp b/src/share/vm/gc/shared/referenceProcessor.hpp --- a/src/share/vm/gc/shared/referenceProcessor.hpp +++ b/src/share/vm/gc/shared/referenceProcessor.hpp @@ -225,7 +225,7 @@ uint num_q() { return _num_q; } uint max_num_q() { return _max_num_q; } - void set_active_mt_degree(uint v) { _num_q = v; } + void set_active_mt_degree(uint v); DiscoveredList* discovered_refs() { return _discovered_refs; } @@ -327,7 +327,7 @@ uint next_id() { uint id = _next_id; assert(!_discovery_is_mt, "Round robin should only be used in serial discovery"); - if (++_next_id >= _num_q) { + if (++_next_id == _num_q) { _next_id = 0; } assert(_next_id < _num_q, "_next_id %u _num_q %u _max_num_q %u", _next_id, _num_q, _max_num_q);