Bug Summary

File:jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
Warning:line 246, column 24
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name g1ConcurrentRefine.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
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
42G1ConcurrentRefineThread* 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
55G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
56 _cr(NULL__null),
57 _threads(NULL__null),
58 _num_max_threads(0)
59{
60}
61
62G1ConcurrentRefineThreadControl::~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
72jint 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
98void 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
119void 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
127void 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.
140STATIC_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)"
)
;
141const size_t max_yellow_zone = LP64_ONLY(max_jint)max_jint NOT_LP64(max_jshort);
142const size_t max_green_zone = max_yellow_zone / 2;
143const size_t max_red_zone = INT_MAX2147483647; // For dcqs.set_max_cards.
144STATIC_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.
188static size_t configuration_buffers_to_cards(size_t value, const char* value_name) {
189 if (value == 0) return 0;
3
Assuming 'value' is equal to 0
4
Taking true branch
5
Returning zero
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.
202typedef Pair<size_t, size_t> Thresholds;
203inline size_t activation_level(const Thresholds& t) { return t.first; }
204inline size_t deactivation_level(const Thresholds& t) { return t.second; }
205
206static 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
226G1ConcurrentRefine::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
239jint G1ConcurrentRefine::initialize() {
240 return _thread_control.initialize(this, max_num_threads());
241}
242
243static size_t calc_min_yellow_zone_size() {
244 size_t step = configuration_buffers_to_cards(G1ConcRefinementThresholdStep, "G1ConcRefinementThresholdStep");
2
Calling 'configuration_buffers_to_cards'
6
Returning from 'configuration_buffers_to_cards'
7
'step' initialized to 0
245 uint n_workers = G1ConcurrentRefine::max_num_threads();
246 if ((max_yellow_zone / step) < n_workers) {
8
Division by zero
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.
255const double InitialPauseTimeCardRefinementRate = 200.0;
256
257static 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
271static 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
284static 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
295G1ConcurrentRefine* G1ConcurrentRefine::create(jint* ecode) {
296 size_t min_yellow_zone_size = calc_min_yellow_zone_size();
1
Calling '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
316void G1ConcurrentRefine::stop() {
317 _thread_control.stop();
318}
319
320G1ConcurrentRefine::~G1ConcurrentRefine() {
321}
322
323void G1ConcurrentRefine::threads_do(ThreadClosure *tc) {
324 _thread_control.worker_threads_do(tc);
325}
326
327uint G1ConcurrentRefine::max_num_threads() {
328 return G1ConcRefinementThreads;
329}
330
331static 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
350static 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
356static size_t calc_new_red_zone(size_t green, size_t yellow) {
357 return MIN2(yellow + (yellow - green), max_red_zone);
358}
359
360void 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
386void 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
417G1ConcurrentRefineStats 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
431size_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
436size_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
441uint G1ConcurrentRefine::worker_id_offset() {
442 return G1DirtyCardQueueSet::num_par_ids();
443}
444
445void 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
451bool 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}