| File: | jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp |
| Warning: | line 246, column 24 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. | |||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
| 4 | * | |||
| 5 | * This code is free software; you can redistribute it and/or modify it | |||
| 6 | * under the terms of the GNU General Public License version 2 only, as | |||
| 7 | * published by the Free Software Foundation. | |||
| 8 | * | |||
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT | |||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
| 12 | * version 2 for more details (a copy is included in the LICENSE file that | |||
| 13 | * accompanied this code). | |||
| 14 | * | |||
| 15 | * You should have received a copy of the GNU General Public License version | |||
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, | |||
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
| 18 | * | |||
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
| 20 | * or visit www.oracle.com if you need additional information or have any | |||
| 21 | * questions. | |||
| 22 | * | |||
| 23 | */ | |||
| 24 | ||||
| 25 | #include "precompiled.hpp" | |||
| 26 | #include "gc/g1/g1BarrierSet.hpp" | |||
| 27 | #include "gc/g1/g1ConcurrentRefine.hpp" | |||
| 28 | #include "gc/g1/g1ConcurrentRefineThread.hpp" | |||
| 29 | #include "gc/g1/g1DirtyCardQueue.hpp" | |||
| 30 | #include "logging/log.hpp" | |||
| 31 | #include "memory/allocation.inline.hpp" | |||
| 32 | #include "memory/iterator.hpp" | |||
| 33 | #include "runtime/globals_extension.hpp" | |||
| 34 | #include "runtime/java.hpp" | |||
| 35 | #include "runtime/thread.hpp" | |||
| 36 | #include "utilities/debug.hpp" | |||
| 37 | #include "utilities/formatBuffer.hpp" | |||
| 38 | #include "utilities/globalDefinitions.hpp" | |||
| 39 | #include "utilities/pair.hpp" | |||
| 40 | #include <math.h> | |||
| 41 | ||||
| 42 | G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) { | |||
| 43 | G1ConcurrentRefineThread* result = NULL__null; | |||
| 44 | if (initializing || !InjectGCWorkerCreationFailure) { | |||
| 45 | result = new G1ConcurrentRefineThread(_cr, worker_id); | |||
| 46 | } | |||
| 47 | if (result == NULL__null || result->osthread() == NULL__null) { | |||
| 48 | log_warning(gc)(!(LogImpl<(LogTag::_gc), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Warning))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Warning>("Failed to create refinement thread %u, no more %s", | |||
| 49 | worker_id, | |||
| 50 | result == NULL__null ? "memory" : "OS threads"); | |||
| 51 | } | |||
| 52 | return result; | |||
| 53 | } | |||
| 54 | ||||
| 55 | G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() : | |||
| 56 | _cr(NULL__null), | |||
| 57 | _threads(NULL__null), | |||
| 58 | _num_max_threads(0) | |||
| 59 | { | |||
| 60 | } | |||
| 61 | ||||
| 62 | G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() { | |||
| 63 | for (uint i = 0; i < _num_max_threads; i++) { | |||
| 64 | G1ConcurrentRefineThread* t = _threads[i]; | |||
| 65 | if (t != NULL__null) { | |||
| 66 | delete t; | |||
| 67 | } | |||
| 68 | } | |||
| 69 | FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads)FreeHeap((char*)(_threads)); | |||
| 70 | } | |||
| 71 | ||||
| 72 | jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint num_max_threads) { | |||
| 73 | assert(cr != NULL, "G1ConcurrentRefine must not be NULL")do { if (!(cr != __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 73, "assert(" "cr != __null" ") failed", "G1ConcurrentRefine must not be NULL" ); ::breakpoint(); } } while (0); | |||
| 74 | _cr = cr; | |||
| 75 | _num_max_threads = num_max_threads; | |||
| 76 | ||||
| 77 | _threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, num_max_threads, mtGC)(G1ConcurrentRefineThread**) (AllocateHeap((num_max_threads) * sizeof(G1ConcurrentRefineThread*), mtGC)); | |||
| 78 | ||||
| 79 | for (uint i = 0; i < num_max_threads; i++) { | |||
| 80 | if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) { | |||
| 81 | _threads[i] = NULL__null; | |||
| 82 | } else { | |||
| 83 | _threads[i] = create_refinement_thread(i, true); | |||
| 84 | if (_threads[i] == NULL__null) { | |||
| 85 | vm_shutdown_during_initialization("Could not allocate refinement threads."); | |||
| 86 | return JNI_ENOMEM(-4); | |||
| 87 | } | |||
| 88 | } | |||
| 89 | } | |||
| 90 | ||||
| 91 | if (num_max_threads > 0) { | |||
| 92 | G1BarrierSet::dirty_card_queue_set().set_primary_refinement_thread(_threads[0]); | |||
| 93 | } | |||
| 94 | ||||
| 95 | return JNI_OK0; | |||
| 96 | } | |||
| 97 | ||||
| 98 | void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) { | |||
| 99 | assert(cur_worker_id < _num_max_threads,do { if (!(cur_worker_id < _num_max_threads)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 101, "assert(" "cur_worker_id < _num_max_threads" ") failed" , "Activating another thread from %u not allowed since there can be at most %u" , cur_worker_id, _num_max_threads); ::breakpoint(); } } while (0) | |||
| 100 | "Activating another thread from %u not allowed since there can be at most %u",do { if (!(cur_worker_id < _num_max_threads)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 101, "assert(" "cur_worker_id < _num_max_threads" ") failed" , "Activating another thread from %u not allowed since there can be at most %u" , cur_worker_id, _num_max_threads); ::breakpoint(); } } while (0) | |||
| 101 | cur_worker_id, _num_max_threads)do { if (!(cur_worker_id < _num_max_threads)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 101, "assert(" "cur_worker_id < _num_max_threads" ") failed" , "Activating another thread from %u not allowed since there can be at most %u" , cur_worker_id, _num_max_threads); ::breakpoint(); } } while (0); | |||
| 102 | if (cur_worker_id == (_num_max_threads - 1)) { | |||
| 103 | // Already the last thread, there is no more thread to activate. | |||
| 104 | return; | |||
| 105 | } | |||
| 106 | ||||
| 107 | uint worker_id = cur_worker_id + 1; | |||
| 108 | G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id]; | |||
| 109 | if (thread_to_activate == NULL__null) { | |||
| 110 | // Still need to create the thread... | |||
| 111 | _threads[worker_id] = create_refinement_thread(worker_id, false); | |||
| 112 | thread_to_activate = _threads[worker_id]; | |||
| 113 | } | |||
| 114 | if (thread_to_activate != NULL__null) { | |||
| 115 | thread_to_activate->activate(); | |||
| 116 | } | |||
| 117 | } | |||
| 118 | ||||
| 119 | void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) { | |||
| 120 | for (uint i = 0; i < _num_max_threads; i++) { | |||
| 121 | if (_threads[i] != NULL__null) { | |||
| 122 | tc->do_thread(_threads[i]); | |||
| 123 | } | |||
| 124 | } | |||
| 125 | } | |||
| 126 | ||||
| 127 | void G1ConcurrentRefineThreadControl::stop() { | |||
| 128 | for (uint i = 0; i < _num_max_threads; i++) { | |||
| 129 | if (_threads[i] != NULL__null) { | |||
| 130 | _threads[i]->stop(); | |||
| 131 | } | |||
| 132 | } | |||
| 133 | } | |||
| 134 | ||||
| 135 | // Arbitrary but large limits, to simplify some of the zone calculations. | |||
| 136 | // The general idea is to allow expressions like | |||
| 137 | // MIN2(x OP y, max_XXX_zone) | |||
| 138 | // without needing to check for overflow in "x OP y", because the | |||
| 139 | // ranges for x and y have been restricted. | |||
| 140 | STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2))static_assert((sizeof(jint ) <= (sizeof(size_t)/2)), "sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2)" ); | |||
| 141 | const size_t max_yellow_zone = LP64_ONLY(max_jint)max_jint NOT_LP64(max_jshort); | |||
| 142 | const size_t max_green_zone = max_yellow_zone / 2; | |||
| 143 | const size_t max_red_zone = INT_MAX2147483647; // For dcqs.set_max_cards. | |||
| 144 | STATIC_ASSERT(max_yellow_zone <= max_red_zone)static_assert((max_yellow_zone <= max_red_zone), "max_yellow_zone <= max_red_zone" ); | |||
| 145 | ||||
| 146 | // Range check assertions for green zone values. | |||
| 147 | #define assert_zone_constraints_g(green)do { size_t azc_g_green = (green); do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 147, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0) \ | |||
| 148 | do { \ | |||
| 149 | size_t azc_g_green = (green); \ | |||
| 150 | assert(azc_g_green <= max_green_zone, \do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 151, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0) | |||
| 151 | "green exceeds max: " SIZE_FORMAT, azc_g_green)do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 151, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); \ | |||
| 152 | } while (0) | |||
| 153 | ||||
| 154 | // Range check assertions for green and yellow zone values. | |||
| 155 | #define assert_zone_constraints_gy(green, yellow)do { size_t azc_gy_green = (green); size_t azc_gy_yellow = (yellow ); do { size_t azc_g_green = (azc_gy_green); do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 155, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0); do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 155, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0); do { if (!(azc_gy_green <= azc_gy_yellow )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 155, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0); } while (0) \ | |||
| 156 | do { \ | |||
| 157 | size_t azc_gy_green = (green); \ | |||
| 158 | size_t azc_gy_yellow = (yellow); \ | |||
| 159 | assert_zone_constraints_g(azc_gy_green)do { size_t azc_g_green = (azc_gy_green); do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 159, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0); \ | |||
| 160 | assert(azc_gy_yellow <= max_yellow_zone, \do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 161, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0) | |||
| 161 | "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow)do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 161, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0); \ | |||
| 162 | assert(azc_gy_green <= azc_gy_yellow, \do { if (!(azc_gy_green <= azc_gy_yellow)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 164, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0) | |||
| 163 | "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")", \do { if (!(azc_gy_green <= azc_gy_yellow)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 164, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0) | |||
| 164 | azc_gy_green, azc_gy_yellow)do { if (!(azc_gy_green <= azc_gy_yellow)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 164, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0); \ | |||
| 165 | } while (0) | |||
| 166 | ||||
| 167 | // Range check assertions for green, yellow, and red zone values. | |||
| 168 | #define assert_zone_constraints_gyr(green, yellow, red)do { size_t azc_gyr_green = (green); size_t azc_gyr_yellow = ( yellow); size_t azc_gyr_red = (red); do { size_t azc_gy_green = (azc_gyr_green); size_t azc_gy_yellow = (azc_gyr_yellow); do { size_t azc_g_green = (azc_gy_green); do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 168, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0); do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 168, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0); do { if (!(azc_gy_green <= azc_gy_yellow )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 168, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0); } while (0); do { if (!(azc_gyr_red <= max_red_zone)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 168, "assert(" "azc_gyr_red <= max_red_zone" ") failed", "red exceeds max: " "%" "l" "u", azc_gyr_red); ::breakpoint( ); } } while (0); do { if (!(azc_gyr_yellow <= azc_gyr_red )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 168, "assert(" "azc_gyr_yellow <= azc_gyr_red" ") failed" , "yellow (" "%" "l" "u" ") exceeds red (" "%" "l" "u" ")", azc_gyr_yellow , azc_gyr_red); ::breakpoint(); } } while (0); } while (0) \ | |||
| 169 | do { \ | |||
| 170 | size_t azc_gyr_green = (green); \ | |||
| 171 | size_t azc_gyr_yellow = (yellow); \ | |||
| 172 | size_t azc_gyr_red = (red); \ | |||
| 173 | assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow)do { size_t azc_gy_green = (azc_gyr_green); size_t azc_gy_yellow = (azc_gyr_yellow); do { size_t azc_g_green = (azc_gy_green) ; do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 173, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0); do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 173, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0); do { if (!(azc_gy_green <= azc_gy_yellow )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 173, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0); } while (0); \ | |||
| 174 | assert(azc_gyr_red <= max_red_zone, \do { if (!(azc_gyr_red <= max_red_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 175, "assert(" "azc_gyr_red <= max_red_zone" ") failed", "red exceeds max: " "%" "l" "u", azc_gyr_red); ::breakpoint( ); } } while (0) | |||
| 175 | "red exceeds max: " SIZE_FORMAT, azc_gyr_red)do { if (!(azc_gyr_red <= max_red_zone)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 175, "assert(" "azc_gyr_red <= max_red_zone" ") failed", "red exceeds max: " "%" "l" "u", azc_gyr_red); ::breakpoint( ); } } while (0); \ | |||
| 176 | assert(azc_gyr_yellow <= azc_gyr_red, \do { if (!(azc_gyr_yellow <= azc_gyr_red)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 178, "assert(" "azc_gyr_yellow <= azc_gyr_red" ") failed" , "yellow (" "%" "l" "u" ") exceeds red (" "%" "l" "u" ")", azc_gyr_yellow , azc_gyr_red); ::breakpoint(); } } while (0) | |||
| 177 | "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")", \do { if (!(azc_gyr_yellow <= azc_gyr_red)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 178, "assert(" "azc_gyr_yellow <= azc_gyr_red" ") failed" , "yellow (" "%" "l" "u" ") exceeds red (" "%" "l" "u" ")", azc_gyr_yellow , azc_gyr_red); ::breakpoint(); } } while (0) | |||
| 178 | azc_gyr_yellow, azc_gyr_red)do { if (!(azc_gyr_yellow <= azc_gyr_red)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 178, "assert(" "azc_gyr_yellow <= azc_gyr_red" ") failed" , "yellow (" "%" "l" "u" ") exceeds red (" "%" "l" "u" ")", azc_gyr_yellow , azc_gyr_red); ::breakpoint(); } } while (0); \ | |||
| 179 | } while (0) | |||
| 180 | ||||
| 181 | // Logging tag sequence for refinement control updates. | |||
| 182 | #define CTRL_TAGSgc, ergo, refine gc, ergo, refine | |||
| 183 | ||||
| 184 | // For logging zone values, ensuring consistency of level and tags. | |||
| 185 | #define LOG_ZONES(...)(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>(...) log_debug( CTRL_TAGS )(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>(__VA_ARGS__) | |||
| 186 | ||||
| 187 | // Convert configuration values in units of buffers to number of cards. | |||
| 188 | static size_t configuration_buffers_to_cards(size_t value, const char* value_name) { | |||
| 189 | if (value == 0) return 0; | |||
| 190 | size_t res = value * G1UpdateBufferSize; | |||
| 191 | ||||
| 192 | if (res / value != G1UpdateBufferSize) { // Check overflow | |||
| 193 | vm_exit_during_initialization(err_msg("configuration_buffers_to_cards: " | |||
| 194 | "(%s = " SIZE_FORMAT"%" "l" "u" ") * (G1UpdateBufferSize = " SIZE_FORMAT"%" "l" "u" ") overflow!", value_name, value, G1UpdateBufferSize)); | |||
| 195 | } | |||
| 196 | return res; | |||
| 197 | } | |||
| 198 | ||||
| 199 | // Package for pair of refinement thread activation and deactivation | |||
| 200 | // thresholds. The activation and deactivation levels are resp. the first | |||
| 201 | // and second values of the pair. | |||
| 202 | typedef Pair<size_t, size_t> Thresholds; | |||
| 203 | inline size_t activation_level(const Thresholds& t) { return t.first; } | |||
| 204 | inline size_t deactivation_level(const Thresholds& t) { return t.second; } | |||
| 205 | ||||
| 206 | static Thresholds calc_thresholds(size_t green_zone, | |||
| 207 | size_t yellow_zone, | |||
| 208 | uint worker_id) { | |||
| 209 | double yellow_size = yellow_zone - green_zone; | |||
| 210 | double step = yellow_size / G1ConcurrentRefine::max_num_threads(); | |||
| 211 | if (worker_id == 0) { | |||
| 212 | // Potentially activate worker 0 more aggressively, to keep | |||
| 213 | // available buffers near green_zone value. When yellow_size is | |||
| 214 | // large we don't want to allow a full step to accumulate before | |||
| 215 | // doing any processing, as that might lead to significantly more | |||
| 216 | // than green_zone buffers to be processed during pause. So limit | |||
| 217 | // to an extra half buffer per pause-time processing thread. | |||
| 218 | step = MIN2(step, configuration_buffers_to_cards(ParallelGCThreads, "ParallelGCThreads") / 2.0); | |||
| 219 | } | |||
| 220 | size_t activate_offset = static_cast<size_t>(ceil(step * (worker_id + 1))); | |||
| 221 | size_t deactivate_offset = static_cast<size_t>(floor(step * worker_id)); | |||
| 222 | return Thresholds(green_zone + activate_offset, | |||
| 223 | green_zone + deactivate_offset); | |||
| 224 | } | |||
| 225 | ||||
| 226 | G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone, | |||
| 227 | size_t yellow_zone, | |||
| 228 | size_t red_zone, | |||
| 229 | size_t min_yellow_zone_size) : | |||
| 230 | _thread_control(), | |||
| 231 | _green_zone(green_zone), | |||
| 232 | _yellow_zone(yellow_zone), | |||
| 233 | _red_zone(red_zone), | |||
| 234 | _min_yellow_zone_size(min_yellow_zone_size) | |||
| 235 | { | |||
| 236 | assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone)do { size_t azc_gyr_green = (green_zone); size_t azc_gyr_yellow = (yellow_zone); size_t azc_gyr_red = (red_zone); do { size_t azc_gy_green = (azc_gyr_green); size_t azc_gy_yellow = (azc_gyr_yellow ); do { size_t azc_g_green = (azc_gy_green); do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 236, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0); do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 236, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0); do { if (!(azc_gy_green <= azc_gy_yellow )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 236, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0); } while (0); do { if (!(azc_gyr_red <= max_red_zone)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 236, "assert(" "azc_gyr_red <= max_red_zone" ") failed", "red exceeds max: " "%" "l" "u", azc_gyr_red); ::breakpoint( ); } } while (0); do { if (!(azc_gyr_yellow <= azc_gyr_red )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 236, "assert(" "azc_gyr_yellow <= azc_gyr_red" ") failed" , "yellow (" "%" "l" "u" ") exceeds red (" "%" "l" "u" ")", azc_gyr_yellow , azc_gyr_red); ::breakpoint(); } } while (0); } while (0); | |||
| 237 | } | |||
| 238 | ||||
| 239 | jint G1ConcurrentRefine::initialize() { | |||
| 240 | return _thread_control.initialize(this, max_num_threads()); | |||
| 241 | } | |||
| 242 | ||||
| 243 | static size_t calc_min_yellow_zone_size() { | |||
| 244 | size_t step = configuration_buffers_to_cards(G1ConcRefinementThresholdStep, "G1ConcRefinementThresholdStep"); | |||
| 245 | uint n_workers = G1ConcurrentRefine::max_num_threads(); | |||
| 246 | if ((max_yellow_zone / step) < n_workers) { | |||
| ||||
| 247 | return max_yellow_zone; | |||
| 248 | } else { | |||
| 249 | return step * n_workers; | |||
| 250 | } | |||
| 251 | } | |||
| 252 | ||||
| 253 | // An initial guess at the rate for pause-time card refinement for one | |||
| 254 | // thread, used when computing the default initial green zone value. | |||
| 255 | const double InitialPauseTimeCardRefinementRate = 200.0; | |||
| 256 | ||||
| 257 | static size_t calc_init_green_zone() { | |||
| 258 | size_t green; | |||
| 259 | if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)(JVMFlag::is_default(Flag_G1ConcRefinementGreenZone_enum))) { | |||
| 260 | const double rate = InitialPauseTimeCardRefinementRate * ParallelGCThreads; | |||
| 261 | // The time budget for pause-time card refinement. | |||
| 262 | const double ms = MaxGCPauseMillis * (G1RSetUpdatingPauseTimePercent / 100.0); | |||
| 263 | green = rate * ms; | |||
| 264 | } else { | |||
| 265 | green = configuration_buffers_to_cards(G1ConcRefinementGreenZone, | |||
| 266 | "G1ConcRefinementGreenZone"); | |||
| 267 | } | |||
| 268 | return MIN2(green, max_green_zone); | |||
| 269 | } | |||
| 270 | ||||
| 271 | static size_t calc_init_yellow_zone(size_t green, size_t min_size) { | |||
| 272 | size_t config = configuration_buffers_to_cards(G1ConcRefinementYellowZone, "G1ConcRefinementYellowZone"); | |||
| 273 | size_t size = 0; | |||
| 274 | if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)(JVMFlag::is_default(Flag_G1ConcRefinementYellowZone_enum))) { | |||
| 275 | size = green * 2; | |||
| 276 | } else if (green < config) { | |||
| 277 | size = config - green; | |||
| 278 | } | |||
| 279 | size = MAX2(size, min_size); | |||
| 280 | size = MIN2(size, max_yellow_zone); | |||
| 281 | return MIN2(green + size, max_yellow_zone); | |||
| 282 | } | |||
| 283 | ||||
| 284 | static size_t calc_init_red_zone(size_t green, size_t yellow) { | |||
| 285 | size_t size = yellow - green; | |||
| 286 | if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)(JVMFlag::is_default(Flag_G1ConcRefinementRedZone_enum))) { | |||
| 287 | size_t config = configuration_buffers_to_cards(G1ConcRefinementRedZone, "G1ConcRefinementRedZone"); | |||
| 288 | if (yellow < config) { | |||
| 289 | size = MAX2(size, config - yellow); | |||
| 290 | } | |||
| 291 | } | |||
| 292 | return MIN2(yellow + size, max_red_zone); | |||
| 293 | } | |||
| 294 | ||||
| 295 | G1ConcurrentRefine* G1ConcurrentRefine::create(jint* ecode) { | |||
| 296 | size_t min_yellow_zone_size = calc_min_yellow_zone_size(); | |||
| ||||
| 297 | size_t green_zone = calc_init_green_zone(); | |||
| 298 | size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size); | |||
| 299 | size_t red_zone = calc_init_red_zone(green_zone, yellow_zone); | |||
| 300 | ||||
| 301 | LOG_ZONES("Initial Refinement Zones: "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Initial Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u" ", " "min yellow size: " "%" "l" "u", green_zone, yellow_zone, red_zone, min_yellow_zone_size ) | |||
| 302 | "green: " SIZE_FORMAT ", "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Initial Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u" ", " "min yellow size: " "%" "l" "u", green_zone, yellow_zone, red_zone, min_yellow_zone_size ) | |||
| 303 | "yellow: " SIZE_FORMAT ", "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Initial Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u" ", " "min yellow size: " "%" "l" "u", green_zone, yellow_zone, red_zone, min_yellow_zone_size ) | |||
| 304 | "red: " SIZE_FORMAT ", "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Initial Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u" ", " "min yellow size: " "%" "l" "u", green_zone, yellow_zone, red_zone, min_yellow_zone_size ) | |||
| 305 | "min yellow size: " SIZE_FORMAT,(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Initial Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u" ", " "min yellow size: " "%" "l" "u", green_zone, yellow_zone, red_zone, min_yellow_zone_size ) | |||
| 306 | green_zone, yellow_zone, red_zone, min_yellow_zone_size)(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Initial Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u" ", " "min yellow size: " "%" "l" "u", green_zone, yellow_zone, red_zone, min_yellow_zone_size ); | |||
| 307 | ||||
| 308 | G1ConcurrentRefine* cr = new G1ConcurrentRefine(green_zone, | |||
| 309 | yellow_zone, | |||
| 310 | red_zone, | |||
| 311 | min_yellow_zone_size); | |||
| 312 | *ecode = cr->initialize(); | |||
| 313 | return cr; | |||
| 314 | } | |||
| 315 | ||||
| 316 | void G1ConcurrentRefine::stop() { | |||
| 317 | _thread_control.stop(); | |||
| 318 | } | |||
| 319 | ||||
| 320 | G1ConcurrentRefine::~G1ConcurrentRefine() { | |||
| 321 | } | |||
| 322 | ||||
| 323 | void G1ConcurrentRefine::threads_do(ThreadClosure *tc) { | |||
| 324 | _thread_control.worker_threads_do(tc); | |||
| 325 | } | |||
| 326 | ||||
| 327 | uint G1ConcurrentRefine::max_num_threads() { | |||
| 328 | return G1ConcRefinementThreads; | |||
| 329 | } | |||
| 330 | ||||
| 331 | static size_t calc_new_green_zone(size_t green, | |||
| 332 | double logged_cards_scan_time, | |||
| 333 | size_t processed_logged_cards, | |||
| 334 | double goal_ms) { | |||
| 335 | // Adjust green zone based on whether we're meeting the time goal. | |||
| 336 | // Limit to max_green_zone. | |||
| 337 | const double inc_k = 1.1, dec_k = 0.9; | |||
| 338 | if (logged_cards_scan_time > goal_ms) { | |||
| 339 | if (green > 0) { | |||
| 340 | green = static_cast<size_t>(green * dec_k); | |||
| 341 | } | |||
| 342 | } else if (logged_cards_scan_time < goal_ms && | |||
| 343 | processed_logged_cards > green) { | |||
| 344 | green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0)); | |||
| 345 | green = MIN2(green, max_green_zone); | |||
| 346 | } | |||
| 347 | return green; | |||
| 348 | } | |||
| 349 | ||||
| 350 | static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) { | |||
| 351 | size_t size = green * 2; | |||
| 352 | size = MAX2(size, min_yellow_size); | |||
| 353 | return MIN2(green + size, max_yellow_zone); | |||
| 354 | } | |||
| 355 | ||||
| 356 | static size_t calc_new_red_zone(size_t green, size_t yellow) { | |||
| 357 | return MIN2(yellow + (yellow - green), max_red_zone); | |||
| 358 | } | |||
| 359 | ||||
| 360 | void G1ConcurrentRefine::update_zones(double logged_cards_scan_time, | |||
| 361 | size_t processed_logged_cards, | |||
| 362 | double goal_ms) { | |||
| 363 | log_trace( CTRL_TAGS )(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Trace))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Trace>("Updating Refinement Zones: " | |||
| 364 | "logged cards scan time: %.3fms, " | |||
| 365 | "processed cards: " SIZE_FORMAT"%" "l" "u" ", " | |||
| 366 | "goal time: %.3fms", | |||
| 367 | logged_cards_scan_time, | |||
| 368 | processed_logged_cards, | |||
| 369 | goal_ms); | |||
| 370 | ||||
| 371 | _green_zone = calc_new_green_zone(_green_zone, | |||
| 372 | logged_cards_scan_time, | |||
| 373 | processed_logged_cards, | |||
| 374 | goal_ms); | |||
| 375 | _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size); | |||
| 376 | _red_zone = calc_new_red_zone(_green_zone, _yellow_zone); | |||
| 377 | ||||
| 378 | assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone)do { size_t azc_gyr_green = (_green_zone); size_t azc_gyr_yellow = (_yellow_zone); size_t azc_gyr_red = (_red_zone); do { size_t azc_gy_green = (azc_gyr_green); size_t azc_gy_yellow = (azc_gyr_yellow ); do { size_t azc_g_green = (azc_gy_green); do { if (!(azc_g_green <= max_green_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 378, "assert(" "azc_g_green <= max_green_zone" ") failed" , "green exceeds max: " "%" "l" "u", azc_g_green); ::breakpoint (); } } while (0); } while (0); do { if (!(azc_gy_yellow <= max_yellow_zone)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 378, "assert(" "azc_gy_yellow <= max_yellow_zone" ") failed" , "yellow exceeds max: " "%" "l" "u", azc_gy_yellow); ::breakpoint (); } } while (0); do { if (!(azc_gy_green <= azc_gy_yellow )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 378, "assert(" "azc_gy_green <= azc_gy_yellow" ") failed" , "green (" "%" "l" "u" ") exceeds yellow (" "%" "l" "u" ")", azc_gy_green, azc_gy_yellow); ::breakpoint(); } } while (0); } while (0); do { if (!(azc_gyr_red <= max_red_zone)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 378, "assert(" "azc_gyr_red <= max_red_zone" ") failed", "red exceeds max: " "%" "l" "u", azc_gyr_red); ::breakpoint( ); } } while (0); do { if (!(azc_gyr_yellow <= azc_gyr_red )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp" , 378, "assert(" "azc_gyr_yellow <= azc_gyr_red" ") failed" , "yellow (" "%" "l" "u" ") exceeds red (" "%" "l" "u" ")", azc_gyr_yellow , azc_gyr_red); ::breakpoint(); } } while (0); } while (0); | |||
| 379 | LOG_ZONES("Updated Refinement Zones: "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Updated Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u", _green_zone , _yellow_zone, _red_zone) | |||
| 380 | "green: " SIZE_FORMAT ", "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Updated Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u", _green_zone , _yellow_zone, _red_zone) | |||
| 381 | "yellow: " SIZE_FORMAT ", "(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Updated Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u", _green_zone , _yellow_zone, _red_zone) | |||
| 382 | "red: " SIZE_FORMAT,(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Updated Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u", _green_zone , _yellow_zone, _red_zone) | |||
| 383 | _green_zone, _yellow_zone, _red_zone)(!(LogImpl<(LogTag::_gc), (LogTag::_ergo), (LogTag::_refine ), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG) >::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag ::_gc), (LogTag::_ergo), (LogTag::_refine), (LogTag::__NO_TAG ), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel ::Debug>("Updated Refinement Zones: " "green: " "%" "l" "u" ", " "yellow: " "%" "l" "u" ", " "red: " "%" "l" "u", _green_zone , _yellow_zone, _red_zone); | |||
| 384 | } | |||
| 385 | ||||
| 386 | void G1ConcurrentRefine::adjust(double logged_cards_scan_time, | |||
| 387 | size_t processed_logged_cards, | |||
| 388 | double goal_ms) { | |||
| 389 | G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); | |||
| 390 | ||||
| 391 | if (G1UseAdaptiveConcRefinement) { | |||
| 392 | update_zones(logged_cards_scan_time, processed_logged_cards, goal_ms); | |||
| 393 | ||||
| 394 | // Change the barrier params | |||
| 395 | if (max_num_threads() == 0) { | |||
| 396 | // Disable dcqs notification when there are no threads to notify. | |||
| 397 | dcqs.set_process_cards_threshold(G1DirtyCardQueueSet::ProcessCardsThresholdNever); | |||
| 398 | } else { | |||
| 399 | // Worker 0 is the primary; wakeup is via dcqs notification. | |||
| 400 | STATIC_ASSERT(max_yellow_zone <= INT_MAX)static_assert((max_yellow_zone <= 2147483647), "max_yellow_zone <= INT_MAX" ); | |||
| 401 | size_t activate = activation_threshold(0); | |||
| 402 | dcqs.set_process_cards_threshold(activate); | |||
| 403 | } | |||
| 404 | dcqs.set_max_cards(red_zone()); | |||
| 405 | } | |||
| 406 | ||||
| 407 | size_t curr_queue_size = dcqs.num_cards(); | |||
| 408 | if ((dcqs.max_cards() > 0) && | |||
| 409 | (curr_queue_size >= yellow_zone())) { | |||
| 410 | dcqs.set_max_cards_padding(curr_queue_size); | |||
| 411 | } else { | |||
| 412 | dcqs.set_max_cards_padding(0); | |||
| 413 | } | |||
| 414 | dcqs.notify_if_necessary(); | |||
| 415 | } | |||
| 416 | ||||
| 417 | G1ConcurrentRefineStats G1ConcurrentRefine::get_and_reset_refinement_stats() { | |||
| 418 | struct CollectStats : public ThreadClosure { | |||
| 419 | G1ConcurrentRefineStats _total_stats; | |||
| 420 | virtual void do_thread(Thread* t) { | |||
| 421 | G1ConcurrentRefineThread* crt = static_cast<G1ConcurrentRefineThread*>(t); | |||
| 422 | G1ConcurrentRefineStats& stats = *crt->refinement_stats(); | |||
| 423 | _total_stats += stats; | |||
| 424 | stats.reset(); | |||
| 425 | } | |||
| 426 | } collector; | |||
| 427 | threads_do(&collector); | |||
| 428 | return collector._total_stats; | |||
| 429 | } | |||
| 430 | ||||
| 431 | size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const { | |||
| 432 | Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id); | |||
| 433 | return activation_level(thresholds); | |||
| 434 | } | |||
| 435 | ||||
| 436 | size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const { | |||
| 437 | Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id); | |||
| 438 | return deactivation_level(thresholds); | |||
| 439 | } | |||
| 440 | ||||
| 441 | uint G1ConcurrentRefine::worker_id_offset() { | |||
| 442 | return G1DirtyCardQueueSet::num_par_ids(); | |||
| 443 | } | |||
| 444 | ||||
| 445 | void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_cur_cards) { | |||
| 446 | if (num_cur_cards > activation_threshold(worker_id + 1)) { | |||
| 447 | _thread_control.maybe_activate_next(worker_id); | |||
| 448 | } | |||
| 449 | } | |||
| 450 | ||||
| 451 | bool G1ConcurrentRefine::do_refinement_step(uint worker_id, | |||
| 452 | G1ConcurrentRefineStats* stats) { | |||
| 453 | G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); | |||
| 454 | ||||
| 455 | size_t curr_cards = dcqs.num_cards(); | |||
| 456 | // If the number of the cards falls down into the yellow zone, | |||
| 457 | // that means that the transition period after the evacuation pause has ended. | |||
| 458 | if (curr_cards <= yellow_zone()) { | |||
| 459 | dcqs.discard_max_cards_padding(); | |||
| 460 | } | |||
| 461 | ||||
| 462 | maybe_activate_more_threads(worker_id, curr_cards); | |||
| 463 | ||||
| 464 | // Process the next buffer, if there are enough left. | |||
| 465 | return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(), | |||
| 466 | deactivation_threshold(worker_id), | |||
| 467 | stats); | |||
| 468 | } |