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

8059758: Footprint regressions with JDK-8038423 Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything. Reviewed-by: jwilhelm, brutisso
author tschatzl
date Fri, 10 Oct 2014 15:51:58 +0200
parents 78bbf4d43a14
children 52b4284cb496
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
2 * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 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"
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 3746
diff changeset
33 #include "services/memTracker.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // BlockOffsetSharedArray
a61af66fc99e Initial load
duke
parents:
diff changeset
37 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 BlockOffsetSharedArray::BlockOffsetSharedArray(MemRegion reserved,
a61af66fc99e Initial load
duke
parents:
diff changeset
40 size_t init_word_size):
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _reserved(reserved), _end(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
42 {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 size_t size = compute_size(reserved.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
44 ReservedSpace rs(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if (!rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 vm_exit_during_initialization("Could not reserve enough space for heap offset array");
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 3746
diff changeset
48
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 3746
diff changeset
49 MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 3746
diff changeset
50
0
a61af66fc99e Initial load
duke
parents:
diff changeset
51 if (!_vs.initialize(rs, 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
52 vm_exit_during_initialization("Could not reserve enough space for heap offset array");
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _offset_array = (u_char*)_vs.low_boundary();
a61af66fc99e Initial load
duke
parents:
diff changeset
55 resize(init_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 if (TraceBlockOffsetTable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 gclog_or_tty->print_cr("BlockOffsetSharedArray::BlockOffsetSharedArray: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
58 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
59 " rs.base(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
60 " rs.size(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
61 " rs end(): " INTPTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
62 p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
63 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
64 " _vs.low_boundary(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
65 " _vs.high_boundary(): " INTPTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
66 p2i(_vs.low_boundary()),
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
67 p2i(_vs.high_boundary()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 void BlockOffsetSharedArray::resize(size_t new_word_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 assert(new_word_size <= _reserved.word_size(), "Resize larger than reserved");
a61af66fc99e Initial load
duke
parents:
diff changeset
73 size_t new_size = compute_size(new_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 size_t old_size = _vs.committed_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 size_t delta;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 char* high = _vs.high();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 _end = _reserved.start() + new_word_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 if (new_size > old_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 delta = ReservedSpace::page_align_size_up(new_size - old_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 assert(delta > 0, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
81 if (!_vs.expand_by(delta)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Do better than this for Merlin
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 6725
diff changeset
83 vm_exit_out_of_memory(delta, OOM_MMAP_ERROR, "offset table expansion");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 assert(_vs.high() == high + delta, "invalid expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
86 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 delta = ReservedSpace::page_align_size_down(old_size - new_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (delta == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 _vs.shrink_by(delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
90 assert(_vs.high() == high - delta, "invalid expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
91 }
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 bool BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 assert(p >= _reserved.start(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
96 size_t delta = pointer_delta(p, _reserved.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
97 return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
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);
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
538 assert(q >= _sp->bottom(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
539 err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
540 p2i(q), p2i(_sp->bottom())));
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
541 assert(q < _sp->end(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
542 err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
543 p2i(q), p2i(_sp->end())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
544 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
547 assert(offset < N_words, "offset too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
548 index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 q -= offset;
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
550 assert(q >= _sp->bottom(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
551 err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
552 p2i(q), p2i(_sp->bottom())));
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
553 assert(q < _sp->end(),
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
554 err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT,
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
555 p2i(q), p2i(_sp->end())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
556 HeapWord* n = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 while (n <= addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 debug_only(HeapWord* last = q); // for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
560 q = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
561 n += _sp->block_size(n);
3359
7d64aa23eb96 7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents: 1972
diff changeset
562 assert(n > q,
3746
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
563 err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT","
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
564 " while querying blk_start(" PTR_FORMAT ")"
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
565 " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")",
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
566 p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
3746
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
568 assert(q <= addr,
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
569 err_msg("wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")",
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
570 p2i(q), p2i(addr)));
3746
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
571 assert(addr <= n,
537a4053b0f9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 3359
diff changeset
572 err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")",
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17467
diff changeset
573 p2i(addr), p2i(n)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
574 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful(
a61af66fc99e Initial load
duke
parents:
diff changeset
578 const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
582 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // Must read this exactly once because it can be modified by parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
585 HeapWord* ub = _unallocated_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
586 if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 assert(ub < _end, "tautology (see above)");
a61af66fc99e Initial load
duke
parents:
diff changeset
588 return ub;
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Otherwise, find the block start using the table, but taking
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // care (cf block_start_unsafe() above) not to parse any objects/blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // on the cards themsleves.
a61af66fc99e Initial load
duke
parents:
diff changeset
594 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
595 assert(_array->address_for_index(index) == addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
596 "arg should be start of card");
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 HeapWord* q = (HeapWord*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 uint offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
600 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 if (offset < N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
603 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
606 q -= (n_cards_back * N_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
609 } while (offset >= N_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 assert(q <= addr, "block start should be to left of arg");
a61af66fc99e Initial load
duke
parents:
diff changeset
611 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // Verification & debugging - ensure that the offset table reflects the fact
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // that the block [blk_start, blk_end) or [blk, blk + size) is a
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // single block of storage. NOTE: can't const this because of
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // call to non-const do_block_internal() below.
a61af66fc99e Initial load
duke
parents:
diff changeset
619 void BlockOffsetArrayNonContigSpace::verify_single_block(
a61af66fc99e Initial load
duke
parents:
diff changeset
620 HeapWord* blk_start, HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 if (VerifyBlockOffsetArray) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 do_block_internal(blk_start, blk_end, Action_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 void BlockOffsetArrayNonContigSpace::verify_single_block(
a61af66fc99e Initial load
duke
parents:
diff changeset
627 HeapWord* blk, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 verify_single_block(blk, blk + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // Verify that the given block is before _unallocated_block
a61af66fc99e Initial load
duke
parents:
diff changeset
632 void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
a61af66fc99e Initial load
duke
parents:
diff changeset
633 HeapWord* blk_start, HeapWord* blk_end) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
634 if (BlockOffsetArrayUseUnallocatedBlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 assert(blk_start < blk_end, "Block inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
636 assert(blk_end <= _unallocated_block, "_unallocated_block problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
a61af66fc99e Initial load
duke
parents:
diff changeset
641 HeapWord* blk, size_t size) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 verify_not_unallocated(blk, blk + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 size_t BlockOffsetArrayNonContigSpace::last_active_index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
647 if (_unallocated_block == _bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
649 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
650 return _array->index_for(_unallocated_block - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // BlockOffsetArrayContigSpace
a61af66fc99e Initial load
duke
parents:
diff changeset
656 //////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
657
a61af66fc99e Initial load
duke
parents:
diff changeset
658 HeapWord* BlockOffsetArrayContigSpace::block_start_unsafe(const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // Otherwise, find the block start using the table.
a61af66fc99e Initial load
duke
parents:
diff changeset
662 assert(_bottom <= addr && addr < _end,
a61af66fc99e Initial load
duke
parents:
diff changeset
663 "addr must be covered by this Array");
a61af66fc99e Initial load
duke
parents:
diff changeset
664 size_t index = _array->index_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // We must make sure that the offset table entry we use is valid. If
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // "addr" is past the end, start at the last known one and go forward.
a61af66fc99e Initial load
duke
parents:
diff changeset
667 index = MIN2(index, _next_offset_index-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
668 HeapWord* q = _array->address_for_index(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
669
a61af66fc99e Initial load
duke
parents:
diff changeset
670 uint offset = _array->offset_array(index); // Extend u_char to uint.
a61af66fc99e Initial load
duke
parents:
diff changeset
671 while (offset > N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // The excess of the offset from N_words indicates a power of Base
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // to go back by.
a61af66fc99e Initial load
duke
parents:
diff changeset
674 size_t n_cards_back = entry_to_cards_back(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 q -= (N_words * n_cards_back);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
677 index -= n_cards_back;
a61af66fc99e Initial load
duke
parents:
diff changeset
678 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
680 while (offset == N_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 assert(q >= _sp->bottom(), "Went below bottom!");
a61af66fc99e Initial load
duke
parents:
diff changeset
682 q -= N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
683 index--;
a61af66fc99e Initial load
duke
parents:
diff changeset
684 offset = _array->offset_array(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 assert(offset < N_words, "offset too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
687 q -= offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
688 HeapWord* n = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690 while (n <= addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
691 debug_only(HeapWord* last = q); // for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
692 q = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 n += _sp->block_size(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695 assert(q <= addr, "wrong order for current and arg");
a61af66fc99e Initial load
duke
parents:
diff changeset
696 assert(addr <= n, "wrong order for arg and next");
a61af66fc99e Initial load
duke
parents:
diff changeset
697 return q;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 //
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // _next_offset_threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // | _next_offset_index
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // v v
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // +-------+-------+-------+-------+-------+
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // | i-1 | i | i+1 | i+2 | i+3 |
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // +-------+-------+-------+-------+-------+
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // ( ^ ]
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // block-start
a61af66fc99e Initial load
duke
parents:
diff changeset
709 //
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
712 HeapWord* blk_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
713 assert(blk_start != NULL && blk_end > blk_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
714 "phantom block");
a61af66fc99e Initial load
duke
parents:
diff changeset
715 assert(blk_end > _next_offset_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
716 "should be past threshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
717 assert(blk_start <= _next_offset_threshold,
1489
cff162798819 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 342
diff changeset
718 "blk_start should be at or before threshold");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
719 assert(pointer_delta(_next_offset_threshold, blk_start) <= N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
720 "offset should be <= BlockOffsetSharedArray::N");
a61af66fc99e Initial load
duke
parents:
diff changeset
721 assert(Universe::heap()->is_in_reserved(blk_start),
a61af66fc99e Initial load
duke
parents:
diff changeset
722 "reference must be into the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
723 assert(Universe::heap()->is_in_reserved(blk_end-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
724 "limit must be within the heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
725 assert(_next_offset_threshold ==
a61af66fc99e Initial load
duke
parents:
diff changeset
726 _array->_reserved.start() + _next_offset_index*N_words,
a61af66fc99e Initial load
duke
parents:
diff changeset
727 "index must agree with threshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 debug_only(size_t orig_next_offset_index = _next_offset_index;)
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // Mark the card that holds the offset into the block. Note
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // that _next_offset_index and _next_offset_threshold are not
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // updated until the end of this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
734 _array->set_offset_array(_next_offset_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
735 _next_offset_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
736 blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // We need to now mark the subsequent cards that this blk spans.
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // Index of card on which blk ends.
a61af66fc99e Initial load
duke
parents:
diff changeset
741 size_t end_index = _array->index_for(blk_end - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // Are there more cards left to be updated?
a61af66fc99e Initial load
duke
parents:
diff changeset
744 if (_next_offset_index + 1 <= end_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
745 HeapWord* rem_st = _array->address_for_index(_next_offset_index + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // Calculate rem_end this way because end_index
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // may be the last valid index in the covered region.
a61af66fc99e Initial load
duke
parents:
diff changeset
748 HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
749 set_remainder_to_point_to_start(rem_st, rem_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // _next_offset_index and _next_offset_threshold updated here.
a61af66fc99e Initial load
duke
parents:
diff changeset
753 _next_offset_index = end_index + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // Calculate _next_offset_threshold this way because end_index
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // 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
756 _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
757 assert(_next_offset_threshold >= blk_end, "Incorrect offset threshold");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // The offset can be 0 if the block starts on a boundary. That
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // is checked by an assertion above.
a61af66fc99e Initial load
duke
parents:
diff changeset
762 size_t start_index = _array->index_for(blk_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 HeapWord* boundary = _array->address_for_index(start_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 assert((_array->offset_array(orig_next_offset_index) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
765 blk_start == boundary) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
766 (_array->offset_array(orig_next_offset_index) > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
767 _array->offset_array(orig_next_offset_index) <= N_words),
a61af66fc99e Initial load
duke
parents:
diff changeset
768 "offset array should have been set");
a61af66fc99e Initial load
duke
parents:
diff changeset
769 for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
770 assert(_array->offset_array(j) > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
771 _array->offset_array(j) <= (u_char) (N_words+N_powers-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
772 "offset array should have been set");
a61af66fc99e Initial load
duke
parents:
diff changeset
773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
774 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 HeapWord* BlockOffsetArrayContigSpace::initialize_threshold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
a61af66fc99e Initial load
duke
parents:
diff changeset
779 "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
780 _next_offset_index = _array->index_for(_bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 _next_offset_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
782 _next_offset_threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
783 _array->address_for_index(_next_offset_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 return _next_offset_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 void BlockOffsetArrayContigSpace::zero_bottom_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
a61af66fc99e Initial load
duke
parents:
diff changeset
789 "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
790 size_t bottom_index = _array->index_for(_bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
791 _array->set_offset_array(bottom_index, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 size_t BlockOffsetArrayContigSpace::last_active_index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 size_t result = _next_offset_index - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
796 return result >= 0 ? result : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
797 }