annotate src/share/vm/memory/blockOffsetTable.cpp @ 1994:6cd6d394f280

7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed()) 7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages. Reviewed-by: johnc, tonyp
author ysr
date Tue, 07 Dec 2010 21:55:53 -0800
parents f95d63e2154a
children 7d64aa23eb96
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
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);
a61af66fc99e Initial load
duke
parents:
diff changeset
544 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
545 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
546 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 assert(offset < N_words, "offset too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
549 index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
550 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 HeapWord* n = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 while (n <= addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 debug_only(HeapWord* last = q); // for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
555 q = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 n += _sp->block_size(n);
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
557 assert(n > q, err_msg("Looping at: " INTPTR_FORMAT, n));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1552
diff changeset
559 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
560 assert(addr <= n, err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", addr, n));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful(
a61af66fc99e Initial load
duke
parents:
diff changeset
565 const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
569 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // Must read this exactly once because it can be modified by parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 HeapWord* ub = _unallocated_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 assert(ub < _end, "tautology (see above)");
a61af66fc99e Initial load
duke
parents:
diff changeset
575 return ub;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // Otherwise, find the block start using the table, but taking
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // care (cf block_start_unsafe() above) not to parse any objects/blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // on the cards themsleves.
a61af66fc99e Initial load
duke
parents:
diff changeset
581 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 assert(_array->address_for_index(index) == addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
583 "arg should be start of card");
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 HeapWord* q = (HeapWord*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
586 uint offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
587 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
589 if (offset < N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 q -= (n_cards_back * N_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596 } while (offset >= N_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 assert(q <= addr, "block start should be to left of arg");
a61af66fc99e Initial load
duke
parents:
diff changeset
598 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // Verification & debugging - ensure that the offset table reflects the fact
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // that the block [blk_start, blk_end) or [blk, blk + size) is a
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // single block of storage. NOTE: can't const this because of
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // call to non-const do_block_internal() below.
a61af66fc99e Initial load
duke
parents:
diff changeset
606 void BlockOffsetArrayNonContigSpace::verify_single_block(
a61af66fc99e Initial load
duke
parents:
diff changeset
607 HeapWord* blk_start, HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if (VerifyBlockOffsetArray) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 do_block_internal(blk_start, blk_end, Action_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 void BlockOffsetArrayNonContigSpace::verify_single_block(
a61af66fc99e Initial load
duke
parents:
diff changeset
614 HeapWord* blk, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 verify_single_block(blk, blk + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // Verify that the given block is before _unallocated_block
a61af66fc99e Initial load
duke
parents:
diff changeset
619 void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
a61af66fc99e Initial load
duke
parents:
diff changeset
620 HeapWord* blk_start, HeapWord* blk_end) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 if (BlockOffsetArrayUseUnallocatedBlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 assert(blk_start < blk_end, "Block inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
623 assert(blk_end <= _unallocated_block, "_unallocated_block problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
a61af66fc99e Initial load
duke
parents:
diff changeset
628 HeapWord* blk, size_t size) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 verify_not_unallocated(blk, blk + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 size_t BlockOffsetArrayNonContigSpace::last_active_index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
634 if (_unallocated_block == _bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 return _array->index_for(_unallocated_block - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // BlockOffsetArrayContigSpace
a61af66fc99e Initial load
duke
parents:
diff changeset
643 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 HeapWord* BlockOffsetArrayContigSpace::block_start_unsafe(const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
646 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // Otherwise, find the block start using the table.
a61af66fc99e Initial load
duke
parents:
diff changeset
649 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
650 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
651 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // We must make sure that the offset table entry we use is valid. If
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // "addr" is past the end, start at the last known one and go forward.
a61af66fc99e Initial load
duke
parents:
diff changeset
654 index = MIN2(index, _next_offset_index-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
655 HeapWord* q = _array->address_for_index(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 uint offset = _array->offset_array(index); // Extend u_char to uint.
a61af66fc99e Initial load
duke
parents:
diff changeset
658 while (offset > N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // The excess of the offset from N_words indicates a power of Base
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // to go back by.
a61af66fc99e Initial load
duke
parents:
diff changeset
661 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 q -= (N_words * n_cards_back);
a61af66fc99e Initial load
duke
parents:
diff changeset
663 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
664 index -= n_cards_back;
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 while (offset == N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
668 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
669 q -= N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
671 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
673 assert(offset < N_words, "offset too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
674 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
675 HeapWord* n = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 while (n <= addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 debug_only(HeapWord* last = q); // for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
679 q = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 n += _sp->block_size(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
682 assert(q <= addr, "wrong order for current and arg");
a61af66fc99e Initial load
duke
parents:
diff changeset
683 assert(addr <= n, "wrong order for arg and next");
a61af66fc99e Initial load
duke
parents:
diff changeset
684 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 //
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // _next_offset_threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // | _next_offset_index
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // +-------+-------+-------+-------+-------+
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // | i-1 | i | i+1 | i+2 | i+3 |
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // +-------+-------+-------+-------+-------+
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // ( ^ ]
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // block-start
a61af66fc99e Initial load
duke
parents:
diff changeset
696 //
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
699 HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 assert(blk_start != NULL && blk_end > blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
701 "phantom block");
a61af66fc99e Initial load
duke
parents:
diff changeset
702 assert(blk_end > _next_offset_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
703 "should be past threshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
704 assert(blk_start <= _next_offset_threshold,
1489
cff162798819 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 342
diff changeset
705 "blk_start should be at or before threshold");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
706 assert(pointer_delta(_next_offset_threshold, blk_start) <= N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
707 "offset should be <= BlockOffsetSharedArray::N");
a61af66fc99e Initial load
duke
parents:
diff changeset
708 assert(Universe::heap()->is_in_reserved(blk_start),
a61af66fc99e Initial load
duke
parents:
diff changeset
709 "reference must be into the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 assert(Universe::heap()->is_in_reserved(blk_end-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
711 "limit must be within the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
712 assert(_next_offset_threshold ==
a61af66fc99e Initial load
duke
parents:
diff changeset
713 _array->_reserved.start() + _next_offset_index*N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
714 "index must agree with threshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 debug_only(size_t orig_next_offset_index = _next_offset_index;)
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // Mark the card that holds the offset into the block. Note
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // that _next_offset_index and _next_offset_threshold are not
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // updated until the end of this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
721 _array->set_offset_array(_next_offset_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
722 _next_offset_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
723 blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // We need to now mark the subsequent cards that this blk spans.
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // Index of card on which blk ends.
a61af66fc99e Initial load
duke
parents:
diff changeset
728 size_t end_index = _array->index_for(blk_end - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // Are there more cards left to be updated?
a61af66fc99e Initial load
duke
parents:
diff changeset
731 if (_next_offset_index + 1 <= end_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 HeapWord* rem_st = _array->address_for_index(_next_offset_index + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // Calculate rem_end this way because end_index
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // may be the last valid index in the covered region.
a61af66fc99e Initial load
duke
parents:
diff changeset
735 HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
736 set_remainder_to_point_to_start(rem_st, rem_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // _next_offset_index and _next_offset_threshold updated here.
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _next_offset_index = end_index + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // Calculate _next_offset_threshold this way because end_index
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // 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
743 _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
744 assert(_next_offset_threshold >= blk_end, "Incorrect offset threshold");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // The offset can be 0 if the block starts on a boundary. That
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // is checked by an assertion above.
a61af66fc99e Initial load
duke
parents:
diff changeset
749 size_t start_index = _array->index_for(blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
750 HeapWord* boundary = _array->address_for_index(start_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 assert((_array->offset_array(orig_next_offset_index) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
752 blk_start == boundary) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
753 (_array->offset_array(orig_next_offset_index) > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
754 _array->offset_array(orig_next_offset_index) <= N_words),
a61af66fc99e Initial load
duke
parents:
diff changeset
755 "offset array should have been set");
a61af66fc99e Initial load
duke
parents:
diff changeset
756 for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 assert(_array->offset_array(j) > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
758 _array->offset_array(j) <= (u_char) (N_words+N_powers-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
759 "offset array should have been set");
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 HeapWord* BlockOffsetArrayContigSpace::initialize_threshold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
a61af66fc99e Initial load
duke
parents:
diff changeset
766 "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
767 _next_offset_index = _array->index_for(_bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
768 _next_offset_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
769 _next_offset_threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
770 _array->address_for_index(_next_offset_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 return _next_offset_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
773
a61af66fc99e Initial load
duke
parents:
diff changeset
774 void BlockOffsetArrayContigSpace::zero_bottom_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
a61af66fc99e Initial load
duke
parents:
diff changeset
776 "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
777 size_t bottom_index = _array->index_for(_bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 _array->set_offset_array(bottom_index, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 void BlockOffsetArrayContigSpace::serialize(SerializeOopClosure* soc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (soc->reading()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // Null these values so that the serializer won't object to updating them.
a61af66fc99e Initial load
duke
parents:
diff changeset
785 _next_offset_threshold = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
786 _next_offset_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
788 soc->do_ptr(&_next_offset_threshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 soc->do_size_t(&_next_offset_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
791
a61af66fc99e Initial load
duke
parents:
diff changeset
792 size_t BlockOffsetArrayContigSpace::last_active_index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 size_t result = _next_offset_index - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
794 return result >= 0 ? result : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }