annotate src/share/vm/memory/cardTableRS.cpp @ 20543:e7d0505c8a30

8059758: Footprint regressions with JDK-8038423 Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything. Reviewed-by: jwilhelm, brutisso
author tschatzl
date Fri, 10 Oct 2014 15:51:58 +0200
parents 833b0f92429a
children 7848fc12602b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
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: 844
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "memory/cardTableRS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "memory/genCollectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "memory/generation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "memory/space.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "runtime/os.hpp"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6725
diff changeset
34 #include "utilities/macros.hpp"
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6725
diff changeset
35 #if INCLUDE_ALL_GCS
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "gc_implementation/g1/concurrentMark.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6725
diff changeset
38 #endif // INCLUDE_ALL_GCS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 CardTableRS::CardTableRS(MemRegion whole_heap,
a61af66fc99e Initial load
duke
parents:
diff changeset
41 int max_covered_regions) :
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
42 GenRemSet(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
43 _cur_youngergen_card_val(youngergenP1_card),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
44 _regions_to_iterate(max_covered_regions - 1)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
45 {
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6725
diff changeset
46 #if INCLUDE_ALL_GCS
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
47 if (UseG1GC) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
48 _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
49 max_covered_regions);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
50 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
51 _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
52 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
53 #else
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
54 _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
55 #endif
20337
1f1d373cd044 8038423: G1: Decommit memory within heap
tschatzl
parents: 17937
diff changeset
56 _ct_bs->initialize();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
57 set_bs(_ct_bs);
10271
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
58 _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1,
20360
833b0f92429a 8046598: Scalable Native memory tracking development
zgu
parents: 20337
diff changeset
59 mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
60 if (_last_cur_val_in_gen == NULL) {
10271
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
61 vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _last_cur_val_in_gen[i] = clean_card_val();
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
66 _ct_bs->set_CTRS(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
10271
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
69 CardTableRS::~CardTableRS() {
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
70 if (_ct_bs) {
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
71 delete _ct_bs;
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
72 _ct_bs = NULL;
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
73 }
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
74 if (_last_cur_val_in_gen) {
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
75 FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen, mtInternal);
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
76 }
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
77 }
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10135
diff changeset
78
0
a61af66fc99e Initial load
duke
parents:
diff changeset
79 void CardTableRS::resize_covered_region(MemRegion new_region) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
80 _ct_bs->resize_covered_region(new_region);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 jbyte CardTableRS::find_unused_youngergenP_card_value() {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 for (jbyte v = youngergenP1_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 v < cur_youngergen_and_prev_nonclean_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 v++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 bool seen = false;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
88 for (int g = 0; g < _regions_to_iterate; g++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
89 if (_last_cur_val_in_gen[g] == v) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 seen = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (!seen) return v;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 void CardTableRS::prepare_for_younger_refs_iterate(bool parallel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Parallel or sequential, we must always set the prev to equal the
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // last one written.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (parallel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // Find a parallel value to be used next.
a61af66fc99e Initial load
duke
parents:
diff changeset
105 jbyte next_val = find_unused_youngergenP_card_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
106 set_cur_youngergen_card_val(next_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // In an sequential traversal we will always write youngergen, so that
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // the inline barrier is correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
111 set_cur_youngergen_card_val(youngergen_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 void CardTableRS::younger_refs_iterate(Generation* g,
a61af66fc99e Initial load
duke
parents:
diff changeset
116 OopsInGenClosure* blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 _last_cur_val_in_gen[g->level()+1] = cur_youngergen_card_val();
a61af66fc99e Initial load
duke
parents:
diff changeset
118 g->younger_refs_iterate(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
121 inline bool ClearNoncleanCardWrapper::clear_card(jbyte* entry) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
122 if (_is_par) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
123 return clear_card_parallel(entry);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
124 } else {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
125 return clear_card_serial(entry);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
126 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
127 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
128
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
129 inline bool ClearNoncleanCardWrapper::clear_card_parallel(jbyte* entry) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
130 while (true) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
131 // In the parallel case, we may have to do this several times.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
132 jbyte entry_val = *entry;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
133 assert(entry_val != CardTableRS::clean_card_val(),
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
134 "We shouldn't be looking at clean cards, and this should "
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
135 "be the only place they get cleaned.");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
136 if (CardTableRS::card_is_dirty_wrt_gen_iter(entry_val)
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
137 || _ct->is_prev_youngergen_card_val(entry_val)) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
138 jbyte res =
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
139 Atomic::cmpxchg(CardTableRS::clean_card_val(), entry, entry_val);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
140 if (res == entry_val) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
141 break;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
142 } else {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
143 assert(res == CardTableRS::cur_youngergen_and_prev_nonclean_card,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
144 "The CAS above should only fail if another thread did "
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
145 "a GC write barrier.");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
147 } else if (entry_val ==
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
148 CardTableRS::cur_youngergen_and_prev_nonclean_card) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
149 // Parallelism shouldn't matter in this case. Only the thread
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
150 // assigned to scan the card should change this value.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
151 *entry = _ct->cur_youngergen_card_val();
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
152 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
153 } else {
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
154 assert(entry_val == _ct->cur_youngergen_card_val(),
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
155 "Should be the only possibility.");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
156 // In this case, the card was clean before, and become
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
157 // cur_youngergen only because of processing of a promoted object.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
158 // We don't have to look at the card.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
159 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
162 return true;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
163 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
165
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
166 inline bool ClearNoncleanCardWrapper::clear_card_serial(jbyte* entry) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
167 jbyte entry_val = *entry;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
168 assert(entry_val != CardTableRS::clean_card_val(),
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
169 "We shouldn't be looking at clean cards, and this should "
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
170 "be the only place they get cleaned.");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
171 assert(entry_val != CardTableRS::cur_youngergen_and_prev_nonclean_card,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
172 "This should be possible in the sequential case.");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
173 *entry = CardTableRS::clean_card_val();
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
174 return true;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
175 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
176
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
177 ClearNoncleanCardWrapper::ClearNoncleanCardWrapper(
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3293
diff changeset
178 DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
179 _dirty_card_closure(dirty_card_closure), _ct(ct) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3357
diff changeset
180 // Cannot yet substitute active_workers for n_par_threads
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3357
diff changeset
181 // in the case where parallelism is being turned off by
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3357
diff changeset
182 // setting n_par_threads to 0.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
183 _is_par = (SharedHeap::heap()->n_par_threads() > 0);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3357
diff changeset
184 assert(!_is_par ||
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3357
diff changeset
185 (SharedHeap::heap()->n_par_threads() ==
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3357
diff changeset
186 SharedHeap::heap()->workers()->active_workers()), "Mismatch");
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
187 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
188
5939
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
189 bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) {
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
190 return (((intptr_t)entry) & (BytesPerWord-1)) == 0;
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
191 }
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
192
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
193 void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
194 assert(mr.word_size() > 0, "Error");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
195 assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
196 // mr.end() may not necessarily be card aligned.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
197 jbyte* cur_entry = _ct->byte_for(mr.last());
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
198 const jbyte* limit = _ct->byte_for(mr.start());
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
199 HeapWord* end_of_non_clean = mr.end();
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
200 HeapWord* start_of_non_clean = end_of_non_clean;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
201 while (cur_entry >= limit) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
202 HeapWord* cur_hw = _ct->addr_for(cur_entry);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
203 if ((*cur_entry != CardTableRS::clean_card_val()) && clear_card(cur_entry)) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
204 // Continue the dirty range by opening the
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
205 // dirty window one card to the left.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
206 start_of_non_clean = cur_hw;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
207 } else {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
208 // We hit a "clean" card; process any non-empty
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
209 // "dirty" range accumulated so far.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
210 if (start_of_non_clean < end_of_non_clean) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
211 const MemRegion mrd(start_of_non_clean, end_of_non_clean);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
212 _dirty_card_closure->do_MemRegion(mrd);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
213 }
5939
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
214
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
215 // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
216 if (is_word_aligned(cur_entry)) {
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
217 jbyte* cur_row = cur_entry - BytesPerWord;
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
218 while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row()) {
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
219 cur_row -= BytesPerWord;
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
220 }
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
221 cur_entry = cur_row + BytesPerWord;
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
222 cur_hw = _ct->addr_for(cur_entry);
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
223 }
c7a555a9449a 7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents: 4095
diff changeset
224
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
225 // Reset the dirty window, while continuing to look
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
226 // for the next dirty card that will start a
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
227 // new dirty window.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
228 end_of_non_clean = cur_hw;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
229 start_of_non_clean = cur_hw;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
230 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
231 // Note that "cur_entry" leads "start_of_non_clean" in
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
232 // its leftward excursion after this point
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
233 // in the loop and, when we hit the left end of "mr",
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
234 // will point off of the left end of the card-table
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
235 // for "mr".
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
236 cur_entry--;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
238 // If the first card of "mr" was dirty, we will have
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
239 // been left with a dirty window, co-initial with "mr",
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
240 // which we now process.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
241 if (start_of_non_clean < end_of_non_clean) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
242 const MemRegion mrd(start_of_non_clean, end_of_non_clean);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
243 _dirty_card_closure->do_MemRegion(mrd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
245 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
246
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // clean (by dirty->clean before) ==> cur_younger_gen
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // dirty ==> cur_youngergen_and_prev_nonclean_card
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // precleaned ==> cur_youngergen_and_prev_nonclean_card
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // prev-younger-gen ==> cur_youngergen_and_prev_nonclean_card
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // cur-younger-gen ==> cur_younger_gen
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // cur_youngergen_and_prev_nonclean_card ==> no change.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
253 void CardTableRS::write_ref_field_gc_par(void* field, oop new_val) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254 jbyte* entry = ct_bs()->byte_for(field);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 jbyte entry_val = *entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // We put this first because it's probably the most common case.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 if (entry_val == clean_card_val()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // No threat of contention with cleaning threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
260 *entry = cur_youngergen_card_val();
a61af66fc99e Initial load
duke
parents:
diff changeset
261 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 } else if (card_is_dirty_wrt_gen_iter(entry_val)
a61af66fc99e Initial load
duke
parents:
diff changeset
263 || is_prev_youngergen_card_val(entry_val)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Mark it as both cur and prev youngergen; card cleaning thread will
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // eventually remove the previous stuff.
a61af66fc99e Initial load
duke
parents:
diff changeset
266 jbyte new_val = cur_youngergen_and_prev_nonclean_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 jbyte res = Atomic::cmpxchg(new_val, entry, entry_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // Did the CAS succeed?
a61af66fc99e Initial load
duke
parents:
diff changeset
269 if (res == entry_val) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Otherwise, retry, to see the new value.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
272 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 assert(entry_val == cur_youngergen_and_prev_nonclean_card
a61af66fc99e Initial load
duke
parents:
diff changeset
274 || entry_val == cur_youngergen_card_val(),
a61af66fc99e Initial load
duke
parents:
diff changeset
275 "should be only possibilities.");
a61af66fc99e Initial load
duke
parents:
diff changeset
276 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 } while (true);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 void CardTableRS::younger_refs_in_space_iterate(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
282 OopsInGenClosure* cl) {
3293
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
283 const MemRegion urasm = sp->used_region_at_save_marks();
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
284 #ifdef ASSERT
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
285 // Convert the assertion check to a warning if we are running
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
286 // CMS+ParNew until related bug is fixed.
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
287 MemRegion ur = sp->used_region();
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
288 assert(ur.contains(urasm) || (UseConcMarkSweepGC && UseParNewGC),
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
289 err_msg("Did you forget to call save_marks()? "
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
290 "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
291 "[" PTR_FORMAT ", " PTR_FORMAT ")",
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
292 p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end())));
3293
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
293 // In the case of CMS+ParNew, issue a warning
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
294 if (!ur.contains(urasm)) {
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
295 assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above");
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
296 warning("CMS+ParNew: Did you forget to call save_marks()? "
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
297 "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
298 "[" PTR_FORMAT ", " PTR_FORMAT ")",
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
299 p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));
3293
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
300 MemRegion ur2 = sp->used_region();
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
301 MemRegion urasm2 = sp->used_region_at_save_marks();
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
302 if (!ur.equals(ur2)) {
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
303 warning("CMS+ParNew: Flickering used_region()!!");
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
304 }
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
305 if (!urasm.equals(urasm2)) {
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
306 warning("CMS+ParNew: Flickering used_region_at_save_marks()!!");
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
307 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3293
diff changeset
308 ShouldNotReachHere();
3293
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
309 }
1f4413413144 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 3287
diff changeset
310 #endif
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3293
diff changeset
311 _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
12033
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
314 void CardTableRS::clear_into_younger(Generation* old_gen) {
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
315 assert(old_gen->level() == 1, "Should only be called for the old generation");
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
316 // The card tables for the youngest gen need never be cleared.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // There's a bit of subtlety in the clear() and invalidate()
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // methods that we exploit here and in invalidate_or_clear()
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // below to avoid missing cards at the fringes. If clear() or
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // invalidate() are changed in the future, this code should
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // be revisited. 20040107.ysr
12030
330dfb0476f4 8022800: Use specific generations rather than generation iteration
brutisso
parents: 10271
diff changeset
322 clear(old_gen->prev_used_region());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
12033
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
325 void CardTableRS::invalidate_or_clear(Generation* old_gen) {
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
326 assert(old_gen->level() == 1, "Should only be called for the old generation");
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
327 // Invalidate the cards for the currently occupied part of
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
328 // the old generation and clear the cards for the
0
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // unoccupied part of the generation (if any, making use
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // of that generation's prev_used_region to determine that
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // region). No need to do anything for the youngest
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // generation. Also see note#20040107.ysr above.
12033
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
333 MemRegion used_mr = old_gen->used_region();
bd902affe102 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013
brutisso
parents: 12030
diff changeset
334 MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr);
12030
330dfb0476f4 8022800: Use specific generations rather than generation iteration
brutisso
parents: 10271
diff changeset
335 if (!to_be_cleared_mr.is_empty()) {
330dfb0476f4 8022800: Use specific generations rather than generation iteration
brutisso
parents: 10271
diff changeset
336 clear(to_be_cleared_mr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
12030
330dfb0476f4 8022800: Use specific generations rather than generation iteration
brutisso
parents: 10271
diff changeset
338 invalidate(used_mr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 class VerifyCleanCardClosure: public OopClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
343 private:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
344 HeapWord* _boundary;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
345 HeapWord* _begin;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
346 HeapWord* _end;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
347 protected:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
348 template <class T> void do_oop_work(T* p) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
349 HeapWord* jp = (HeapWord*)p;
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
350 assert(jp >= _begin && jp < _end,
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
351 err_msg("Error: jp " PTR_FORMAT " should be within "
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
352 "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")",
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
353 p2i(jp), p2i(_begin), p2i(_end)));
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
354 oop obj = oopDesc::load_decode_heap_oop(p);
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
355 guarantee(obj == NULL || (HeapWord*)obj >= _boundary,
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
356 err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on "
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
357 "clean card crosses boundary" PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
358 p2i((HeapWord*)obj), p2i(jp), p2i(_boundary)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
360
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
361 public:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
362 VerifyCleanCardClosure(HeapWord* b, HeapWord* begin, HeapWord* end) :
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
363 _boundary(b), _begin(begin), _end(end) {
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
364 assert(b <= begin,
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
365 err_msg("Error: boundary " PTR_FORMAT " should be at or below begin " PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
366 p2i(b), p2i(begin)));
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
367 assert(begin <= end,
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
368 err_msg("Error: begin " PTR_FORMAT " should be strictly below end " PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 12033
diff changeset
369 p2i(begin), p2i(end)));
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
370 }
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
371
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
372 virtual void do_oop(oop* p) { VerifyCleanCardClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
373 virtual void do_oop(narrowOop* p) { VerifyCleanCardClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
374 };
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 class VerifyCTSpaceClosure: public SpaceClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
377 private:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378 CardTableRS* _ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 HeapWord* _boundary;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
381 VerifyCTSpaceClosure(CardTableRS* ct, HeapWord* boundary) :
a61af66fc99e Initial load
duke
parents:
diff changeset
382 _ct(ct), _boundary(boundary) {}
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
383 virtual void do_space(Space* s) { _ct->verify_space(s, _boundary); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
384 };
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 class VerifyCTGenClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 CardTableRS* _ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
389 VerifyCTGenClosure(CardTableRS* ct) : _ct(ct) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
390 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // Skip the youngest generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
392 if (gen->level() == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Normally, we're interested in pointers to younger generations.
a61af66fc99e Initial load
duke
parents:
diff changeset
394 VerifyCTSpaceClosure blk(_ct, gen->reserved().start());
a61af66fc99e Initial load
duke
parents:
diff changeset
395 gen->space_iterate(&blk, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397 };
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 void CardTableRS::verify_space(Space* s, HeapWord* gen_boundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // We don't need to do young-gen spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (s->end() <= gen_boundary) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 MemRegion used = s->used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 jbyte* cur_entry = byte_for(used.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
405 jbyte* limit = byte_after(used.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
406 while (cur_entry < limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 if (*cur_entry == CardTableModRefBS::clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 jbyte* first_dirty = cur_entry+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 while (first_dirty < limit &&
a61af66fc99e Initial load
duke
parents:
diff changeset
410 *first_dirty == CardTableModRefBS::clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 first_dirty++;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // If the first object is a regular object, and it has a
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // young-to-old field, that would mark the previous card.
a61af66fc99e Initial load
duke
parents:
diff changeset
415 HeapWord* boundary = addr_for(cur_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 HeapWord* end = (first_dirty >= limit) ? used.end() : addr_for(first_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 HeapWord* boundary_block = s->block_start(boundary);
a61af66fc99e Initial load
duke
parents:
diff changeset
418 HeapWord* begin = boundary; // Until proven otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
419 HeapWord* start_block = boundary_block; // Until proven otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (boundary_block < boundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (s->block_is_obj(boundary_block) && s->obj_is_alive(boundary_block)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 oop boundary_obj = oop(boundary_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 if (!boundary_obj->is_objArray() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
424 !boundary_obj->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 guarantee(cur_entry > byte_for(used.start()),
a61af66fc99e Initial load
duke
parents:
diff changeset
426 "else boundary would be boundary_block");
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (*byte_for(boundary_block) != CardTableModRefBS::clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 begin = boundary_block + s->block_size(boundary_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 start_block = begin;
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // Now traverse objects until end.
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
435 if (begin < end) {
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
436 MemRegion mr(begin, end);
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
437 VerifyCleanCardClosure verify_blk(gen_boundary, begin, end);
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
438 for (HeapWord* cur = start_block; cur < end; cur += s->block_size(cur)) {
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
439 if (s->block_is_obj(cur) && s->obj_is_alive(cur)) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 5939
diff changeset
440 oop(cur)->oop_iterate_no_header(&verify_blk, mr);
2428
5134fa1cfe63 7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC
ysr
parents: 1972
diff changeset
441 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 cur_entry = first_dirty;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // We'd normally expect that cur_youngergen_and_prev_nonclean_card
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // is a transient value, that cannot be in the card table
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // except during GC, and thus assert that:
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // guarantee(*cur_entry != cur_youngergen_and_prev_nonclean_card,
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // "Illegal CT value");
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // That however, need not hold, as will become clear in the
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // following...
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // We'd normally expect that if we are in the parallel case,
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // we can't have left a prev value (which would be different
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // from the current value) in the card table, and so we'd like to
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // assert that:
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // guarantee(cur_youngergen_card_val() == youngergen_card
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // || !is_prev_youngergen_card_val(*cur_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // "Illegal CT value");
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // That, however, may not hold occasionally, because of
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // CMS or MSC in the old gen. To wit, consider the
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // following two simple illustrative scenarios:
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // (a) CMS: Consider the case where a large object L
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // spanning several cards is allocated in the old
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // gen, and has a young gen reference stored in it, dirtying
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // some interior cards. A young collection scans the card,
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // finds a young ref and installs a youngergenP_n value.
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // L then goes dead. Now a CMS collection starts,
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // finds L dead and sweeps it up. Assume that L is
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // abutting _unallocated_blk, so _unallocated_blk is
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // adjusted down to (below) L. Assume further that
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // no young collection intervenes during this CMS cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // The next young gen cycle will not get to look at this
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // youngergenP_n card since it lies in the unoccupied
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // part of the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // Some young collections later the blocks on this
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // card can be re-allocated either due to direct allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // or due to absorbing promotions. At this time, the
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // before-gc verification will fail the above assert.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // (b) MSC: In this case, an object L with a young reference
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // is on a card that (therefore) holds a youngergen_n value.
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // Suppose also that L lies towards the end of the used
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // the used space before GC. An MSC collection
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // occurs that compacts to such an extent that this
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // card is no longer in the occupied part of the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // Since current code in MSC does not always clear cards
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // in the unused part of old gen, this stale youngergen_n
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // value is left behind and can later be covered by
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // an object when promotion or direct allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // re-allocates that part of the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
492 //
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // Fortunately, the presence of such stale card values is
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // "only" a minor annoyance in that subsequent young collections
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // might needlessly scan such cards, but would still never corrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // the heap as a result. However, it's likely not to be a significant
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // performance inhibitor in practice. For instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // some recent measurements with unoccupied cards eagerly cleared
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // out to maintain this invariant, showed next to no
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // change in young collection times; of course one can construct
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // degenerate examples where the cost can be significant.)
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // Note, in particular, that if the "stale" card is modified
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // after re-allocation, it would be dirty, not "stale". Thus,
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // we can never have a younger ref in such a card and it is
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // safe not to scan that card in any collection. [As we see
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // below, we do some unnecessary scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // in some cases in the current parallel scanning algorithm.]
a61af66fc99e Initial load
duke
parents:
diff changeset
508 //
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // The main point below is that the parallel card scanning code
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // deals correctly with these stale card values. There are two main
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // cases to consider where we have a stale "younger gen" value and a
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // "derivative" case to consider, where we have a stale
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // "cur_younger_gen_and_prev_non_clean" value, as will become
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // apparent in the case analysis below.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // o Case 1. If the stale value corresponds to a younger_gen_n
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // value other than the cur_younger_gen value then the code
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // treats this as being tantamount to a prev_younger_gen
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // card. This means that the card may be unnecessarily scanned.
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // There are two sub-cases to consider:
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // o Case 1a. Let us say that the card is in the occupied part
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // of the generation at the time the collection begins. In
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // that case the card will be either cleared when it is scanned
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // for young pointers, or will be set to cur_younger_gen as a
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // result of promotion. (We have elided the normal case where
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // the scanning thread and the promoting thread interleave
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // possibly resulting in a transient
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // cur_younger_gen_and_prev_non_clean value before settling
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // to cur_younger_gen. [End Case 1a.]
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // o Case 1b. Consider now the case when the card is in the unoccupied
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // part of the space which becomes occupied because of promotions
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // into it during the current young GC. In this case the card
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // will never be scanned for young references. The current
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // code will set the card value to either
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // cur_younger_gen_and_prev_non_clean or leave
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // it with its stale value -- because the promotions didn't
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // result in any younger refs on that card. Of these two
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // cases, the latter will be covered in Case 1a during
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // a subsequent scan. To deal with the former case, we need
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // to further consider how we deal with a stale value of
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // cur_younger_gen_and_prev_non_clean in our case analysis
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // below. This we do in Case 3 below. [End Case 1b]
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // [End Case 1]
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // o Case 2. If the stale value corresponds to cur_younger_gen being
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // a value not necessarily written by a current promotion, the
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // card will not be scanned by the younger refs scanning code.
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // (This is OK since as we argued above such cards cannot contain
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // any younger refs.) The result is that this value will be
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // treated as a prev_younger_gen value in a subsequent collection,
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // which is addressed in Case 1 above. [End Case 2]
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // o Case 3. We here consider the "derivative" case from Case 1b. above
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // because of which we may find a stale
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // cur_younger_gen_and_prev_non_clean card value in the table.
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // Once again, as in Case 1, we consider two subcases, depending
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // on whether the card lies in the occupied or unoccupied part
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // of the space at the start of the young collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // o Case 3a. Let us say the card is in the occupied part of
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // the old gen at the start of the young collection. In that
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // case, the card will be scanned by the younger refs scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // code which will set it to cur_younger_gen. In a subsequent
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // scan, the card will be considered again and get its final
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // correct value. [End Case 3a]
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // o Case 3b. Now consider the case where the card is in the
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // unoccupied part of the old gen, and is occupied as a result
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // of promotions during thus young gc. In that case,
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // the card will not be scanned for younger refs. The presence
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // of newly promoted objects on the card will then result in
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // its keeping the value cur_younger_gen_and_prev_non_clean
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // value, which we have dealt with in Case 3 here. [End Case 3b]
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // [End Case 3]
a61af66fc99e Initial load
duke
parents:
diff changeset
570 //
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // (Please refer to the code in the helper class
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // ClearNonCleanCardWrapper and in CardTableModRefBS for details.)
a61af66fc99e Initial load
duke
parents:
diff changeset
573 //
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // The informal arguments above can be tightened into a formal
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // correctness proof and it behooves us to write up such a proof,
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // or to use model checking to prove that there are no lingering
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // concerns.
a61af66fc99e Initial load
duke
parents:
diff changeset
578 //
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Clearly because of Case 3b one cannot bound the time for
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // which a card will retain what we have called a "stale" value.
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // However, one can obtain a Loose upper bound on the redundant
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // work as a result of such stale values. Note first that any
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // time a stale card lies in the occupied part of the space at
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // the start of the collection, it is scanned by younger refs
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // code and we can define a rank function on card values that
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // declines when this is so. Note also that when a card does not
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // lie in the occupied part of the space at the beginning of a
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // young collection, its rank can either decline or stay unchanged.
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // In this case, no extra work is done in terms of redundant
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // younger refs scanning of that card.
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Then, the case analysis above reveals that, in the worst case,
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // any such stale card will be scanned unnecessarily at most twice.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 //
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // It is nonethelss advisable to try and get rid of some of this
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // redundant work in a subsequent (low priority) re-design of
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // the card-scanning code, if only to simplify the underlying
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // state machine analysis/proof. ysr 1/28/2002. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
598 cur_entry++;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 void CardTableRS::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // At present, we only know how to verify the card table RS for
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // generational heaps.
a61af66fc99e Initial load
duke
parents:
diff changeset
606 VerifyCTGenClosure blk(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 CollectedHeap* ch = Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 if (ch->kind() == CollectedHeap::GenCollectedHeap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
610 GenCollectedHeap::heap()->generation_iterate(&blk, false);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
611 _ct_bs->verify();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
614
a61af66fc99e Initial load
duke
parents:
diff changeset
615
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
616 void CardTableRS::verify_aligned_region_empty(MemRegion mr) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
617 if (!mr.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 jbyte* cur_entry = byte_for(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
619 jbyte* limit = byte_after(mr.last());
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
620 // The region mr may not start on a card boundary so
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
621 // the first card may reflect a write to the space
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
622 // just prior to mr.
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
623 if (!is_aligned(mr.start())) {
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
624 cur_entry++;
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
625 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
626 for (;cur_entry < limit; cur_entry++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 guarantee(*cur_entry == CardTableModRefBS::clean_card,
a61af66fc99e Initial load
duke
parents:
diff changeset
628 "Unexpected dirty card found");
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631 }