Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | c84ee870e0b9 |
children | d2a62e0f25eb 922993931b3d |
rev | line source |
---|---|
342 | 1 /* |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
1972
diff
changeset
|
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
342 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1282
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1282
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1282
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/g1/concurrentG1Refine.hpp" | |
27 #include "gc_implementation/g1/concurrentG1RefineThread.hpp" | |
28 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | |
29 #include "gc_implementation/g1/g1CollectorPolicy.hpp" | |
30 #include "gc_implementation/g1/g1RemSet.hpp" | |
31 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
32 #include "memory/space.inline.hpp" | |
33 #include "runtime/atomic.hpp" | |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
34 #include "runtime/java.hpp" |
1972 | 35 #include "utilities/copy.hpp" |
342 | 36 |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
37 // Possible sizes for the card counts cache: odd primes that roughly double in size. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
38 // (See jvmtiTagMap.cpp). |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
39 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
40 #define MAX_SIZE ((size_t) -1) |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
41 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
42 size_t ConcurrentG1Refine::_cc_cache_sizes[] = { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
43 16381, 32771, 76831, 150001, 307261, |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
44 614563, 1228891, 2457733, 4915219, 9830479, |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
45 19660831, 39321619, 78643219, 157286461, MAX_SIZE |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
46 }; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
47 |
342 | 48 ConcurrentG1Refine::ConcurrentG1Refine() : |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
49 _card_counts(NULL), _card_epochs(NULL), |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
50 _n_card_counts(0), _max_cards(0), _max_n_card_counts(0), |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
51 _cache_size_index(0), _expand_card_counts(false), |
342 | 52 _hot_cache(NULL), |
53 _def_use_cache(false), _use_cache(false), | |
2434
c84ee870e0b9
7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents:
2431
diff
changeset
|
54 // We initialize the epochs of the array to 0. By initializing |
c84ee870e0b9
7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents:
2431
diff
changeset
|
55 // _n_periods to 1 and not 0 we automatically invalidate all the |
c84ee870e0b9
7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents:
2431
diff
changeset
|
56 // entries on the array. Otherwise we might accidentally think that |
c84ee870e0b9
7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents:
2431
diff
changeset
|
57 // we claimed a card that was in fact never set (see CR7033292). |
c84ee870e0b9
7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents:
2431
diff
changeset
|
58 _n_periods(1), |
794 | 59 _threads(NULL), _n_threads(0) |
342 | 60 { |
1111 | 61 |
62 // Ergomonically select initial concurrent refinement parameters | |
1282 | 63 if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) { |
64 FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, MAX2<int>(ParallelGCThreads, 1)); | |
1111 | 65 } |
1282 | 66 set_green_zone(G1ConcRefinementGreenZone); |
1111 | 67 |
1282 | 68 if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) { |
69 FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3); | |
1111 | 70 } |
1282 | 71 set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone())); |
1111 | 72 |
1282 | 73 if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) { |
74 FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2); | |
1111 | 75 } |
1282 | 76 set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone())); |
1111 | 77 _n_worker_threads = thread_num(); |
78 // We need one extra thread to do the young gen rset size sampling. | |
79 _n_threads = _n_worker_threads + 1; | |
80 reset_threshold_step(); | |
81 | |
82 _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads); | |
83 int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids(); | |
84 ConcurrentG1RefineThread *next = NULL; | |
85 for (int i = _n_threads - 1; i >= 0; i--) { | |
86 ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i); | |
87 assert(t != NULL, "Conc refine should have been created"); | |
88 assert(t->cg1r() == this, "Conc refine thread should refer to this"); | |
89 _threads[i] = t; | |
90 next = t; | |
342 | 91 } |
92 } | |
93 | |
1111 | 94 void ConcurrentG1Refine::reset_threshold_step() { |
1282 | 95 if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) { |
1111 | 96 _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1); |
97 } else { | |
1282 | 98 _thread_threshold_step = G1ConcRefinementThresholdStep; |
795
215f81b4d9b3
6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents:
794
diff
changeset
|
99 } |
1111 | 100 } |
101 | |
102 int ConcurrentG1Refine::thread_num() { | |
1282 | 103 return MAX2<int>((G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads : ParallelGCThreads, 1); |
795
215f81b4d9b3
6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents:
794
diff
changeset
|
104 } |
215f81b4d9b3
6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents:
794
diff
changeset
|
105 |
342 | 106 void ConcurrentG1Refine::init() { |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
107 if (G1ConcRSLogCacheSize > 0) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
108 _g1h = G1CollectedHeap::heap(); |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
109 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
110 _max_cards = _g1h->max_capacity() >> CardTableModRefBS::card_shift; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
111 _max_n_card_counts = _max_cards * G1MaxHotCardCountSizePercent / 100; |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
112 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
113 size_t max_card_num = ((size_t)1 << (sizeof(unsigned)*BitsPerByte-1)) - 1; |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
114 guarantee(_max_cards < max_card_num, "card_num representation"); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
115 |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
116 // We need _n_card_counts to be less than _max_n_card_counts here |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
117 // so that the expansion call (below) actually allocates the |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
118 // _counts and _epochs arrays. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
119 assert(_n_card_counts == 0, "pre-condition"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
120 assert(_max_n_card_counts > 0, "pre-condition"); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
121 |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
122 // Find the index into cache size array that is of a size that's |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
123 // large enough to hold desired_sz. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
124 size_t desired_sz = _max_cards / InitialCacheFraction; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
125 int desired_sz_index = 0; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
126 while (_cc_cache_sizes[desired_sz_index] < desired_sz) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
127 desired_sz_index += 1; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
128 assert(desired_sz_index < MAX_CC_CACHE_INDEX, "invariant"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
129 } |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
130 assert(desired_sz_index < MAX_CC_CACHE_INDEX, "invariant"); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
131 |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
132 // If the desired_sz value is between two sizes then |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
133 // _cc_cache_sizes[desired_sz_index-1] < desired_sz <= _cc_cache_sizes[desired_sz_index] |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
134 // we will start with the lower size in the optimistic expectation that |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
135 // we will not need to expand up. Note desired_sz_index could also be 0. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
136 if (desired_sz_index > 0 && |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
137 _cc_cache_sizes[desired_sz_index] > desired_sz) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
138 desired_sz_index -= 1; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
139 } |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
140 |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
141 if (!expand_card_count_cache(desired_sz_index)) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
142 // Allocation was unsuccessful - exit |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
143 vm_exit_during_initialization("Could not reserve enough space for card count cache"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
144 } |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
145 assert(_n_card_counts > 0, "post-condition"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
146 assert(_cache_size_index == desired_sz_index, "post-condition"); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
147 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
148 Copy::fill_to_bytes(&_card_counts[0], |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
149 _n_card_counts * sizeof(CardCountCacheEntry)); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
150 Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry)); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
151 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
152 ModRefBarrierSet* bs = _g1h->mr_bs(); |
342 | 153 guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
154 _ct_bs = (CardTableModRefBS*)bs; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
155 _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start()); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
156 |
342 | 157 _def_use_cache = true; |
158 _use_cache = true; | |
159 _hot_cache_size = (1 << G1ConcRSLogCacheSize); | |
160 _hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size); | |
161 _n_hot = 0; | |
162 _hot_cache_idx = 0; | |
889 | 163 |
164 // For refining the cards in the hot cache in parallel | |
165 int n_workers = (ParallelGCThreads > 0 ? | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
166 _g1h->workers()->total_workers() : 1); |
889 | 167 _hot_cache_par_chunk_size = MAX2(1, _hot_cache_size / n_workers); |
168 _hot_cache_par_claimed_idx = 0; | |
342 | 169 } |
170 } | |
171 | |
794 | 172 void ConcurrentG1Refine::stop() { |
173 if (_threads != NULL) { | |
174 for (int i = 0; i < _n_threads; i++) { | |
175 _threads[i]->stop(); | |
176 } | |
177 } | |
178 } | |
179 | |
1111 | 180 void ConcurrentG1Refine::reinitialize_threads() { |
181 reset_threshold_step(); | |
182 if (_threads != NULL) { | |
183 for (int i = 0; i < _n_threads; i++) { | |
184 _threads[i]->initialize(); | |
185 } | |
186 } | |
187 } | |
188 | |
342 | 189 ConcurrentG1Refine::~ConcurrentG1Refine() { |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
190 if (G1ConcRSLogCacheSize > 0) { |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
191 // Please see the comment in allocate_card_count_cache |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
192 // for why we call os::malloc() and os::free() directly. |
342 | 193 assert(_card_counts != NULL, "Logic"); |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
194 os::free(_card_counts); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
195 assert(_card_epochs != NULL, "Logic"); |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
196 os::free(_card_epochs); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
197 |
342 | 198 assert(_hot_cache != NULL, "Logic"); |
199 FREE_C_HEAP_ARRAY(jbyte*, _hot_cache); | |
200 } | |
794 | 201 if (_threads != NULL) { |
202 for (int i = 0; i < _n_threads; i++) { | |
203 delete _threads[i]; | |
204 } | |
799
f89cf529c3c7
6849122: G1: Typo introduced during implementation of the parallel refinement
iveresov
parents:
795
diff
changeset
|
205 FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads); |
342 | 206 } |
207 } | |
208 | |
794 | 209 void ConcurrentG1Refine::threads_do(ThreadClosure *tc) { |
210 if (_threads != NULL) { | |
211 for (int i = 0; i < _n_threads; i++) { | |
212 tc->do_thread(_threads[i]); | |
213 } | |
342 | 214 } |
215 } | |
216 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
217 bool ConcurrentG1Refine::is_young_card(jbyte* card_ptr) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
218 HeapWord* start = _ct_bs->addr_for(card_ptr); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
219 HeapRegion* r = _g1h->heap_region_containing(start); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
220 if (r != NULL && r->is_young()) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
221 return true; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
222 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
223 // This card is not associated with a heap region |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
224 // so can't be young. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
225 return false; |
342 | 226 } |
227 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
228 jbyte* ConcurrentG1Refine::add_card_count(jbyte* card_ptr, int* count, bool* defer) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
229 unsigned new_card_num = ptr_2_card_num(card_ptr); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
230 unsigned bucket = hash(new_card_num); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
231 assert(0 <= bucket && bucket < _n_card_counts, "Bounds"); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
232 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
233 CardCountCacheEntry* count_ptr = &_card_counts[bucket]; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
234 CardEpochCacheEntry* epoch_ptr = &_card_epochs[bucket]; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
235 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
236 // We have to construct a new entry if we haven't updated the counts |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
237 // during the current period, or if the count was updated for a |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
238 // different card number. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
239 unsigned int new_epoch = (unsigned int) _n_periods; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
240 julong new_epoch_entry = make_epoch_entry(new_card_num, new_epoch); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
241 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
242 while (true) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
243 // Fetch the previous epoch value |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
244 julong prev_epoch_entry = epoch_ptr->_value; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
245 julong cas_res; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
246 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
247 if (extract_epoch(prev_epoch_entry) != new_epoch) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
248 // This entry has not yet been updated during this period. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
249 // Note: we update the epoch value atomically to ensure |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
250 // that there is only one winner that updates the cached |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
251 // card_ptr value even though all the refine threads share |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
252 // the same epoch value. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
253 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
254 cas_res = (julong) Atomic::cmpxchg((jlong) new_epoch_entry, |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
255 (volatile jlong*)&epoch_ptr->_value, |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
256 (jlong) prev_epoch_entry); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
257 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
258 if (cas_res == prev_epoch_entry) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
259 // We have successfully won the race to update the |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
260 // epoch and card_num value. Make it look like the |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
261 // count and eviction count were previously cleared. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
262 count_ptr->_count = 1; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
263 count_ptr->_evict_count = 0; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
264 *count = 0; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
265 // We can defer the processing of card_ptr |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
266 *defer = true; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
267 return card_ptr; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
268 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
269 // We did not win the race to update the epoch field, so some other |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
270 // thread must have done it. The value that gets returned by CAS |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
271 // should be the new epoch value. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
272 assert(extract_epoch(cas_res) == new_epoch, "unexpected epoch"); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
273 // We could 'continue' here or just re-read the previous epoch value |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
274 prev_epoch_entry = epoch_ptr->_value; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
275 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
276 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
277 // The epoch entry for card_ptr has been updated during this period. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
278 unsigned old_card_num = extract_card_num(prev_epoch_entry); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
279 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
280 // The card count that will be returned to caller |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
281 *count = count_ptr->_count; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
282 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
283 // Are we updating the count for the same card? |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
284 if (new_card_num == old_card_num) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
285 // Same card - just update the count. We could have more than one |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
286 // thread racing to update count for the current card. It should be |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
287 // OK not to use a CAS as the only penalty should be some missed |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
288 // increments of the count which delays identifying the card as "hot". |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
289 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
290 if (*count < max_jubyte) count_ptr->_count++; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
291 // We can defer the processing of card_ptr |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
292 *defer = true; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
293 return card_ptr; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
294 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
295 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
296 // Different card - evict old card info |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
297 if (count_ptr->_evict_count < max_jubyte) count_ptr->_evict_count++; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
298 if (count_ptr->_evict_count > G1CardCountCacheExpandThreshold) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
299 // Trigger a resize the next time we clear |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
300 _expand_card_counts = true; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
301 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
302 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
303 cas_res = (julong) Atomic::cmpxchg((jlong) new_epoch_entry, |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
304 (volatile jlong*)&epoch_ptr->_value, |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
305 (jlong) prev_epoch_entry); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
306 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
307 if (cas_res == prev_epoch_entry) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
308 // We successfully updated the card num value in the epoch entry |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
309 count_ptr->_count = 0; // initialize counter for new card num |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
310 jbyte* old_card_ptr = card_num_2_ptr(old_card_num); |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
311 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
312 // Even though the region containg the card at old_card_num was not |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
313 // in the young list when old_card_num was recorded in the epoch |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
314 // cache it could have been added to the free list and subsequently |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
315 // added to the young list in the intervening time. See CR 6817995. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
316 // We do not deal with this case here - it will be handled in |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
317 // HeapRegion::oops_on_card_seq_iterate_careful after it has been |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
318 // determined that the region containing the card has been allocated |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
319 // to, and it's safe to check the young type of the region. |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
320 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
321 // We do not want to defer processing of card_ptr in this case |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
322 // (we need to refine old_card_ptr and card_ptr) |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
323 *defer = false; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
324 return old_card_ptr; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
325 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
326 // Someone else beat us - try again. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
327 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
328 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
329 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
330 jbyte* ConcurrentG1Refine::cache_insert(jbyte* card_ptr, bool* defer) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
331 int count; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
332 jbyte* cached_ptr = add_card_count(card_ptr, &count, defer); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
333 assert(cached_ptr != NULL, "bad cached card ptr"); |
1246
deada8912c54
6914402: G1: assert(!is_young_card(cached_ptr),"shouldn't get a card in young region")
johnc
parents:
1111
diff
changeset
|
334 |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
335 // We've just inserted a card pointer into the card count cache |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
336 // and got back the card that we just inserted or (evicted) the |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
337 // previous contents of that count slot. |
1246
deada8912c54
6914402: G1: assert(!is_young_card(cached_ptr),"shouldn't get a card in young region")
johnc
parents:
1111
diff
changeset
|
338 |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
339 // The card we got back could be in a young region. When the |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
340 // returned card (if evicted) was originally inserted, we had |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
341 // determined that its containing region was not young. However |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
342 // it is possible for the region to be freed during a cleanup |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
343 // pause, then reallocated and tagged as young which will result |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
344 // in the returned card residing in a young region. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
345 // |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
346 // We do not deal with this case here - the change from non-young |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
347 // to young could be observed at any time - it will be handled in |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
348 // HeapRegion::oops_on_card_seq_iterate_careful after it has been |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
349 // determined that the region containing the card has been allocated |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
350 // to. |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
351 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
352 // The card pointer we obtained from card count cache is not hot |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
353 // so do not store it in the cache; return it for immediate |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
354 // refining. |
342 | 355 if (count < G1ConcRSHotCardLimit) { |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
356 return cached_ptr; |
342 | 357 } |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
358 |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
359 // Otherwise, the pointer we got from the _card_counts cache is hot. |
342 | 360 jbyte* res = NULL; |
361 MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag); | |
362 if (_n_hot == _hot_cache_size) { | |
363 res = _hot_cache[_hot_cache_idx]; | |
364 _n_hot--; | |
365 } | |
366 // Now _n_hot < _hot_cache_size, and we can insert at _hot_cache_idx. | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
367 _hot_cache[_hot_cache_idx] = cached_ptr; |
342 | 368 _hot_cache_idx++; |
369 if (_hot_cache_idx == _hot_cache_size) _hot_cache_idx = 0; | |
370 _n_hot++; | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
371 |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
372 // The card obtained from the hot card cache could be in a young |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
373 // region. See above on how this can happen. |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
374 |
342 | 375 return res; |
376 } | |
377 | |
1705 | 378 void ConcurrentG1Refine::clean_up_cache(int worker_i, |
379 G1RemSet* g1rs, | |
380 DirtyCardQueue* into_cset_dcq) { | |
342 | 381 assert(!use_cache(), "cache should be disabled"); |
889 | 382 int start_idx; |
383 | |
384 while ((start_idx = _hot_cache_par_claimed_idx) < _n_hot) { // read once | |
385 int end_idx = start_idx + _hot_cache_par_chunk_size; | |
386 | |
387 if (start_idx == | |
388 Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) { | |
389 // The current worker has successfully claimed the chunk [start_idx..end_idx) | |
390 end_idx = MIN2(end_idx, _n_hot); | |
391 for (int i = start_idx; i < end_idx; i++) { | |
392 jbyte* entry = _hot_cache[i]; | |
393 if (entry != NULL) { | |
1705 | 394 if (g1rs->concurrentRefineOneCard(entry, worker_i, true)) { |
395 // 'entry' contains references that point into the current | |
396 // collection set. We need to record 'entry' in the DCQS | |
397 // that's used for that purpose. | |
398 // | |
399 // The only time we care about recording cards that contain | |
400 // references that point into the collection set is during | |
401 // RSet updating while within an evacuation pause. | |
402 // In this case worker_i should be the id of a GC worker thread | |
403 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause"); | |
2364
04d1138b4cce
7023747: G1: too strict assert in RefineRecordRefsIntoCSCardTableEntryClosure::do_card_ptr in g1RemSet.cpp
brutisso
parents:
2188
diff
changeset
|
404 assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "incorrect worker id"); |
1705 | 405 into_cset_dcq->enqueue(entry); |
406 } | |
889 | 407 } |
408 } | |
342 | 409 } |
410 } | |
411 } | |
412 | |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
413 // The arrays used to hold the card counts and the epochs must have |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
414 // a 1:1 correspondence. Hence they are allocated and freed together |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
415 // Returns true if the allocations of both the counts and epochs |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
416 // were successful; false otherwise. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
417 bool ConcurrentG1Refine::allocate_card_count_cache(size_t n, |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
418 CardCountCacheEntry** counts, |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
419 CardEpochCacheEntry** epochs) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
420 // We call the allocation/free routines directly for the counts |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
421 // and epochs arrays. The NEW_C_HEAP_ARRAY/FREE_C_HEAP_ARRAY |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
422 // macros call AllocateHeap and FreeHeap respectively. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
423 // AllocateHeap will call vm_exit_out_of_memory in the event |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
424 // of an allocation failure and abort the JVM. With the |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
425 // _counts/epochs arrays we only need to abort the JVM if the |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
426 // initial allocation of these arrays fails. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
427 // |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
428 // Additionally AllocateHeap/FreeHeap do some tracing of |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
429 // allocate/free calls so calling one without calling the |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
430 // other can cause inconsistencies in the tracing. So we |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
431 // call neither. |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
432 |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
433 assert(*counts == NULL, "out param"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
434 assert(*epochs == NULL, "out param"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
435 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
436 size_t counts_size = n * sizeof(CardCountCacheEntry); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
437 size_t epochs_size = n * sizeof(CardEpochCacheEntry); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
438 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
439 *counts = (CardCountCacheEntry*) os::malloc(counts_size); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
440 if (*counts == NULL) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
441 // allocation was unsuccessful |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
442 return false; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
443 } |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
444 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
445 *epochs = (CardEpochCacheEntry*) os::malloc(epochs_size); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
446 if (*epochs == NULL) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
447 // allocation was unsuccessful - free counts array |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
448 assert(*counts != NULL, "must be"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
449 os::free(*counts); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
450 *counts = NULL; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
451 return false; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
452 } |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
453 |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
454 // We successfully allocated both counts and epochs |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
455 return true; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
456 } |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
457 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
458 // Returns true if the card counts/epochs cache was |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
459 // successfully expanded; false otherwise. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
460 bool ConcurrentG1Refine::expand_card_count_cache(int cache_size_idx) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
461 // Can we expand the card count and epoch tables? |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
462 if (_n_card_counts < _max_n_card_counts) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
463 assert(cache_size_idx >= 0 && cache_size_idx < MAX_CC_CACHE_INDEX, "oob"); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
464 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
465 size_t cache_size = _cc_cache_sizes[cache_size_idx]; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
466 // Make sure we don't go bigger than we will ever need |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
467 cache_size = MIN2(cache_size, _max_n_card_counts); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
468 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
469 // Should we expand the card count and card epoch tables? |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
470 if (cache_size > _n_card_counts) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
471 // We have been asked to allocate new, larger, arrays for |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
472 // the card counts and the epochs. Attempt the allocation |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
473 // of both before we free the existing arrays in case |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
474 // the allocation is unsuccessful... |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
475 CardCountCacheEntry* counts = NULL; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
476 CardEpochCacheEntry* epochs = NULL; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
477 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
478 if (allocate_card_count_cache(cache_size, &counts, &epochs)) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
479 // Allocation was successful. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
480 // We can just free the old arrays; we're |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
481 // not interested in preserving the contents |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
482 if (_card_counts != NULL) os::free(_card_counts); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
483 if (_card_epochs != NULL) os::free(_card_epochs); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
484 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
485 // Cache the size of the arrays and the index that got us there. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
486 _n_card_counts = cache_size; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
487 _cache_size_index = cache_size_idx; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
488 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
489 _card_counts = counts; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
490 _card_epochs = epochs; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
491 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
492 // We successfully allocated/expanded the caches. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
493 return true; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
494 } |
342 | 495 } |
496 } | |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
497 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
498 // We did not successfully expand the caches. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
499 return false; |
342 | 500 } |
501 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
502 void ConcurrentG1Refine::clear_and_record_card_counts() { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
503 if (G1ConcRSLogCacheSize == 0) return; |
342 | 504 |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
505 #ifndef PRODUCT |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
506 double start = os::elapsedTime(); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
507 #endif |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
508 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
509 if (_expand_card_counts) { |
2431
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
510 int new_idx = _cache_size_index + 1; |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
511 |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
512 if (expand_card_count_cache(new_idx)) { |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
513 // Allocation was successful and _n_card_counts has |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
514 // been updated to the new size. We only need to clear |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
515 // the epochs so we don't read a bogus epoch value |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
516 // when inserting a card into the hot card cache. |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
517 Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry)); |
02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents:
2364
diff
changeset
|
518 } |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
519 _expand_card_counts = false; |
342 | 520 } |
521 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
522 int this_epoch = (int) _n_periods; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
523 assert((this_epoch+1) <= max_jint, "to many periods"); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
524 // Update epoch |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
525 _n_periods++; |
342 | 526 |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
527 #ifndef PRODUCT |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
528 double elapsed = os::elapsedTime() - start; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
529 _g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
889
diff
changeset
|
530 #endif |
342 | 531 } |
1019 | 532 |
533 void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const { | |
534 for (int i = 0; i < _n_threads; ++i) { | |
535 _threads[i]->print_on(st); | |
536 st->cr(); | |
537 } | |
538 } |