annotate src/share/vm/memory/blockOffsetTable.cpp @ 1716:be3f9c242c9d

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