1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)psMarkSweepDecorator.cpp 1.26 07/05/17 15:52:53 JVM"
3 #endif
4 /*
5 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
76
77 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
78 // The object forwarding code is duplicated. Factor this out!!!!!
79 //
80 // This method "precompacts" objects inside its space to dest. It places forwarding
81 // pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
82 // finish by compacting into our own space.
83
84 void PSMarkSweepDecorator::precompact() {
85 // Reset our own compact top.
86 set_compaction_top(space()->bottom());
87
88 /* We allow some amount of garbage towards the bottom of the space, so
89 * we don't start compacting before there is a significant gain to be made.
90 * Occasionally, we want to ensure a full compaction, which is determined
91 * by the MarkSweepAlwaysCompactCount parameter. This is a significant
92 * performance improvement!
93 */
94 bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
95
96 ssize_t allowed_deadspace = 0;
97 if (skip_dead) {
98 int ratio = allowed_dead_ratio();
99 allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize;
100 }
101
102 // Fetch the current destination decorator
103 PSMarkSweepDecorator* dest = destination_decorator();
104 ObjectStartArray* start_array = dest->start_array();
105
106 HeapWord* compact_top = dest->compaction_top();
107 HeapWord* compact_end = dest->space()->end();
108
109 HeapWord* q = space()->bottom();
110 HeapWord* t = space()->top();
111
112 HeapWord* end_of_live= q; /* One byte beyond the last byte of the last
113 live object. */
114 HeapWord* first_dead = space()->end(); /* The first dead object. */
115 LiveRange* liveRange = NULL; /* The current live range, recorded in the
116 first header of preceding free area. */
117 _first_dead = first_dead;
118
119 const intx interval = PrefetchScanIntervalInBytes;
138
139 // Advance to the next compaction decorator
140 advance_destination_decorator();
141 dest = destination_decorator();
142
143 // Update compaction info
144 start_array = dest->start_array();
145 compact_top = dest->compaction_top();
146 compact_end = dest->space()->end();
147 assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
148 assert(compact_end > compact_top, "Must always be space remaining");
149 compaction_max_size =
150 pointer_delta(compact_end, compact_top);
151 }
152
153 // store the forwarding pointer into the mark word
154 if (q != compact_top) {
155 oop(q)->forward_to(oop(compact_top));
156 assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
157 } else {
158 // Don't clear the mark since it's confuses parallel old
159 // verification.
160 if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
161 // if the object isn't moving we can just set the mark to the default
162 // mark and handle it specially later on.
163 oop(q)->init_mark();
164 }
165 assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
166 }
167
168 // Update object start array
169 if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
170 if (start_array)
171 start_array->allocate_block(compact_top);
172 }
173
174 debug_only(MarkSweep::register_live_oop(oop(q), size));
175 compact_top += size;
176 assert(compact_top <= dest->space()->end(),
177 "Exceeding space in destination");
178
179 q += size;
180 end_of_live = q;
181 } else {
182 /* run over all the contiguous dead objects */
183 HeapWord* end = q;
184 do {
185 /* prefetch beyond end */
186 Prefetch::write(end, interval);
187 end += oop(end)->size();
188 } while (end < t && (!oop(end)->is_gc_marked()));
189
190 /* see if we might want to pretend this object is alive so that
191 * we don't have to compact quite as often.
192 */
193 if (allowed_deadspace > 0 && q == compact_top) {
194 size_t sz = pointer_delta(end, q);
205 // Advance to the next compaction decorator
206 advance_destination_decorator();
207 dest = destination_decorator();
208
209 // Update compaction info
210 start_array = dest->start_array();
211 compact_top = dest->compaction_top();
212 compact_end = dest->space()->end();
213 assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
214 assert(compact_end > compact_top, "Must always be space remaining");
215 compaction_max_size =
216 pointer_delta(compact_end, compact_top);
217 }
218
219 // store the forwarding pointer into the mark word
220 if (q != compact_top) {
221 oop(q)->forward_to(oop(compact_top));
222 assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
223 } else {
224 // if the object isn't moving we can just set the mark to the default
225 // Don't clear the mark since it's confuses parallel old
226 // verification.
227 if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
228 // mark and handle it specially later on.
229 oop(q)->init_mark();
230 }
231 assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
232 }
233
234 if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
235 // Update object start array
236 if (start_array)
237 start_array->allocate_block(compact_top);
238 }
239
240 debug_only(MarkSweep::register_live_oop(oop(q), sz));
241 compact_top += sz;
242 assert(compact_top <= dest->space()->end(),
243 "Exceeding space in destination");
244
245 q = end;
246 end_of_live = end;
247 continue;
248 }
249 }
250
251 /* for the previous LiveRange, record the end of the live objects. */
252 if (liveRange) {
253 liveRange->set_end(q);
254 }
255
256 /* record the current LiveRange object.
257 * liveRange->start() is overlaid on the mark word.
258 */
259 liveRange = (LiveRange*)q;
260 liveRange->set_start(end);
267
268 /* move on to the next object */
269 q = end;
270 }
271 }
272
273 assert(q == t, "just checking");
274 if (liveRange != NULL) {
275 liveRange->set_end(q);
276 }
277 _end_of_live = end_of_live;
278 if (end_of_live < first_dead) {
279 first_dead = end_of_live;
280 }
281 _first_dead = first_dead;
282
283 // Update compaction top
284 dest->set_compaction_top(compact_top);
285 }
286
287 bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words,
288 HeapWord* q, size_t deadlength) {
289 allowed_deadspace_words -= deadlength;
290 if (allowed_deadspace_words >= 0) {
291 oop(q)->set_mark(markOopDesc::prototype()->set_marked());
292 const size_t aligned_min_int_array_size =
293 align_object_size(typeArrayOopDesc::header_size(T_INT));
294 if (deadlength >= aligned_min_int_array_size) {
295 oop(q)->set_klass(Universe::intArrayKlassObj());
296 assert(((deadlength - aligned_min_int_array_size) * (HeapWordSize/sizeof(jint))) < (size_t)max_jint,
297 "deadspace too big for Arrayoop");
298 typeArrayOop(q)->set_length((int)((deadlength - aligned_min_int_array_size)
299 * (HeapWordSize/sizeof(jint))));
300 } else {
301 assert((int) deadlength == instanceOopDesc::header_size(),
302 "size for smallest fake dead object doesn't match");
303 oop(q)->set_klass(SystemDictionary::object_klass());
304 }
305 assert((int) deadlength == oop(q)->size(),
306 "make sure size for fake dead object match");
307 // Recall that we required "q == compaction_top".
308 return true;
309 } else {
310 allowed_deadspace_words = 0;
311 return false;
312 }
313 }
314
315 void PSMarkSweepDecorator::adjust_pointers() {
316 // adjust all the interior pointers to point at the new locations of objects
317 // Used by MarkSweep::mark_sweep_phase3()
318
319 HeapWord* q = space()->bottom();
320 HeapWord* t = _end_of_live; // Established by "prepare_for_compaction".
321
322 assert(_first_dead <= _end_of_live, "Stands to reason, no?");
323
324 if (q < t && _first_dead > q &&
325 !oop(q)->is_gc_marked()) {
326 // we have a chunk of the space which hasn't moved and we've
327 // reinitialized the mark word during the previous pass, so we can't
328 // use is_gc_marked for the traversal.
329 HeapWord* end = _first_dead;
330
331 while (q < end) {
332 debug_only(MarkSweep::track_interior_pointers(oop(q)));
333
334 // point all the oops to the new location
335 size_t size = oop(q)->adjust_pointers();
336
337 debug_only(MarkSweep::check_interior_pointers());
338
339 debug_only(MarkSweep::validate_live_oop(oop(q), size));
340
341 q += size;
342 }
343
344 if (_first_dead == t) {
345 q = t;
346 } else {
347 // $$$ This is funky. Using this to read the previously written
348 // LiveRange. See also use below.
349 q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
350 }
351 }
352 const intx interval = PrefetchScanIntervalInBytes;
353
354 debug_only(HeapWord* prev_q = NULL);
355 while (q < t) {
356 // prefetch beyond q
357 Prefetch::write(q, interval);
358 if (oop(q)->is_gc_marked()) {
359 // q is alive
360 debug_only(MarkSweep::track_interior_pointers(oop(q)));
361 // point all the oops to the new location
362 size_t size = oop(q)->adjust_pointers();
363 debug_only(MarkSweep::check_interior_pointers());
364 debug_only(MarkSweep::validate_live_oop(oop(q), size));
365 debug_only(prev_q = q);
366 q += size;
367 } else {
368 // q is not a live object, so its mark should point at the next
369 // live object
370 debug_only(prev_q = q);
371 q = (HeapWord*) oop(q)->mark()->decode_pointer();
372 assert(q > prev_q, "we should be moving forward through memory");
373 }
374 }
375
376 assert(q == t, "just checking");
377 }
378
379 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
380 // Copy all live objects to their new location
381 // Used by MarkSweep::mark_sweep_phase4()
382
383 HeapWord* q = space()->bottom();
384 HeapWord* const t = _end_of_live;
385 debug_only(HeapWord* prev_q = NULL);
386
387 if (q < t && _first_dead > q &&
388 !oop(q)->is_gc_marked()) {
389 #ifdef ASSERT
390 // we have a chunk of the space which hasn't moved and we've reinitialized the
391 // mark word during the previous pass, so we can't use is_gc_marked for the
392 // traversal.
393 HeapWord* const end = _first_dead;
394
395 while (q < end) {
396 size_t size = oop(q)->size();
397 assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
398 debug_only(MarkSweep::live_oop_moved_to(q, size, q));
399 debug_only(prev_q = q);
400 q += size;
401 }
402 #endif
403
404 if (_first_dead == t) {
405 q = t;
406 } else {
407 // $$$ Funky
408 q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
409 }
410 }
411
412 const intx scan_interval = PrefetchScanIntervalInBytes;
413 const intx copy_interval = PrefetchCopyIntervalInBytes;
414
415 while (q < t) {
416 if (!oop(q)->is_gc_marked()) {
417 // mark is pointer to next marked oop
418 debug_only(prev_q = q);
419 q = (HeapWord*) oop(q)->mark()->decode_pointer();
420 assert(q > prev_q, "we should be moving forward through memory");
421 } else {
422 // prefetch beyond q
423 Prefetch::read(q, scan_interval);
424
425 // size and destination
426 size_t size = oop(q)->size();
427 HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
428
429 // prefetch beyond compaction_top
430 Prefetch::write(compaction_top, copy_interval);
431
432 // copy object and reinit its mark
433 debug_only(MarkSweep::live_oop_moved_to(q, size, compaction_top));
434 assert(q != compaction_top, "everything in this pass should be moving");
435 Copy::aligned_conjoint_words(q, compaction_top, size);
436 oop(compaction_top)->init_mark();
437 assert(oop(compaction_top)->klass() != NULL, "should have a class");
438
439 debug_only(prev_q = q);
440 q += size;
441 }
442 }
443
444 assert(compaction_top() >= space()->bottom() && compaction_top() <= space()->end(),
445 "should point inside space");
446 space()->set_top(compaction_top());
447
448 if (mangle_free_space) space()->mangle_unused_area();
449 }
|
1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)psMarkSweepDecorator.cpp 1.26 07/05/17 15:52:53 JVM"
3 #endif
4 /*
5 * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
76
77 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
78 // The object forwarding code is duplicated. Factor this out!!!!!
79 //
80 // This method "precompacts" objects inside its space to dest. It places forwarding
81 // pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
82 // finish by compacting into our own space.
83
84 void PSMarkSweepDecorator::precompact() {
85 // Reset our own compact top.
86 set_compaction_top(space()->bottom());
87
88 /* We allow some amount of garbage towards the bottom of the space, so
89 * we don't start compacting before there is a significant gain to be made.
90 * Occasionally, we want to ensure a full compaction, which is determined
91 * by the MarkSweepAlwaysCompactCount parameter. This is a significant
92 * performance improvement!
93 */
94 bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
95
96 size_t allowed_deadspace = 0;
97 if (skip_dead) {
98 const size_t ratio = allowed_dead_ratio();
99 allowed_deadspace = space()->capacity_in_words() * ratio / 100;
100 }
101
102 // Fetch the current destination decorator
103 PSMarkSweepDecorator* dest = destination_decorator();
104 ObjectStartArray* start_array = dest->start_array();
105
106 HeapWord* compact_top = dest->compaction_top();
107 HeapWord* compact_end = dest->space()->end();
108
109 HeapWord* q = space()->bottom();
110 HeapWord* t = space()->top();
111
112 HeapWord* end_of_live= q; /* One byte beyond the last byte of the last
113 live object. */
114 HeapWord* first_dead = space()->end(); /* The first dead object. */
115 LiveRange* liveRange = NULL; /* The current live range, recorded in the
116 first header of preceding free area. */
117 _first_dead = first_dead;
118
119 const intx interval = PrefetchScanIntervalInBytes;
138
139 // Advance to the next compaction decorator
140 advance_destination_decorator();
141 dest = destination_decorator();
142
143 // Update compaction info
144 start_array = dest->start_array();
145 compact_top = dest->compaction_top();
146 compact_end = dest->space()->end();
147 assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
148 assert(compact_end > compact_top, "Must always be space remaining");
149 compaction_max_size =
150 pointer_delta(compact_end, compact_top);
151 }
152
153 // store the forwarding pointer into the mark word
154 if (q != compact_top) {
155 oop(q)->forward_to(oop(compact_top));
156 assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
157 } else {
158 // if the object isn't moving we can just set the mark to the default
159 // mark and handle it specially later on.
160 oop(q)->init_mark();
161 assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
162 }
163
164 // Update object start array
165 if (start_array) {
166 start_array->allocate_block(compact_top);
167 }
168
169 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size));
170 compact_top += size;
171 assert(compact_top <= dest->space()->end(),
172 "Exceeding space in destination");
173
174 q += size;
175 end_of_live = q;
176 } else {
177 /* run over all the contiguous dead objects */
178 HeapWord* end = q;
179 do {
180 /* prefetch beyond end */
181 Prefetch::write(end, interval);
182 end += oop(end)->size();
183 } while (end < t && (!oop(end)->is_gc_marked()));
184
185 /* see if we might want to pretend this object is alive so that
186 * we don't have to compact quite as often.
187 */
188 if (allowed_deadspace > 0 && q == compact_top) {
189 size_t sz = pointer_delta(end, q);
200 // Advance to the next compaction decorator
201 advance_destination_decorator();
202 dest = destination_decorator();
203
204 // Update compaction info
205 start_array = dest->start_array();
206 compact_top = dest->compaction_top();
207 compact_end = dest->space()->end();
208 assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
209 assert(compact_end > compact_top, "Must always be space remaining");
210 compaction_max_size =
211 pointer_delta(compact_end, compact_top);
212 }
213
214 // store the forwarding pointer into the mark word
215 if (q != compact_top) {
216 oop(q)->forward_to(oop(compact_top));
217 assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
218 } else {
219 // if the object isn't moving we can just set the mark to the default
220 // mark and handle it specially later on.
221 oop(q)->init_mark();
222 assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
223 }
224
225 // Update object start array
226 if (start_array) {
227 start_array->allocate_block(compact_top);
228 }
229
230 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz));
231 compact_top += sz;
232 assert(compact_top <= dest->space()->end(),
233 "Exceeding space in destination");
234
235 q = end;
236 end_of_live = end;
237 continue;
238 }
239 }
240
241 /* for the previous LiveRange, record the end of the live objects. */
242 if (liveRange) {
243 liveRange->set_end(q);
244 }
245
246 /* record the current LiveRange object.
247 * liveRange->start() is overlaid on the mark word.
248 */
249 liveRange = (LiveRange*)q;
250 liveRange->set_start(end);
257
258 /* move on to the next object */
259 q = end;
260 }
261 }
262
263 assert(q == t, "just checking");
264 if (liveRange != NULL) {
265 liveRange->set_end(q);
266 }
267 _end_of_live = end_of_live;
268 if (end_of_live < first_dead) {
269 first_dead = end_of_live;
270 }
271 _first_dead = first_dead;
272
273 // Update compaction top
274 dest->set_compaction_top(compact_top);
275 }
276
277 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
278 HeapWord* q, size_t deadlength) {
279 if (allowed_deadspace_words >= deadlength) {
280 allowed_deadspace_words -= deadlength;
281 CollectedHeap::fill_with_object(q, deadlength);
282 oop(q)->set_mark(oop(q)->mark()->set_marked());
283 assert((int) deadlength == oop(q)->size(), "bad filler object size");
284 // Recall that we required "q == compaction_top".
285 return true;
286 } else {
287 allowed_deadspace_words = 0;
288 return false;
289 }
290 }
291
292 void PSMarkSweepDecorator::adjust_pointers() {
293 // adjust all the interior pointers to point at the new locations of objects
294 // Used by MarkSweep::mark_sweep_phase3()
295
296 HeapWord* q = space()->bottom();
297 HeapWord* t = _end_of_live; // Established by "prepare_for_compaction".
298
299 assert(_first_dead <= _end_of_live, "Stands to reason, no?");
300
301 if (q < t && _first_dead > q &&
302 !oop(q)->is_gc_marked()) {
303 // we have a chunk of the space which hasn't moved and we've
304 // reinitialized the mark word during the previous pass, so we can't
305 // use is_gc_marked for the traversal.
306 HeapWord* end = _first_dead;
307
308 while (q < end) {
309 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
310 // point all the oops to the new location
311 size_t size = oop(q)->adjust_pointers();
312 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
313 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
314 q += size;
315 }
316
317 if (_first_dead == t) {
318 q = t;
319 } else {
320 // $$$ This is funky. Using this to read the previously written
321 // LiveRange. See also use below.
322 q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
323 }
324 }
325 const intx interval = PrefetchScanIntervalInBytes;
326
327 debug_only(HeapWord* prev_q = NULL);
328 while (q < t) {
329 // prefetch beyond q
330 Prefetch::write(q, interval);
331 if (oop(q)->is_gc_marked()) {
332 // q is alive
333 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
334 // point all the oops to the new location
335 size_t size = oop(q)->adjust_pointers();
336 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
337 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
338 debug_only(prev_q = q);
339 q += size;
340 } else {
341 // q is not a live object, so its mark should point at the next
342 // live object
343 debug_only(prev_q = q);
344 q = (HeapWord*) oop(q)->mark()->decode_pointer();
345 assert(q > prev_q, "we should be moving forward through memory");
346 }
347 }
348
349 assert(q == t, "just checking");
350 }
351
352 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
353 // Copy all live objects to their new location
354 // Used by MarkSweep::mark_sweep_phase4()
355
356 HeapWord* q = space()->bottom();
357 HeapWord* const t = _end_of_live;
358 debug_only(HeapWord* prev_q = NULL);
359
360 if (q < t && _first_dead > q &&
361 !oop(q)->is_gc_marked()) {
362 #ifdef ASSERT
363 // we have a chunk of the space which hasn't moved and we've reinitialized the
364 // mark word during the previous pass, so we can't use is_gc_marked for the
365 // traversal.
366 HeapWord* const end = _first_dead;
367
368 while (q < end) {
369 size_t size = oop(q)->size();
370 assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
371 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q));
372 debug_only(prev_q = q);
373 q += size;
374 }
375 #endif
376
377 if (_first_dead == t) {
378 q = t;
379 } else {
380 // $$$ Funky
381 q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
382 }
383 }
384
385 const intx scan_interval = PrefetchScanIntervalInBytes;
386 const intx copy_interval = PrefetchCopyIntervalInBytes;
387
388 while (q < t) {
389 if (!oop(q)->is_gc_marked()) {
390 // mark is pointer to next marked oop
391 debug_only(prev_q = q);
392 q = (HeapWord*) oop(q)->mark()->decode_pointer();
393 assert(q > prev_q, "we should be moving forward through memory");
394 } else {
395 // prefetch beyond q
396 Prefetch::read(q, scan_interval);
397
398 // size and destination
399 size_t size = oop(q)->size();
400 HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
401
402 // prefetch beyond compaction_top
403 Prefetch::write(compaction_top, copy_interval);
404
405 // copy object and reinit its mark
406 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, compaction_top));
407 assert(q != compaction_top, "everything in this pass should be moving");
408 Copy::aligned_conjoint_words(q, compaction_top, size);
409 oop(compaction_top)->init_mark();
410 assert(oop(compaction_top)->klass() != NULL, "should have a class");
411
412 debug_only(prev_q = q);
413 q += size;
414 }
415 }
416
417 assert(compaction_top() >= space()->bottom() && compaction_top() <= space()->end(),
418 "should point inside space");
419 space()->set_top(compaction_top());
420
421 if (mangle_free_space) {
422 space()->mangle_unused_area();
423 }
424 }
|