annotate src/share/vm/memory/blockOffsetTable.cpp @ 3772:6747fd0512e0

7004681: G1: Extend marking verification to Full GCs Summary: Perform a heap verification after the first phase of G1's full GC using objects' mark words to determine liveness. The third parameter of the heap verification routines, which was used in G1 to determine which marking bitmap to use in liveness calculations, has been changed from a boolean to an enum with values defined for using the mark word, and the 'prev' and 'next' bitmaps. Reviewed-by: tonyp, ysr
author johnc
date Tue, 14 Jun 2011 11:01:10 -0700
parents 537a4053b0f9
children d2a62e0f25eb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
3746
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
2 * Copyright (c) 2000, 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: 1489
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1489
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: 1489
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: 1716
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
26 #include "gc_interface/collectedHeap.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
27 #include "memory/blockOffsetTable.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
28 #include "memory/iterator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
29 #include "memory/space.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
30 #include "memory/universe.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
31 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1716
diff changeset
32 #include "runtime/java.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // BlockOffsetSharedArray
a61af66fc99e Initial load
duke
parents:
diff changeset
36 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 BlockOffsetSharedArray::BlockOffsetSharedArray(MemRegion reserved,
a61af66fc99e Initial load
duke
parents:
diff changeset
39 size_t init_word_size):
a61af66fc99e Initial load
duke
parents:
diff changeset
40 _reserved(reserved), _end(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
41 {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 size_t size = compute_size(reserved.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
43 ReservedSpace rs(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
44 if (!rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
45 vm_exit_during_initialization("Could not reserve enough space for heap offset array");
a61af66fc99e Initial load
duke
parents:
diff changeset
46 }
a61af66fc99e Initial load
duke
parents:
diff changeset
47 if (!_vs.initialize(rs, 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 vm_exit_during_initialization("Could not reserve enough space for heap offset array");
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _offset_array = (u_char*)_vs.low_boundary();
a61af66fc99e Initial load
duke
parents:
diff changeset
51 resize(init_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 if (TraceBlockOffsetTable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 gclog_or_tty->print_cr("BlockOffsetSharedArray::BlockOffsetSharedArray: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
54 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
55 " rs.base(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
56 " rs.size(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
57 " rs end(): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
58 rs.base(), rs.size(), rs.base() + rs.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
59 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
60 " _vs.low_boundary(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
61 " _vs.high_boundary(): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _vs.low_boundary(),
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _vs.high_boundary());
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 void BlockOffsetSharedArray::resize(size_t new_word_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 assert(new_word_size <= _reserved.word_size(), "Resize larger than reserved");
a61af66fc99e Initial load
duke
parents:
diff changeset
69 size_t new_size = compute_size(new_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
70 size_t old_size = _vs.committed_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
71 size_t delta;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 char* high = _vs.high();
a61af66fc99e Initial load
duke
parents:
diff changeset
73 _end = _reserved.start() + new_word_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 if (new_size > old_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 delta = ReservedSpace::page_align_size_up(new_size - old_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 assert(delta > 0, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
77 if (!_vs.expand_by(delta)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // Do better than this for Merlin
a61af66fc99e Initial load
duke
parents:
diff changeset
79 vm_exit_out_of_memory(delta, "offset table expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81 assert(_vs.high() == high + delta, "invalid expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
82 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 delta = ReservedSpace::page_align_size_down(old_size - new_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (delta == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 _vs.shrink_by(delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 assert(_vs.high() == high - delta, "invalid expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 bool BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 assert(p >= _reserved.start(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
92 size_t delta = pointer_delta(p, _reserved.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
93 return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void BlockOffsetSharedArray::serialize(SerializeOopClosure* soc,
a61af66fc99e Initial load
duke
parents:
diff changeset
98 HeapWord* start, HeapWord* end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 assert(_offset_array[0] == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert(start <= end, "bad address range");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 size_t start_index = index_for(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 size_t end_index = index_for(end-1)+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 soc->do_region(&_offset_array[start_index],
a61af66fc99e Initial load
duke
parents:
diff changeset
104 (end_index - start_index) * sizeof(_offset_array[0]));
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // BlockOffsetArray
a61af66fc99e Initial load
duke
parents:
diff changeset
109 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 BlockOffsetArray::BlockOffsetArray(BlockOffsetSharedArray* array,
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
112 MemRegion mr, bool init_to_zero_) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
113 BlockOffsetTable(mr.start(), mr.end()),
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
114 _array(array)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
115 {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 assert(_bottom <= _end, "arguments out of order");
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
117 set_init_to_zero(init_to_zero_);
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
118 if (!init_to_zero_) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // initialize cards to point back to mr.start()
a61af66fc99e Initial load
duke
parents:
diff changeset
120 set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
121 _array->set_offset_array(0, 0); // set first card to 0
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // The arguments follow the normal convention of denoting
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // a right-open interval: [start, end)
a61af66fc99e Initial load
duke
parents:
diff changeset
128 void
a61af66fc99e Initial load
duke
parents:
diff changeset
129 BlockOffsetArray::
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
130 set_remainder_to_point_to_start(HeapWord* start, HeapWord* end, bool reducing) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
131
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
132 check_reducing_assertion(reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
133 if (start >= end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // The start address is equal to the end address (or to
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // the right of the end address) so there are not cards
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // that need to be updated..
a61af66fc99e Initial load
duke
parents:
diff changeset
137 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // Write the backskip value for each region.
a61af66fc99e Initial load
duke
parents:
diff changeset
141 //
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // offset
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // card 2nd 3rd
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // | +- 1st | |
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // v v v v
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // |x|0|0|0|0|0|0|0|1|1|1|1|1|1| ... |1|1|1|1|2|2|2|2|2|2| ...
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // 11 19 75
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // 12
a61af66fc99e Initial load
duke
parents:
diff changeset
151 //
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // offset card is the card that points to the start of an object
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // x - offset value of offset card
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // 1st - start of first logarithmic region
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // 0 corresponds to logarithmic value N_words + 0 and 2**(3 * 0) = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // 2nd - start of second logarithmic region
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // 1 corresponds to logarithmic value N_words + 1 and 2**(3 * 1) = 8
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // 3rd - start of third logarithmic region
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // 2 corresponds to logarithmic value N_words + 2 and 2**(3 * 2) = 64
a61af66fc99e Initial load
duke
parents:
diff changeset
160 //
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // integer below the block offset entry is an example of
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // the index of the entry
a61af66fc99e Initial load
duke
parents:
diff changeset
163 //
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Given an address,
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Find the index for the address
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Find the block offset table entry
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // Convert the entry to a back slide
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // (e.g., with today's, offset = 0x81 =>
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // back slip = 2**(3*(0x81 - N_words)) = 2**3) = 8
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Move back N (e.g., 8) entries and repeat with the
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // value of the new entry
a61af66fc99e Initial load
duke
parents:
diff changeset
172 //
a61af66fc99e Initial load
duke
parents:
diff changeset
173 size_t start_card = _array->index_for(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 size_t end_card = _array->index_for(end-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 assert(start ==_array->address_for_index(start_card), "Precondition");
a61af66fc99e Initial load
duke
parents:
diff changeset
176 assert(end ==_array->address_for_index(end_card)+N_words, "Precondition");
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
177 set_remainder_to_point_to_start_incl(start_card, end_card, reducing); // closed interval
0
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Unlike the normal convention in this code, the argument here denotes
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // a closed, inclusive interval: [start_card, end_card], cf set_remainder_to_point_to_start()
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // above.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 void
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
185 BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t end_card, bool reducing) {
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
186
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
187 check_reducing_assertion(reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if (start_card > end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(start_card > _array->index_for(_bottom), "Cannot be first card");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 assert(_array->offset_array(start_card-1) <= N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
193 "Offset card has an unexpected value");
a61af66fc99e Initial load
duke
parents:
diff changeset
194 size_t start_card_for_region = start_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 u_char offset = max_jubyte;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
196 for (int i = 0; i < N_powers; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // -1 so that the the card with the actual offset is counted. Another -1
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // so that the reach ends in this region and not at the start
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // of the next.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 size_t reach = start_card - 1 + (power_to_cards_back(i+1) - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 offset = N_words + i;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if (reach >= end_card) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
203 _array->set_offset_array(start_card_for_region, end_card, offset, reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
204 start_card_for_region = reach + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
207 _array->set_offset_array(start_card_for_region, reach, offset, reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
208 start_card_for_region = reach + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210 assert(start_card_for_region > end_card, "Sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
211 DEBUG_ONLY(check_all_cards(start_card, end_card);)
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // The card-interval [start_card, end_card] is a closed interval; this
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // is an expensive check -- use with care and only under protection of
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // suitable flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
217 void BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (end_card < start_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222 guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
223 u_char last_entry = N_words;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
224 for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 u_char entry = _array->offset_array(c);
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
226 guarantee(entry >= last_entry, "Monotonicity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if (c - start_card > power_to_cards_back(1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 guarantee(entry > N_words, "Should be in logarithmic region");
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 size_t backskip = entry_to_cards_back(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 size_t landing_card = c - backskip;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 guarantee(landing_card >= (start_card - 1), "Inv");
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (landing_card >= start_card) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
234 guarantee(_array->offset_array(landing_card) <= entry, "Monotonicity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235 } else {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
236 guarantee(landing_card == (start_card - 1), "Tautology");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
237 // Note that N_words is the maximum offset value
0
a61af66fc99e Initial load
duke
parents:
diff changeset
238 guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
240 last_entry = entry; // remember for monotonicity test
0
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 void
a61af66fc99e Initial load
duke
parents:
diff changeset
246 BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 assert(blk_start != NULL && blk_end > blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
248 "phantom block");
a61af66fc99e Initial load
duke
parents:
diff changeset
249 single_block(blk_start, blk_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Action_mark - update the BOT for the block [blk_start, blk_end).
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Current typical use is for splitting a block.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Action_single - udpate the BOT for an allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Action_verify - BOT verification.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 void
a61af66fc99e Initial load
duke
parents:
diff changeset
257 BlockOffsetArray::do_block_internal(HeapWord* blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
258 HeapWord* blk_end,
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
259 Action action, bool reducing) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
260 assert(Universe::heap()->is_in_reserved(blk_start),
a61af66fc99e Initial load
duke
parents:
diff changeset
261 "reference must be into the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
262 assert(Universe::heap()->is_in_reserved(blk_end-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
263 "limit must be within the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // This is optimized to make the test fast, assuming we only rarely
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // cross boundaries.
a61af66fc99e Initial load
duke
parents:
diff changeset
266 uintptr_t end_ui = (uintptr_t)(blk_end - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 uintptr_t start_ui = (uintptr_t)blk_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // Calculate the last card boundary preceding end of blk
a61af66fc99e Initial load
duke
parents:
diff changeset
269 intptr_t boundary_before_end = (intptr_t)end_ui;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 clear_bits(boundary_before_end, right_n_bits(LogN));
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (start_ui <= (uintptr_t)boundary_before_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // blk starts at or crosses a boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // Calculate index of card on which blk begins
a61af66fc99e Initial load
duke
parents:
diff changeset
274 size_t start_index = _array->index_for(blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // Index of card on which blk ends
a61af66fc99e Initial load
duke
parents:
diff changeset
276 size_t end_index = _array->index_for(blk_end - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Start address of card on which blk begins
a61af66fc99e Initial load
duke
parents:
diff changeset
278 HeapWord* boundary = _array->address_for_index(start_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 assert(boundary <= blk_start, "blk should start at or after boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (blk_start != boundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // blk starts strictly after boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // adjust card boundary and start_index forward to next card
a61af66fc99e Initial load
duke
parents:
diff changeset
283 boundary += N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 start_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 assert(start_index <= end_index, "monotonicity of index_for()");
a61af66fc99e Initial load
duke
parents:
diff changeset
287 assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
288 switch (action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 case Action_mark: {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 if (init_to_zero()) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
291 _array->set_offset_array(start_index, boundary, blk_start, reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
292 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 } // Else fall through to the next case
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 case Action_single: {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
296 _array->set_offset_array(start_index, boundary, blk_start, reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // We have finished marking the "offset card". We need to now
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // mark the subsequent cards that this blk spans.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 if (start_index < end_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
302 set_remainder_to_point_to_start(rem_st, rem_end, reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
304 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306 case Action_check: {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 _array->check_offset_array(start_index, boundary, blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // We have finished checking the "offset card". We need to now
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // check the subsequent cards that this blk spans.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 check_all_cards(start_index + 1, end_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
314 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // The range [blk_start, blk_end) represents a single contiguous block
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // of storage; modify the block offset table to represent this
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // information; Right-open interval: [blk_start, blk_end)
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // NOTE: this method does _not_ adjust _unallocated_block.
a61af66fc99e Initial load
duke
parents:
diff changeset
323 void
a61af66fc99e Initial load
duke
parents:
diff changeset
324 BlockOffsetArray::single_block(HeapWord* blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
325 HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 do_block_internal(blk_start, blk_end, Action_single);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 void BlockOffsetArray::verify() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // For each entry in the block offset table, verify that
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // the entry correctly finds the start of an object at the
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // first address covered by the block or to the left of that
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // first address.
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 size_t next_index = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
336 size_t last_index = last_active_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Use for debugging. Initialize to NULL to distinguish the
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // first iteration through the while loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
340 HeapWord* last_p = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 HeapWord* last_start = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 oop last_o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 while (next_index <= last_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // Use an address past the start of the address for
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // the entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
347 HeapWord* p = _array->address_for_index(next_index) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 if (p >= _end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // That's all of the allocated block table.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // block_start() asserts that start <= p.
a61af66fc99e Initial load
duke
parents:
diff changeset
353 HeapWord* start = block_start(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // First check if the start is an allocated block and only
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // then if it is a valid object.
a61af66fc99e Initial load
duke
parents:
diff changeset
356 oop o = oop(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
357 assert(!Universe::is_fully_initialized() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
358 _sp->is_free_block(start) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
359 o->is_oop_or_null(), "Bad object was found");
a61af66fc99e Initial load
duke
parents:
diff changeset
360 next_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 last_p = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 last_start = start;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 last_o = o;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // BlockOffsetArrayNonContigSpace
a61af66fc99e Initial load
duke
parents:
diff changeset
369 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // The block [blk_start, blk_end) has been allocated;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // adjust the block offset table to represent this information;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // NOTE: Clients of BlockOffsetArrayNonContigSpace: consider using
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // the somewhat more lightweight split_block() or
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // (when init_to_zero()) mark_block() wherever possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // right-open interval: [blk_start, blk_end)
a61af66fc99e Initial load
duke
parents:
diff changeset
377 void
a61af66fc99e Initial load
duke
parents:
diff changeset
378 BlockOffsetArrayNonContigSpace::alloc_block(HeapWord* blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
379 HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 assert(blk_start != NULL && blk_end > blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
381 "phantom block");
a61af66fc99e Initial load
duke
parents:
diff changeset
382 single_block(blk_start, blk_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 allocated(blk_start, blk_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Adjust BOT to show that a previously whole block has been split
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // into two. We verify the BOT for the first part (prefix) and
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // update the BOT for the second part (suffix).
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // blk is the start of the block
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // blk_size is the size of the original block
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // left_blk_size is the size of the first part of the split
a61af66fc99e Initial load
duke
parents:
diff changeset
392 void BlockOffsetArrayNonContigSpace::split_block(HeapWord* blk,
a61af66fc99e Initial load
duke
parents:
diff changeset
393 size_t blk_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
394 size_t left_blk_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // Verify that the BOT shows [blk, blk + blk_size) to be one block.
a61af66fc99e Initial load
duke
parents:
diff changeset
396 verify_single_block(blk, blk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // is one single block.
a61af66fc99e Initial load
duke
parents:
diff changeset
399 assert(blk_size > 0, "Should be positive");
a61af66fc99e Initial load
duke
parents:
diff changeset
400 assert(left_blk_size > 0, "Should be positive");
a61af66fc99e Initial load
duke
parents:
diff changeset
401 assert(left_blk_size < blk_size, "Not a split");
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // Start addresses of prefix block and suffix block.
a61af66fc99e Initial load
duke
parents:
diff changeset
404 HeapWord* pref_addr = blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 HeapWord* suff_addr = blk + left_blk_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 HeapWord* end_addr = blk + blk_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Indices for starts of prefix block and suffix block.
a61af66fc99e Initial load
duke
parents:
diff changeset
409 size_t pref_index = _array->index_for(pref_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 if (_array->address_for_index(pref_index) != pref_addr) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
411 // pref_addr does not begin pref_index
0
a61af66fc99e Initial load
duke
parents:
diff changeset
412 pref_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 size_t suff_index = _array->index_for(suff_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 if (_array->address_for_index(suff_index) != suff_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // suff_addr does not begin suff_index
a61af66fc99e Initial load
duke
parents:
diff changeset
418 suff_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Definition: A block B, denoted [B_start, B_end) __starts__
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // a card C, denoted [C_start, C_end), where C_start and C_end
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // are the heap addresses that card C covers, iff
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // B_start <= C_start < B_end.
a61af66fc99e Initial load
duke
parents:
diff changeset
425 //
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // We say that a card C "is started by" a block B, iff
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // B "starts" C.
a61af66fc99e Initial load
duke
parents:
diff changeset
428 //
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // Note that the cardinality of the set of cards {C}
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // started by a block B can be 0, 1, or more.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 //
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // Below, pref_index and suff_index are, respectively, the
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // first (least) card indices that the prefix and suffix of
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // the split start; end_index is one more than the index of
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // the last (greatest) card that blk starts.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 size_t end_index = _array->index_for(end_addr - 1) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // Calculate the # cards that the prefix and suffix affect.
a61af66fc99e Initial load
duke
parents:
diff changeset
439 size_t num_pref_cards = suff_index - pref_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 size_t num_suff_cards = end_index - suff_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // Change the cards that need changing
a61af66fc99e Initial load
duke
parents:
diff changeset
443 if (num_suff_cards > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 HeapWord* boundary = _array->address_for_index(suff_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // Set the offset card for suffix block
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
446 _array->set_offset_array(suff_index, boundary, suff_addr, true /* reducing */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // Change any further cards that need changing in the suffix
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (num_pref_cards > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 if (num_pref_cards >= num_suff_cards) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Unilaterally fix all of the suffix cards: closed card
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // index interval in args below.
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
452 set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
453 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // Unilaterally fix the first (num_pref_cards - 1) following
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // the "offset card" in the suffix block.
a61af66fc99e Initial load
duke
parents:
diff changeset
456 set_remainder_to_point_to_start_incl(suff_index + 1,
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
457 suff_index + num_pref_cards - 1, true /* reducing */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // Fix the appropriate cards in the remainder of the
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // suffix block -- these are the last num_pref_cards
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // cards in each power block of the "new" range plumbed
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // from suff_addr.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 bool more = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 uint i = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 while (more && (i < N_powers)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 size_t back_by = power_to_cards_back(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
466 size_t right_index = suff_index + back_by - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
467 size_t left_index = right_index - num_pref_cards + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
468 if (right_index >= end_index - 1) { // last iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
469 right_index = end_index - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 more = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (back_by > num_pref_cards) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // Fill in the remainder of this "power block", if it
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // is non-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if (left_index <= right_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 _array->set_offset_array(left_index, right_index,
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
477 N_words + i - 1, true /* reducing */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
478 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 more = false; // we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 while (more && (i < N_powers)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 size_t back_by = power_to_cards_back(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
488 size_t right_index = suff_index + back_by - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 size_t left_index = right_index - num_pref_cards + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (right_index >= end_index - 1) { // last iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
491 right_index = end_index - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 if (left_index > right_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495 more = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 assert(left_index <= right_index, "Error");
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
498 _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
499 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502 } // else no more cards to fix in suffix
a61af66fc99e Initial load
duke
parents:
diff changeset
503 } // else nothing needs to be done
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Verify that we did the right thing
a61af66fc99e Initial load
duke
parents:
diff changeset
505 verify_single_block(pref_addr, left_blk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 verify_single_block(suff_addr, blk_size - left_blk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // Mark the BOT such that if [blk_start, blk_end) straddles a card
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // boundary, the card following the first such boundary is marked
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // with the appropriate offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // NOTE: this method does _not_ adjust _unallocated_block or
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // any cards subsequent to the first one.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 void
a61af66fc99e Initial load
duke
parents:
diff changeset
516 BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start,
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
517 HeapWord* blk_end, bool reducing) {
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
518 do_block_internal(blk_start, blk_end, Action_mark, reducing);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe(
a61af66fc99e Initial load
duke
parents:
diff changeset
522 const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
523 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
524 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
525 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // Must read this exactly once because it can be modified by parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 HeapWord* ub = _unallocated_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 assert(ub < _end, "tautology (see above)");
a61af66fc99e Initial load
duke
parents:
diff changeset
531 return ub;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // Otherwise, find the block start using the table.
a61af66fc99e Initial load
duke
parents:
diff changeset
535 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
536 HeapWord* q = _array->address_for_index(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 uint offset = _array->offset_array(index); // Extend u_char to uint.
a61af66fc99e Initial load
duke
parents:
diff changeset
539 while (offset >= N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // The excess of the offset from N_words indicates a power of Base
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // to go back by.
a61af66fc99e Initial load
duke
parents:
diff changeset
542 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 q -= (N_words * n_cards_back);
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
544 assert(q >= _sp->bottom(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
545 err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
546 q, _sp->bottom()));
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
547 assert(q < _sp->end(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
548 err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
549 q, _sp->end()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
550 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553 assert(offset < N_words, "offset too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
554 index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
555 q -= offset;
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
556 assert(q >= _sp->bottom(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
557 err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
558 q, _sp->bottom()));
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
559 assert(q < _sp->end(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
560 err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
561 q, _sp->end()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
562 HeapWord* n = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 while (n <= addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 debug_only(HeapWord* last = q); // for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
566 q = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 n += _sp->block_size(n);
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
568 assert(n > q,
3746
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
569 err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT","
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
570 " while querying blk_start(" PTR_FORMAT ")"
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
571 " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")",
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
572 n, last, addr, _sp->bottom(), _sp->end()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
573 }
3746
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
574 assert(q <= addr,
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
575 err_msg("wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")",
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
576 q, addr));
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
577 assert(addr <= n,
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
578 err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")",
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
579 addr, n));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
580 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful(
a61af66fc99e Initial load
duke
parents:
diff changeset
584 const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
588 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // Must read this exactly once because it can be modified by parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
591 HeapWord* ub = _unallocated_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
592 if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 assert(ub < _end, "tautology (see above)");
a61af66fc99e Initial load
duke
parents:
diff changeset
594 return ub;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Otherwise, find the block start using the table, but taking
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // care (cf block_start_unsafe() above) not to parse any objects/blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // on the cards themsleves.
a61af66fc99e Initial load
duke
parents:
diff changeset
600 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 assert(_array->address_for_index(index) == addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
602 "arg should be start of card");
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 HeapWord* q = (HeapWord*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 uint offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if (offset < N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
610 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
612 q -= (n_cards_back * N_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
613 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
615 } while (offset >= N_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
616 assert(q <= addr, "block start should be to left of arg");
a61af66fc99e Initial load
duke
parents:
diff changeset
617 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // Verification & debugging - ensure that the offset table reflects the fact
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // that the block [blk_start, blk_end) or [blk, blk + size) is a
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // single block of storage. NOTE: can't const this because of
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // call to non-const do_block_internal() below.
a61af66fc99e Initial load
duke
parents:
diff changeset
625 void BlockOffsetArrayNonContigSpace::verify_single_block(
a61af66fc99e Initial load
duke
parents:
diff changeset
626 HeapWord* blk_start, HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (VerifyBlockOffsetArray) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 do_block_internal(blk_start, blk_end, Action_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 void BlockOffsetArrayNonContigSpace::verify_single_block(
a61af66fc99e Initial load
duke
parents:
diff changeset
633 HeapWord* blk, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
634 verify_single_block(blk, blk + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // Verify that the given block is before _unallocated_block
a61af66fc99e Initial load
duke
parents:
diff changeset
638 void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
a61af66fc99e Initial load
duke
parents:
diff changeset
639 HeapWord* blk_start, HeapWord* blk_end) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 if (BlockOffsetArrayUseUnallocatedBlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 assert(blk_start < blk_end, "Block inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
642 assert(blk_end <= _unallocated_block, "_unallocated_block problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
a61af66fc99e Initial load
duke
parents:
diff changeset
647 HeapWord* blk, size_t size) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 verify_not_unallocated(blk, blk + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 size_t BlockOffsetArrayNonContigSpace::last_active_index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 if (_unallocated_block == _bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
654 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 return _array->index_for(_unallocated_block - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // BlockOffsetArrayContigSpace
a61af66fc99e Initial load
duke
parents:
diff changeset
662 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 HeapWord* BlockOffsetArrayContigSpace::block_start_unsafe(const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
665 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Otherwise, find the block start using the table.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
669 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // We must make sure that the offset table entry we use is valid. If
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // "addr" is past the end, start at the last known one and go forward.
a61af66fc99e Initial load
duke
parents:
diff changeset
673 index = MIN2(index, _next_offset_index-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 HeapWord* q = _array->address_for_index(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
675
a61af66fc99e Initial load
duke
parents:
diff changeset
676 uint offset = _array->offset_array(index); // Extend u_char to uint.
a61af66fc99e Initial load
duke
parents:
diff changeset
677 while (offset > N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // The excess of the offset from N_words indicates a power of Base
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // to go back by.
a61af66fc99e Initial load
duke
parents:
diff changeset
680 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 q -= (N_words * n_cards_back);
a61af66fc99e Initial load
duke
parents:
diff changeset
682 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
683 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
684 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 while (offset == N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
688 q -= N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
690 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692 assert(offset < N_words, "offset too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
693 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 HeapWord* n = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 while (n <= addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 debug_only(HeapWord* last = q); // for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
698 q = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
699 n += _sp->block_size(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701 assert(q <= addr, "wrong order for current and arg");
a61af66fc99e Initial load
duke
parents:
diff changeset
702 assert(addr <= n, "wrong order for arg and next");
a61af66fc99e Initial load
duke
parents:
diff changeset
703 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 //
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // _next_offset_threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // | _next_offset_index
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // +-------+-------+-------+-------+-------+
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // | i-1 | i | i+1 | i+2 | i+3 |
a61af66fc99e Initial load
duke
parents:
diff changeset
712 // +-------+-------+-------+-------+-------+
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // ( ^ ]
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // block-start
a61af66fc99e Initial load
duke
parents:
diff changeset
715 //
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
718 HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 assert(blk_start != NULL && blk_end > blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
720 "phantom block");
a61af66fc99e Initial load
duke
parents:
diff changeset
721 assert(blk_end > _next_offset_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
722 "should be past threshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
723 assert(blk_start <= _next_offset_threshold,
1489
cff162798819 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 342
diff changeset
724 "blk_start should be at or before threshold");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
725 assert(pointer_delta(_next_offset_threshold, blk_start) <= N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
726 "offset should be <= BlockOffsetSharedArray::N");
a61af66fc99e Initial load
duke
parents:
diff changeset
727 assert(Universe::heap()->is_in_reserved(blk_start),
a61af66fc99e Initial load
duke
parents:
diff changeset
728 "reference must be into the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
729 assert(Universe::heap()->is_in_reserved(blk_end-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
730 "limit must be within the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
731 assert(_next_offset_threshold ==
a61af66fc99e Initial load
duke
parents:
diff changeset
732 _array->_reserved.start() + _next_offset_index*N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
733 "index must agree with threshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 debug_only(size_t orig_next_offset_index = _next_offset_index;)
a61af66fc99e Initial load
duke
parents:
diff changeset
736
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // Mark the card that holds the offset into the block. Note
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // that _next_offset_index and _next_offset_threshold are not
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // updated until the end of this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _array->set_offset_array(_next_offset_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
741 _next_offset_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
742 blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // We need to now mark the subsequent cards that this blk spans.
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // Index of card on which blk ends.
a61af66fc99e Initial load
duke
parents:
diff changeset
747 size_t end_index = _array->index_for(blk_end - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // Are there more cards left to be updated?
a61af66fc99e Initial load
duke
parents:
diff changeset
750 if (_next_offset_index + 1 <= end_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 HeapWord* rem_st = _array->address_for_index(_next_offset_index + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // Calculate rem_end this way because end_index
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // may be the last valid index in the covered region.
a61af66fc99e Initial load
duke
parents:
diff changeset
754 HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 set_remainder_to_point_to_start(rem_st, rem_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // _next_offset_index and _next_offset_threshold updated here.
a61af66fc99e Initial load
duke
parents:
diff changeset
759 _next_offset_index = end_index + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // Calculate _next_offset_threshold this way because end_index
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // may be the last valid index in the covered region.
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
762 _next_offset_threshold = _array->address_for_index(end_index) + N_words;
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
763 assert(_next_offset_threshold >= blk_end, "Incorrect offset threshold");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // The offset can be 0 if the block starts on a boundary. That
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // is checked by an assertion above.
a61af66fc99e Initial load
duke
parents:
diff changeset
768 size_t start_index = _array->index_for(blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 HeapWord* boundary = _array->address_for_index(start_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
770 assert((_array->offset_array(orig_next_offset_index) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
771 blk_start == boundary) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
772 (_array->offset_array(orig_next_offset_index) > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
773 _array->offset_array(orig_next_offset_index) <= N_words),
a61af66fc99e Initial load
duke
parents:
diff changeset
774 "offset array should have been set");
a61af66fc99e Initial load
duke
parents:
diff changeset
775 for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 assert(_array->offset_array(j) > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
777 _array->offset_array(j) <= (u_char) (N_words+N_powers-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
778 "offset array should have been set");
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 HeapWord* BlockOffsetArrayContigSpace::initialize_threshold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
a61af66fc99e Initial load
duke
parents:
diff changeset
785 "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
786 _next_offset_index = _array->index_for(_bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
787 _next_offset_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 _next_offset_threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
789 _array->address_for_index(_next_offset_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
790 return _next_offset_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 void BlockOffsetArrayContigSpace::zero_bottom_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
794 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
a61af66fc99e Initial load
duke
parents:
diff changeset
795 "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
796 size_t bottom_index = _array->index_for(_bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 _array->set_offset_array(bottom_index, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 void BlockOffsetArrayContigSpace::serialize(SerializeOopClosure* soc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 if (soc->reading()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // Null these values so that the serializer won't object to updating them.
a61af66fc99e Initial load
duke
parents:
diff changeset
804 _next_offset_threshold = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
805 _next_offset_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807 soc->do_ptr(&_next_offset_threshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 soc->do_size_t(&_next_offset_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 size_t BlockOffsetArrayContigSpace::last_active_index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 size_t result = _next_offset_index - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 return result >= 0 ? result : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }