annotate src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @ 6862:8a5ea0a9ccc4

7127708: G1: change task num types from int to uint in concurrent mark Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich. Reviewed-by: johnc Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author johnc
date Sat, 06 Oct 2012 01:17:44 -0700
parents d2a62e0f25eb
children 957c266d8bc5 b9a9ed0f8eeb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
3860
3be7439273c5 7044486: open jdk repos have files with incorrect copyright headers, which can end up in src bundles
katleman
parents: 3762
diff changeset
2 * Copyright (c) 2007, 2011, 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: 845
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 845
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: 845
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: 1833
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
26 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
27 #include "memory/cardTableModRefBS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
28 #include "memory/cardTableRS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
29 #include "memory/sharedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
30 #include "memory/space.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
31 #include "memory/universe.hpp"
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
32 #include "oops/oop.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
33 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
34 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
35 #include "runtime/virtualspace.hpp"
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
36 #include "runtime/vmThread.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
38 void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
39 OopsInGenClosure* cl,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
40 CardTableRS* ct,
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
41 int n_threads) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
42 assert(n_threads > 0, "Error: expected n_threads > 0");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
43 assert((n_threads == 1 && ParallelGCThreads == 0) ||
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
44 n_threads <= (int)ParallelGCThreads,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
45 "# worker threads != # requested!");
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
46 assert(!Thread::current()->is_VM_thread() || (n_threads == 1), "There is only 1 VM thread");
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
47 assert(UseDynamicNumberOfGCThreads ||
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
48 !FLAG_IS_DEFAULT(ParallelGCThreads) ||
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
49 n_threads == (int)ParallelGCThreads,
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
50 "# worker threads != # requested!");
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
51 // Make sure the LNC array is valid for the space.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
52 jbyte** lowest_non_clean;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
53 uintptr_t lowest_non_clean_base_chunk_index;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
54 size_t lowest_non_clean_chunk_size;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
55 get_LNC_array_for_space(sp, lowest_non_clean,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
56 lowest_non_clean_base_chunk_index,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
57 lowest_non_clean_chunk_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
58
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
59 uint n_strides = n_threads * ParGCStridesPerThread;
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
60 SequentialSubTasksDone* pst = sp->par_seq_tasks();
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
61 // Sets the condition for completion of the subtask (how many threads
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3860
diff changeset
62 // need to finish in order to be done).
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
63 pst->set_n_threads(n_threads);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
64 pst->set_n_tasks(n_strides);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
65
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
66 uint stride = 0;
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
67 while (!pst->is_task_claimed(/* reference */ stride)) {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
68 process_stride(sp, mr, stride, n_strides, cl, ct,
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
69 lowest_non_clean,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
70 lowest_non_clean_base_chunk_index,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
71 lowest_non_clean_chunk_size);
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
72 }
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
73 if (pst->all_tasks_completed()) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
74 // Clear lowest_non_clean array for next time.
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
75 intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
76 uintptr_t last_chunk_index = addr_to_chunk_index(mr.last());
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
77 for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
78 intptr_t ind = ch - lowest_non_clean_base_chunk_index;
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
79 assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
80 "Bounds error");
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
81 lowest_non_clean[ind] = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 void
a61af66fc99e Initial load
duke
parents:
diff changeset
87 CardTableModRefBS::
a61af66fc99e Initial load
duke
parents:
diff changeset
88 process_stride(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
89 MemRegion used,
a61af66fc99e Initial load
duke
parents:
diff changeset
90 jint stride, int n_strides,
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
91 OopsInGenClosure* cl,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
92 CardTableRS* ct,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93 jbyte** lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
94 uintptr_t lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
95 size_t lowest_non_clean_chunk_size) {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
96 // We go from higher to lower addresses here; it wouldn't help that much
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
97 // because of the strided parallelism pattern used here.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Find the first card address of the first chunk in the stride that is
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // at least "bottom" of the used region.
a61af66fc99e Initial load
duke
parents:
diff changeset
101 jbyte* start_card = byte_for(used.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
102 jbyte* end_card = byte_after(used.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
103 uintptr_t start_chunk = addr_to_chunk_index(used.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
104 uintptr_t start_chunk_stride_num = start_chunk % n_strides;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 jbyte* chunk_card_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if ((uintptr_t)stride >= start_chunk_stride_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 chunk_card_start = (jbyte*)(start_card +
a61af66fc99e Initial load
duke
parents:
diff changeset
109 (stride - start_chunk_stride_num) *
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
110 ParGCCardsPerStrideChunk);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
111 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // Go ahead to the next chunk group boundary, then to the requested stride.
a61af66fc99e Initial load
duke
parents:
diff changeset
113 chunk_card_start = (jbyte*)(start_card +
a61af66fc99e Initial load
duke
parents:
diff changeset
114 (n_strides - start_chunk_stride_num + stride) *
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
115 ParGCCardsPerStrideChunk);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 while (chunk_card_start < end_card) {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
119 // Even though we go from lower to higher addresses below, the
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
120 // strided parallelism can interleave the actual processing of the
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
121 // dirty pages in various ways. For a specific chunk within this
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
122 // stride, we take care to avoid double scanning or missing a card
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
123 // by suitably initializing the "min_done" field in process_chunk_boundaries()
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
124 // below, together with the dirty region extension accomplished in
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
125 // DirtyCardToOopClosure::do_MemRegion().
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
126 jbyte* chunk_card_end = chunk_card_start + ParGCCardsPerStrideChunk;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Invariant: chunk_mr should be fully contained within the "used" region.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 MemRegion chunk_mr = MemRegion(addr_for(chunk_card_start),
a61af66fc99e Initial load
duke
parents:
diff changeset
129 chunk_card_end >= end_card ?
a61af66fc99e Initial load
duke
parents:
diff changeset
130 used.end() : addr_for(chunk_card_end));
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
a61af66fc99e Initial load
duke
parents:
diff changeset
132 assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
a61af66fc99e Initial load
duke
parents:
diff changeset
133
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
134 DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(),
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
135 cl->gen_boundary());
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
136 ClearNoncleanCardWrapper clear_cl(dcto_cl, ct);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
137
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
138
0
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Process the chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
140 process_chunk_boundaries(sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
141 dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
142 chunk_mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
143 used,
a61af66fc99e Initial load
duke
parents:
diff changeset
144 lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
145 lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
146 lowest_non_clean_chunk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
147
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
148 // We want the LNC array updates above in process_chunk_boundaries
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
149 // to be visible before any of the card table value changes as a
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
150 // result of the dirty card iteration below.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
151 OrderAccess::storestore();
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
152
3287
c48ad6ab8bdf 7037276: Unnecessary double traversal of dirty card windows
ysr
parents: 3256
diff changeset
153 // We do not call the non_clean_card_iterate_serial() version because
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
154 // we want to clear the cards: clear_cl here does the work of finding
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
155 // contiguous dirty ranges of cards to process and clear.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
156 clear_cl.do_MemRegion(chunk_mr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // Find the next chunk of the stride.
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
159 chunk_card_start += ParGCCardsPerStrideChunk * n_strides;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
163
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
164 // If you want a talkative process_chunk_boundaries,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
165 // then #define NOISY(x) x
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
166 #ifdef NOISY
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
167 #error "Encountered a global preprocessor flag, NOISY, which might clash with local definition to follow"
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
168 #else
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
169 #define NOISY(x)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
170 #endif
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
171
0
a61af66fc99e Initial load
duke
parents:
diff changeset
172 void
a61af66fc99e Initial load
duke
parents:
diff changeset
173 CardTableModRefBS::
a61af66fc99e Initial load
duke
parents:
diff changeset
174 process_chunk_boundaries(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
175 DirtyCardToOopClosure* dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
176 MemRegion chunk_mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
177 MemRegion used,
a61af66fc99e Initial load
duke
parents:
diff changeset
178 jbyte** lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
179 uintptr_t lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
180 size_t lowest_non_clean_chunk_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
181 {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
182 // We must worry about non-array objects that cross chunk boundaries,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
183 // because such objects are both precisely and imprecisely marked:
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
184 // .. if the head of such an object is dirty, the entire object
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
185 // needs to be scanned, under the interpretation that this
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
186 // was an imprecise mark
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
187 // .. if the head of such an object is not dirty, we can assume
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
188 // precise marking and it's efficient to scan just the dirty
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
189 // cards.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
190 // In either case, each scanned reference must be scanned precisely
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
191 // once so as to avoid cloning of a young referent. For efficiency,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
192 // our closures depend on this property and do not protect against
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
193 // double scans.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 uintptr_t cur_chunk_index = addr_to_chunk_index(chunk_mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
196 cur_chunk_index = cur_chunk_index - lowest_non_clean_base_chunk_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
197
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
198 NOISY(tty->print_cr("===========================================================================");)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
199 NOISY(tty->print_cr(" process_chunk_boundary: Called with [" PTR_FORMAT "," PTR_FORMAT ")",
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
200 chunk_mr.start(), chunk_mr.end());)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
201
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
202 // First, set "our" lowest_non_clean entry, which would be
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
203 // used by the thread scanning an adjoining left chunk with
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
204 // a non-array object straddling the mutual boundary.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
205 // Find the object that spans our boundary, if one exists.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
206 // first_block is the block possibly straddling our left boundary.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
207 HeapWord* first_block = sp->block_start(chunk_mr.start());
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
208 assert((chunk_mr.start() != used.start()) || (first_block == chunk_mr.start()),
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
209 "First chunk should always have a co-initial block");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
210 // Does the block straddle the chunk's left boundary, and is it
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
211 // a non-array object?
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
212 if (first_block < chunk_mr.start() // first block straddles left bdry
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
213 && sp->block_is_obj(first_block) // first block is an object
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
214 && !(oop(first_block)->is_objArray() // first block is not an array (arrays are precisely dirtied)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
215 || oop(first_block)->is_typeArray())) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
216 // Find our least non-clean card, so that a left neighbour
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
217 // does not scan an object straddling the mutual boundary
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
218 // too far to the right, and attempt to scan a portion of
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
219 // that object twice.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
220 jbyte* first_dirty_card = NULL;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
221 jbyte* last_card_of_first_obj =
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
222 byte_for(first_block + sp->block_size(first_block) - 1);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
223 jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
224 jbyte* last_card_of_cur_chunk = byte_for(chunk_mr.last());
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
225 jbyte* last_card_to_check =
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
226 (jbyte*) MIN2((intptr_t) last_card_of_cur_chunk,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
227 (intptr_t) last_card_of_first_obj);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
228 // Note that this does not need to go beyond our last card
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
229 // if our first object completely straddles this chunk.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
230 for (jbyte* cur = first_card_of_cur_chunk;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
231 cur <= last_card_to_check; cur++) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
232 jbyte val = *cur;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
233 if (card_will_be_scanned(val)) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
234 first_dirty_card = cur; break;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
235 } else {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
236 assert(!card_may_have_been_dirty(val), "Error");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
237 }
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
238 }
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
239 if (first_dirty_card != NULL) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
240 NOISY(tty->print_cr(" LNC: Found a dirty card at " PTR_FORMAT " in current chunk",
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
241 first_dirty_card);)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
242 assert(0 <= cur_chunk_index && cur_chunk_index < lowest_non_clean_chunk_size,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
243 "Bounds error.");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
244 assert(lowest_non_clean[cur_chunk_index] == NULL,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
245 "Write exactly once : value should be stable hereafter for this round");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
246 lowest_non_clean[cur_chunk_index] = first_dirty_card;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
247 } NOISY(else {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
248 tty->print_cr(" LNC: Found no dirty card in current chunk; leaving LNC entry NULL");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
249 // In the future, we could have this thread look for a non-NULL value to copy from its
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
250 // right neighbour (up to the end of the first object).
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
251 if (last_card_of_cur_chunk < last_card_of_first_obj) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
252 tty->print_cr(" LNC: BEWARE!!! first obj straddles past right end of chunk:\n"
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
253 " might be efficient to get value from right neighbour?");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
254 }
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
255 })
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
256 } else {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
257 // In this case we can help our neighbour by just asking them
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
258 // to stop at our first card (even though it may not be dirty).
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
259 NOISY(tty->print_cr(" LNC: first block is not a non-array object; setting LNC to first card of current chunk");)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
260 assert(lowest_non_clean[cur_chunk_index] == NULL, "Write once : value should be stable hereafter");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
261 jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
262 lowest_non_clean[cur_chunk_index] = first_card_of_cur_chunk;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
263 }
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
264 NOISY(tty->print_cr(" process_chunk_boundary: lowest_non_clean[" INTPTR_FORMAT "] = " PTR_FORMAT
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
265 " which corresponds to the heap address " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
266 cur_chunk_index, lowest_non_clean[cur_chunk_index],
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
267 (lowest_non_clean[cur_chunk_index] != NULL)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
268 ? addr_for(lowest_non_clean[cur_chunk_index])
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
269 : NULL);)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
270 NOISY(tty->print_cr("---------------------------------------------------------------------------");)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
271
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
272 // Next, set our own max_to_do, which will strictly/exclusively bound
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
273 // the highest address that we will scan past the right end of our chunk.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
274 HeapWord* max_to_do = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
275 if (chunk_mr.end() < used.end()) {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
276 // This is not the last chunk in the used region.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
277 // What is our last block? We check the first block of
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
278 // the next (right) chunk rather than strictly check our last block
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
279 // because it's potentially more efficient to do so.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
280 HeapWord* const last_block = sp->block_start(chunk_mr.end());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
281 assert(last_block <= chunk_mr.end(), "In case this property changes.");
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
282 if ((last_block == chunk_mr.end()) // our last block does not straddle boundary
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
283 || !sp->block_is_obj(last_block) // last_block isn't an object
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
284 || oop(last_block)->is_objArray() // last_block is an array (precisely marked)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
285 || oop(last_block)->is_typeArray()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
286 max_to_do = chunk_mr.end();
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
287 NOISY(tty->print_cr(" process_chunk_boundary: Last block on this card is not a non-array object;\n"
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
288 " max_to_do left at " PTR_FORMAT, max_to_do);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
289 } else {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
290 assert(last_block < chunk_mr.end(), "Tautology");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
291 // It is a non-array object that straddles the right boundary of this chunk.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // last_obj_card is the card corresponding to the start of the last object
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // in the chunk. Note that the last object may not start in
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // the chunk.
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
295 jbyte* const last_obj_card = byte_for(last_block);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
296 const jbyte val = *last_obj_card;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
297 if (!card_will_be_scanned(val)) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
298 assert(!card_may_have_been_dirty(val), "Error");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
299 // The card containing the head is not dirty. Any marks on
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // subsequent cards still in this chunk must have been made
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
301 // precisely; we can cap processing at the end of our chunk.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
302 max_to_do = chunk_mr.end();
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
303 NOISY(tty->print_cr(" process_chunk_boundary: Head of last object on this card is not dirty;\n"
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
304 " max_to_do left at " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
305 max_to_do);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // The last object must be considered dirty, and extends onto the
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // following chunk. Look for a dirty card in that chunk that will
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // bound our processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 jbyte* limit_card = NULL;
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
311 const size_t last_block_size = sp->block_size(last_block);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
312 jbyte* const last_card_of_last_obj =
0
a61af66fc99e Initial load
duke
parents:
diff changeset
313 byte_for(last_block + last_block_size - 1);
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
314 jbyte* const first_card_of_next_chunk = byte_for(chunk_mr.end());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // This search potentially goes a long distance looking
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
316 // for the next card that will be scanned, terminating
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
317 // at the end of the last_block, if no earlier dirty card
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
318 // is found.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
319 assert(byte_for(chunk_mr.end()) - byte_for(chunk_mr.start()) == ParGCCardsPerStrideChunk,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
320 "last card of next chunk may be wrong");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
321 for (jbyte* cur = first_card_of_next_chunk;
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
322 cur <= last_card_of_last_obj; cur++) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
323 const jbyte val = *cur;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
324 if (card_will_be_scanned(val)) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
325 NOISY(tty->print_cr(" Found a non-clean card " PTR_FORMAT " with value 0x%x",
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
326 cur, (int)val);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
327 limit_card = cur; break;
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
328 } else {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
329 assert(!card_may_have_been_dirty(val), "Error: card can't be skipped");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
332 if (limit_card != NULL) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
333 max_to_do = addr_for(limit_card);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
334 assert(limit_card != NULL && max_to_do != NULL, "Error");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
335 NOISY(tty->print_cr(" process_chunk_boundary: Found a dirty card at " PTR_FORMAT
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
336 " max_to_do set at " PTR_FORMAT " which is before end of last block in chunk: "
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
337 PTR_FORMAT " + " PTR_FORMAT " = " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
338 limit_card, max_to_do, last_block, last_block_size, (last_block+last_block_size));)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
339 } else {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
340 // The following is a pessimistic value, because it's possible
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
341 // that a dirty card on a subsequent chunk has been cleared by
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
342 // the time we get to look at it; we'll correct for that further below,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
343 // using the LNC array which records the least non-clean card
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
344 // before cards were cleared in a particular chunk.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
345 limit_card = last_card_of_last_obj;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
346 max_to_do = last_block + last_block_size;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
347 assert(limit_card != NULL && max_to_do != NULL, "Error");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
348 NOISY(tty->print_cr(" process_chunk_boundary: Found no dirty card before end of last block in chunk\n"
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
349 " Setting limit_card to " PTR_FORMAT
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
350 " and max_to_do " PTR_FORMAT " + " PTR_FORMAT " = " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
351 limit_card, last_block, last_block_size, max_to_do);)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
352 }
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
353 assert(0 < cur_chunk_index+1 && cur_chunk_index+1 < lowest_non_clean_chunk_size,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
354 "Bounds error.");
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
355 // It is possible that a dirty card for the last object may have been
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
356 // cleared before we had a chance to examine it. In that case, the value
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
357 // will have been logged in the LNC for that chunk.
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
358 // We need to examine as many chunks to the right as this object
3762
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
359 // covers. However, we need to bound this checking to the largest
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
360 // entry in the LNC array: this is because the heap may expand
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
361 // after the LNC array has been created but before we reach this point,
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
362 // and the last block in our chunk may have been expanded to include
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
363 // the expansion delta (and possibly subsequently allocated from, so
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
364 // it wouldn't be sufficient to check whether that last block was
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
365 // or was not an object at this point).
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
366 uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1)
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
367 - lowest_non_clean_base_chunk_index;
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
368 const uintptr_t last_chunk_index = addr_to_chunk_index(used.last())
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
369 - lowest_non_clean_base_chunk_index;
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
370 if (last_chunk_index_to_check > last_chunk_index) {
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
371 assert(last_block + last_block_size > used.end(),
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
372 err_msg("Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
373 " does not exceed used.end() = " PTR_FORMAT ","
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
374 " yet last_chunk_index_to_check " INTPTR_FORMAT
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
375 " exceeds last_chunk_index " INTPTR_FORMAT,
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
376 last_chunk_index_to_check, last_chunk_index));
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
377 assert(sp->used_region().end() > used.end(),
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
378 err_msg("Expansion did not happen: "
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
379 "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
380 sp->used_region().start(), sp->used_region().end(), used.start(), used.end()));
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
381 NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");)
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
382 last_chunk_index_to_check = last_chunk_index;
5c0a3c1858b1 7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
ysr
parents: 3359
diff changeset
383 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
384 for (uintptr_t lnc_index = cur_chunk_index + 1;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
385 lnc_index <= last_chunk_index_to_check;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
386 lnc_index++) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
387 jbyte* lnc_card = lowest_non_clean[lnc_index];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
388 if (lnc_card != NULL) {
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
389 // we can stop at the first non-NULL entry we find
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
390 if (lnc_card <= limit_card) {
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
391 NOISY(tty->print_cr(" process_chunk_boundary: LNC card " PTR_FORMAT " is lower than limit_card " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
392 " max_to_do will be lowered to " PTR_FORMAT " from " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
393 lnc_card, limit_card, addr_for(lnc_card), max_to_do);)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
394 limit_card = lnc_card;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
395 max_to_do = addr_for(limit_card);
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
396 assert(limit_card != NULL && max_to_do != NULL, "Error");
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
397 }
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
398 // In any case, we break now
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
399 break;
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
400 } // else continue to look for a non-NULL entry if any
0
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
402 assert(limit_card != NULL && max_to_do != NULL, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
404 assert(max_to_do != NULL, "OOPS 1 !");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
406 assert(max_to_do != NULL, "OOPS 2!");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
407 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 max_to_do = used.end();
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
409 NOISY(tty->print_cr(" process_chunk_boundary: Last chunk of this space;\n"
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
410 " max_to_do left at " PTR_FORMAT,
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
411 max_to_do);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
413 assert(max_to_do != NULL, "OOPS 3!");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Now we can set the closure we're using so it doesn't to beyond
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // max_to_do.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 dcto_cl->set_min_done(max_to_do);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
418 dcto_cl->set_last_bottom(max_to_do);
a61af66fc99e Initial load
duke
parents:
diff changeset
419 #endif
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
420 NOISY(tty->print_cr("===========================================================================\n");)
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
421 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
422
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
423 #undef NOISY
0
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 void
a61af66fc99e Initial load
duke
parents:
diff changeset
426 CardTableModRefBS::
a61af66fc99e Initial load
duke
parents:
diff changeset
427 get_LNC_array_for_space(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
428 jbyte**& lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
429 uintptr_t& lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
430 size_t& lowest_non_clean_chunk_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 int i = find_covering_region_containing(sp->bottom());
a61af66fc99e Initial load
duke
parents:
diff changeset
433 MemRegion covered = _covered[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
434 size_t n_chunks = chunks_to_cover(covered);
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // Only the first thread to obtain the lock will resize the
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // LNC array for the covered region. Any later expansion can't affect
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // the used_at_save_marks region.
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // (I observed a bug in which the first thread to execute this would
3357
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
440 // resize, and then it would cause "expand_and_allocate" that would
fc2b798ab316 6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents: 3287
diff changeset
441 // increase the number of chunks in the covered region. Then a second
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // thread would come and execute this, see that the size didn't match,
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // and free and allocate again. So the first thread would be using a
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // freed "_lowest_non_clean" array.)
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // Do a dirty read here. If we pass the conditional then take the rare
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // event lock and do the read again in case some other thread had already
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // succeeded and done the resize.
a61af66fc99e Initial load
duke
parents:
diff changeset
449 int cur_collection = Universe::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
450 if (_last_LNC_resizing_collection[i] != cur_collection) {
a61af66fc99e Initial load
duke
parents:
diff changeset
451 MutexLocker x(ParGCRareEvent_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 if (_last_LNC_resizing_collection[i] != cur_collection) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 if (_lowest_non_clean[i] == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
454 n_chunks != _lowest_non_clean_chunk_size[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Should we delete the old?
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (_lowest_non_clean[i] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 assert(n_chunks != _lowest_non_clean_chunk_size[i],
a61af66fc99e Initial load
duke
parents:
diff changeset
459 "logical consequence");
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
460 FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i], mtGC);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
461 _lowest_non_clean[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // Now allocate a new one if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if (_lowest_non_clean[i] == NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
465 _lowest_non_clean[i] = NEW_C_HEAP_ARRAY(CardPtr, n_chunks, mtGC);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
466 _lowest_non_clean_chunk_size[i] = n_chunks;
a61af66fc99e Initial load
duke
parents:
diff changeset
467 _lowest_non_clean_base_chunk_index[i] = addr_to_chunk_index(covered.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
468 for (int j = 0; j < (int)n_chunks; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _lowest_non_clean[i][j] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
472 _last_LNC_resizing_collection[i] = cur_collection;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // In any case, now do the initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
476 lowest_non_clean = _lowest_non_clean[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
477 lowest_non_clean_base_chunk_index = _lowest_non_clean_base_chunk_index[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
478 lowest_non_clean_chunk_size = _lowest_non_clean_chunk_size[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }