104 size_t allowed_deadspace = 0;
105 if (skip_dead) {
106 const size_t ratio = space->allowed_dead_ratio();
107 allowed_deadspace = (space->capacity() * ratio / 100) / HeapWordSize;
108 }
109
110 HeapWord* q = space->bottom();
111 HeapWord* t = space->scan_limit();
112
113 HeapWord* end_of_live= q; // One byte beyond the last byte of the last
114 // live object.
115 HeapWord* first_dead = space->end(); // The first dead object.
116 LiveRange* liveRange = NULL; // The current live range, recorded in the
117 // first header of preceding free area.
118 space->_first_dead = first_dead;
119
120 const intx interval = PrefetchScanIntervalInBytes;
121
122 while (q < t) {
123 assert(!space->scanned_block_is_obj(q) ||
124 oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
125 oop(q)->mark()->has_bias_pattern(),
126 "these are the only valid states during a mark sweep");
127 if (space->scanned_block_is_obj(q) && oop(q)->is_gc_marked()) {
128 // prefetch beyond q
129 Prefetch::write(q, interval);
130 size_t size = space->scanned_block_size(q);
131 compact_top = cp->space->forward(oop(q), size, cp, compact_top);
132 q += size;
133 end_of_live = q;
134 } else {
135 // run over all the contiguous dead objects
136 HeapWord* end = q;
137 do {
138 // prefetch beyond end
139 Prefetch::write(end, interval);
140 end += space->scanned_block_size(end);
141 } while (end < t && (!space->scanned_block_is_obj(end) || !oop(end)->is_gc_marked()));
142
143 // see if we might want to pretend this object is alive so that
144 // we don't have to compact quite as often.
145 if (allowed_deadspace > 0 && q == compact_top) {
146 size_t sz = pointer_delta(end, q);
147 if (space->insert_deadspace(allowed_deadspace, q, sz)) {
148 compact_top = cp->space->forward(oop(q), sz, cp, compact_top);
149 q = end;
150 end_of_live = end;
151 continue;
152 }
153 }
154
155 // otherwise, it really is a free region.
156
157 // for the previous LiveRange, record the end of the live objects.
158 if (liveRange) {
159 liveRange->set_end(q);
160 }
161
162 // record the current LiveRange object.
163 // liveRange->start() is overlaid on the mark word.
164 liveRange = (LiveRange*)q;
165 liveRange->set_start(end);
166 liveRange->set_end(end);
167
168 // see if this is the first dead region.
169 if (q < first_dead) {
170 first_dead = q;
171 }
172
173 // move on to the next object
174 q = end;
175 }
176 }
177
178 assert(q == t, "just checking");
179 if (liveRange != NULL) {
180 liveRange->set_end(q);
181 }
182 space->_end_of_live = end_of_live;
183 if (end_of_live < first_dead) {
184 first_dead = end_of_live;
185 }
186 space->_first_dead = first_dead;
187
188 // save the compaction_top of the compaction space.
189 cp->space->set_compaction_top(compact_top);
190 }
191
192 template <class SpaceType>
193 inline void CompactibleSpace::scan_and_adjust_pointers(SpaceType* space) {
194 // adjust all the interior pointers to point at the new locations of objects
195 // Used by MarkSweep::mark_sweep_phase3()
196
197 HeapWord* q = space->bottom();
198 HeapWord* t = space->_end_of_live; // Established by "prepare_for_compaction".
199
200 assert(space->_first_dead <= space->_end_of_live, "Stands to reason, no?");
201
202 if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) {
203 // we have a chunk of the space which hasn't moved and we've
204 // reinitialized the mark word during the previous pass, so we can't
205 // use is_gc_marked for the traversal.
206 HeapWord* end = space->_first_dead;
207
208 while (q < end) {
209 // I originally tried to conjoin "block_start(q) == q" to the
210 // assertion below, but that doesn't work, because you can't
211 // accurately traverse previous objects to get to the current one
212 // after their pointers have been
213 // updated, until the actual compaction is done. dld, 4/00
214 assert(space->block_is_obj(q), "should be at block boundaries, and should be looking at objs");
215
216 // point all the oops to the new location
217 size_t size = MarkSweep::adjust_pointers(oop(q));
218 size = space->adjust_obj_size(size);
219
220 q += size;
221 }
222
223 if (space->_first_dead == t) {
224 q = t;
225 } else {
226 // $$$ This is funky. Using this to read the previously written
227 // LiveRange. See also use below.
228 q = (HeapWord*)oop(space->_first_dead)->mark()->decode_pointer();
229 }
230 }
231
232 const intx interval = PrefetchScanIntervalInBytes;
233
234 debug_only(HeapWord* prev_q = NULL);
235 while (q < t) {
236 // prefetch beyond q
237 Prefetch::write(q, interval);
238 if (oop(q)->is_gc_marked()) {
239 // q is alive
240 // point all the oops to the new location
241 size_t size = MarkSweep::adjust_pointers(oop(q));
242 size = space->adjust_obj_size(size);
243 debug_only(prev_q = q);
244 q += size;
245 } else {
246 // q is not a live object, so its mark should point at the next
247 // live object
248 debug_only(prev_q = q);
249 q = (HeapWord*) oop(q)->mark()->decode_pointer();
250 assert(q > prev_q, "we should be moving forward through memory");
251 }
252 }
253
254 assert(q == t, "just checking");
255 }
256
257 template <class SpaceType>
258 inline void CompactibleSpace::scan_and_compact(SpaceType* space) {
259 // Copy all live objects to their new location
260 // Used by MarkSweep::mark_sweep_phase4()
261
262 HeapWord* q = space->bottom();
263 HeapWord* const t = space->_end_of_live;
264 debug_only(HeapWord* prev_q = NULL);
265
266 if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) {
267 #ifdef ASSERT // Debug only
268 // we have a chunk of the space which hasn't moved and we've reinitialized
269 // the mark word during the previous pass, so we can't use is_gc_marked for
270 // the traversal.
271 HeapWord* const end = space->_first_dead;
272
273 while (q < end) {
274 size_t size = space->obj_size(q);
275 assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
276 prev_q = q;
277 q += size;
278 }
279 #endif
280
281 if (space->_first_dead == t) {
282 q = t;
283 } else {
284 // $$$ Funky
285 q = (HeapWord*) oop(space->_first_dead)->mark()->decode_pointer();
286 }
287 }
288
289 const intx scan_interval = PrefetchScanIntervalInBytes;
290 const intx copy_interval = PrefetchCopyIntervalInBytes;
291 while (q < t) {
292 if (!oop(q)->is_gc_marked()) {
293 // mark is pointer to next marked oop
294 debug_only(prev_q = q);
295 q = (HeapWord*) oop(q)->mark()->decode_pointer();
296 assert(q > prev_q, "we should be moving forward through memory");
297 } else {
298 // prefetch beyond q
299 Prefetch::read(q, scan_interval);
300
301 // size and destination
302 size_t size = space->obj_size(q);
303 HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
304
305 // prefetch beyond compaction_top
306 Prefetch::write(compaction_top, copy_interval);
307
308 // copy object and reinit its mark
309 assert(q != compaction_top, "everything in this pass should be moving");
310 Copy::aligned_conjoint_words(q, compaction_top, size);
311 oop(compaction_top)->init_mark();
312 assert(oop(compaction_top)->klass() != NULL, "should have a class");
313
314 debug_only(prev_q = q);
315 q += size;
316 }
317 }
318
319 // Let's remember if we were empty before we did the compaction.
320 bool was_empty = space->used_region().is_empty();
321 // Reset space after compaction is complete
322 space->reset_after_compaction();
323 // We do this clear, below, since it has overloaded meanings for some
324 // space subtypes. For example, OffsetTableContigSpace's that were
325 // compacted into will have had their offset table thresholds updated
326 // continuously, but those that weren't need to have their thresholds
327 // re-initialized. Also mangles unused area for debugging.
328 if (space->used_region().is_empty()) {
329 if (!was_empty) space->clear(SpaceDecorator::Mangle);
330 } else {
|
104 size_t allowed_deadspace = 0;
105 if (skip_dead) {
106 const size_t ratio = space->allowed_dead_ratio();
107 allowed_deadspace = (space->capacity() * ratio / 100) / HeapWordSize;
108 }
109
110 HeapWord* q = space->bottom();
111 HeapWord* t = space->scan_limit();
112
113 HeapWord* end_of_live= q; // One byte beyond the last byte of the last
114 // live object.
115 HeapWord* first_dead = space->end(); // The first dead object.
116 LiveRange* liveRange = NULL; // The current live range, recorded in the
117 // first header of preceding free area.
118 space->_first_dead = first_dead;
119
120 const intx interval = PrefetchScanIntervalInBytes;
121
122 while (q < t) {
123 assert(!space->scanned_block_is_obj(q) ||
124 space->make_oop(q)->mark()->is_marked() ||
125 oopDesc::bs()->resolve_oop(space->make_oop(q))->mark()->is_marked() ||
126 space->make_oop(q)->mark()->is_unlocked() ||
127 oopDesc::bs()->resolve_oop(space->make_oop(q))->mark()->is_unlocked() ||
128 space->make_oop(q)->mark()->has_bias_pattern() ||
129 oopDesc::bs()->resolve_oop(space->make_oop(q))->mark()->has_bias_pattern(),
130 "these are the only valid states during a mark sweep");
131 if (space->scanned_block_is_obj(q) && space->make_oop(q)->is_gc_marked()) {
132 // prefetch beyond q
133 Prefetch::write(q, interval);
134 size_t size = space->scanned_block_size(q);
135 compact_top = cp->space->forward(space->make_oop(q), size, cp, compact_top);
136 q += size;
137 end_of_live = q;
138 } else {
139 // run over all the contiguous dead objects
140 HeapWord* end = q;
141 do {
142 // prefetch beyond end
143 Prefetch::write(end, interval);
144 end += space->scanned_block_size(end);
145 } while (end < t && (!space->scanned_block_is_obj(end) || !space->make_oop(end)->is_gc_marked()));
146
147 // see if we might want to pretend this object is alive so that
148 // we don't have to compact quite as often.
149 if (allowed_deadspace > 0 && q == compact_top) {
150 size_t sz = pointer_delta(end, q);
151 if (space->insert_deadspace(allowed_deadspace, q, sz)) {
152 compact_top = cp->space->forward(space->make_oop(q), sz, cp, compact_top);
153 q = end;
154 end_of_live = end;
155 continue;
156 }
157 }
158
159 // otherwise, it really is a free region.
160
161 // for the previous LiveRange, record the end of the live objects.
162 if (liveRange) {
163 liveRange->set_end(q);
164 }
165
166 // record the current LiveRange object.
167 // liveRange->start() is overlaid on the mark word.
168 liveRange = (LiveRange*) (HeapWord*) space->make_oop(q);
169 liveRange->set_start(end);
170 liveRange->set_end(end);
171
172 // see if this is the first dead region.
173 if (q < first_dead) {
174 first_dead = q;
175 }
176
177 // move on to the next object
178 q = end;
179 }
180 }
181
182 assert(q == t, "just checking");
183 if (liveRange != NULL) {
184 liveRange->set_end(q);
185 }
186 space->_end_of_live = end_of_live;
187 if (end_of_live < first_dead) {
188 first_dead = end_of_live;
189 }
190 space->_first_dead = first_dead;
191
192 // save the compaction_top of the compaction space.
193 cp->space->set_compaction_top(compact_top);
194 }
195
196 template <class SpaceType>
197 inline void CompactibleSpace::scan_and_adjust_pointers(SpaceType* space) {
198 // adjust all the interior pointers to point at the new locations of objects
199 // Used by MarkSweep::mark_sweep_phase3()
200
201 HeapWord* q = space->bottom();
202 HeapWord* t = space->_end_of_live; // Established by "prepare_for_compaction".
203
204 assert(space->_first_dead <= space->_end_of_live, "Stands to reason, no?");
205
206 if (q < t && space->_first_dead > q && !space->make_oop(q)->is_gc_marked()) {
207 // we have a chunk of the space which hasn't moved and we've
208 // reinitialized the mark word during the previous pass, so we can't
209 // use is_gc_marked for the traversal.
210 HeapWord* end = space->_first_dead;
211
212 while (q < end) {
213 // I originally tried to conjoin "block_start(q) == q" to the
214 // assertion below, but that doesn't work, because you can't
215 // accurately traverse previous objects to get to the current one
216 // after their pointers have been
217 // updated, until the actual compaction is done. dld, 4/00
218 assert(space->block_is_obj(q), "should be at block boundaries, and should be looking at objs");
219
220 // point all the oops to the new location
221 size_t size = MarkSweep::adjust_pointers(space->make_oop(q));
222 size = space->adjust_obj_size(size);
223
224 q += size;
225 }
226
227 if (space->_first_dead == t) {
228 q = t;
229 } else {
230 // $$$ This is funky. Using this to read the previously written
231 // LiveRange. See also use below.
232 q = (HeapWord*)oop(space->_first_dead)->mark()->decode_pointer();
233 }
234 }
235
236 const intx interval = PrefetchScanIntervalInBytes;
237
238 debug_only(HeapWord* prev_q = NULL);
239 while (q < t) {
240 // prefetch beyond q
241 Prefetch::write(q, interval);
242 if (space->make_oop(q)->is_gc_marked()) {
243 // q is alive
244 // point all the oops to the new location
245 size_t size = MarkSweep::adjust_pointers(space->make_oop(q));
246 size = space->adjust_obj_size(size);
247 debug_only(prev_q = q);
248 q += size;
249 } else {
250 // q is not a live object, so its mark should point at the next
251 // live object
252 debug_only(prev_q = q);
253 q = (HeapWord*) space->make_oop(q)->mark()->decode_pointer();
254 assert(q > prev_q, "we should be moving forward through memory");
255 }
256 }
257
258 assert(q == t, "just checking");
259 }
260
261 template <class SpaceType>
262 inline void CompactibleSpace::scan_and_compact(SpaceType* space) {
263 // Copy all live objects to their new location
264 // Used by MarkSweep::mark_sweep_phase4()
265
266 HeapWord* q = space->bottom();
267 HeapWord* const t = space->_end_of_live;
268 debug_only(HeapWord* prev_q = NULL);
269
270 if (q < t && space->_first_dead > q && !space->make_oop(q)->is_gc_marked()) {
271 #ifdef ASSERT // Debug only
272 // we have a chunk of the space which hasn't moved and we've reinitialized
273 // the mark word during the previous pass, so we can't use is_gc_marked for
274 // the traversal.
275 HeapWord* const end = space->_first_dead;
276
277 while (q < end) {
278 size_t size = space->obj_size(q);
279 assert(!space->make_oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
280 prev_q = q;
281 q += size;
282 }
283 #endif
284
285 if (space->_first_dead == t) {
286 q = t;
287 } else {
288 // $$$ Funky
289 q = (HeapWord*) oop(space->_first_dead)->mark()->decode_pointer();
290 }
291 }
292
293 const intx scan_interval = PrefetchScanIntervalInBytes;
294 const intx copy_interval = PrefetchCopyIntervalInBytes;
295 while (q < t) {
296 if (!space->make_oop(q)->is_gc_marked()) {
297 // mark is pointer to next marked oop
298 debug_only(prev_q = q);
299 q = (HeapWord*) space->make_oop(q)->mark()->decode_pointer();
300 assert(q > prev_q, "we should be moving forward through memory");
301 } else {
302 // prefetch beyond q
303 Prefetch::read(q, scan_interval);
304
305 // size and destination
306 size_t size = space->obj_size(q);
307 HeapWord* compaction_top = (HeapWord*)space->make_oop(q)->forwardee();
308
309 // prefetch beyond compaction_top
310 Prefetch::write(compaction_top, copy_interval);
311
312 // copy object and reinit its mark
313 assert(q != compaction_top, "everything in this pass should be moving");
314 Copy::aligned_conjoint_words((HeapWord*) space->make_oop(q), compaction_top, size);
315 oop(compaction_top)->init_mark();
316 assert(oop(compaction_top)->klass() != NULL, "should have a class");
317
318 debug_only(prev_q = q);
319 q += size;
320 }
321 }
322
323 // Let's remember if we were empty before we did the compaction.
324 bool was_empty = space->used_region().is_empty();
325 // Reset space after compaction is complete
326 space->reset_after_compaction();
327 // We do this clear, below, since it has overloaded meanings for some
328 // space subtypes. For example, OffsetTableContigSpace's that were
329 // compacted into will have had their offset table thresholds updated
330 // continuously, but those that weren't need to have their thresholds
331 // re-initialized. Also mangles unused area for debugging.
332 if (space->used_region().is_empty()) {
333 if (!was_empty) space->clear(SpaceDecorator::Mangle);
334 } else {
|