23 |
23 |
24 #include "precompiled.hpp" |
24 #include "precompiled.hpp" |
25 |
25 |
26 #include "code/codeCache.hpp" |
26 #include "code/codeCache.hpp" |
27 #include "gc/shared/gcTraceTime.inline.hpp" |
27 #include "gc/shared/gcTraceTime.inline.hpp" |
|
28 #include "gc/shared/preservedMarks.inline.hpp" |
28 #include "gc/shenandoah/shenandoahForwarding.inline.hpp" |
29 #include "gc/shenandoah/shenandoahForwarding.inline.hpp" |
29 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" |
30 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" |
30 #include "gc/shenandoah/shenandoahCollectionSet.hpp" |
31 #include "gc/shenandoah/shenandoahCollectionSet.hpp" |
31 #include "gc/shenandoah/shenandoahFreeSet.hpp" |
32 #include "gc/shenandoah/shenandoahFreeSet.hpp" |
32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
33 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
44 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" |
45 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" |
45 #include "memory/metaspace.hpp" |
46 #include "memory/metaspace.hpp" |
46 #include "memory/universe.hpp" |
47 #include "memory/universe.hpp" |
47 #include "oops/compressedOops.inline.hpp" |
48 #include "oops/compressedOops.inline.hpp" |
48 #include "oops/oop.inline.hpp" |
49 #include "oops/oop.inline.hpp" |
|
50 #include "runtime/biasedLocking.hpp" |
49 #include "runtime/thread.hpp" |
51 #include "runtime/thread.hpp" |
50 #include "utilities/copy.hpp" |
52 #include "utilities/copy.hpp" |
51 #include "utilities/growableArray.hpp" |
53 #include "utilities/growableArray.hpp" |
52 #include "gc/shared/workgroup.hpp" |
54 #include "gc/shared/workgroup.hpp" |
|
55 |
|
56 ShenandoahMarkCompact::ShenandoahMarkCompact() : |
|
57 _gc_timer(NULL), |
|
58 _preserved_marks(new PreservedMarksSet(true)) {} |
53 |
59 |
54 void ShenandoahMarkCompact::initialize(GCTimer* gc_timer) { |
60 void ShenandoahMarkCompact::initialize(GCTimer* gc_timer) { |
55 _gc_timer = gc_timer; |
61 _gc_timer = gc_timer; |
56 } |
62 } |
57 |
63 |
119 rp->abandon_partial_discovery(); |
125 rp->abandon_partial_discovery(); |
120 rp->verify_no_references_recorded(); |
126 rp->verify_no_references_recorded(); |
121 |
127 |
122 // e. Set back forwarded objects bit back, in case some steps above dropped it. |
128 // e. Set back forwarded objects bit back, in case some steps above dropped it. |
123 heap->set_has_forwarded_objects(has_forwarded_objects); |
129 heap->set_has_forwarded_objects(has_forwarded_objects); |
|
130 |
|
131 // The rest of prologue: |
|
132 BiasedLocking::preserve_marks(); |
|
133 _preserved_marks->init(heap->workers()->active_workers()); |
124 } |
134 } |
125 |
135 |
126 heap->make_parsable(true); |
136 heap->make_parsable(true); |
127 |
137 |
128 OrderAccess::fence(); |
138 OrderAccess::fence(); |
157 phase3_update_references(); |
167 phase3_update_references(); |
158 |
168 |
159 phase4_compact_objects(worker_slices); |
169 phase4_compact_objects(worker_slices); |
160 } |
170 } |
161 |
171 |
|
172 { |
|
173 // Epilogue |
|
174 SharedRestorePreservedMarksTaskExecutor exec(heap->workers()); |
|
175 _preserved_marks->restore(&exec); |
|
176 BiasedLocking::restore_marks(); |
|
177 _preserved_marks->reclaim(); |
|
178 |
|
179 JvmtiExport::gc_epilogue(); |
|
180 } |
|
181 |
162 // Resize metaspace |
182 // Resize metaspace |
163 MetaspaceGC::compute_new_size(); |
183 MetaspaceGC::compute_new_size(); |
164 |
184 |
165 // Free worker slices |
185 // Free worker slices |
166 for (uint i = 0; i < heap->max_workers(); i++) { |
186 for (uint i = 0; i < heap->max_workers(); i++) { |
167 delete worker_slices[i]; |
187 delete worker_slices[i]; |
168 } |
188 } |
169 FREE_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, worker_slices); |
189 FREE_C_HEAP_ARRAY(ShenandoahHeapRegionSet*, worker_slices); |
170 |
|
171 JvmtiExport::gc_epilogue(); |
|
172 |
190 |
173 heap->set_full_gc_move_in_progress(false); |
191 heap->set_full_gc_move_in_progress(false); |
174 heap->set_full_gc_in_progress(false); |
192 heap->set_full_gc_in_progress(false); |
175 |
193 |
176 if (ShenandoahVerify) { |
194 if (ShenandoahVerify) { |
228 heap->mark_complete_marking_context(); |
246 heap->mark_complete_marking_context(); |
229 } |
247 } |
230 |
248 |
231 class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure { |
249 class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure { |
232 private: |
250 private: |
|
251 PreservedMarks* const _preserved_marks; |
233 ShenandoahHeap* const _heap; |
252 ShenandoahHeap* const _heap; |
234 GrowableArray<ShenandoahHeapRegion*>& _empty_regions; |
253 GrowableArray<ShenandoahHeapRegion*>& _empty_regions; |
235 int _empty_regions_pos; |
254 int _empty_regions_pos; |
236 ShenandoahHeapRegion* _to_region; |
255 ShenandoahHeapRegion* _to_region; |
237 ShenandoahHeapRegion* _from_region; |
256 ShenandoahHeapRegion* _from_region; |
238 HeapWord* _compact_point; |
257 HeapWord* _compact_point; |
239 |
258 |
240 public: |
259 public: |
241 ShenandoahPrepareForCompactionObjectClosure(GrowableArray<ShenandoahHeapRegion*>& empty_regions, ShenandoahHeapRegion* to_region) : |
260 ShenandoahPrepareForCompactionObjectClosure(PreservedMarks* preserved_marks, |
|
261 GrowableArray<ShenandoahHeapRegion*>& empty_regions, |
|
262 ShenandoahHeapRegion* to_region) : |
|
263 _preserved_marks(preserved_marks), |
242 _heap(ShenandoahHeap::heap()), |
264 _heap(ShenandoahHeap::heap()), |
243 _empty_regions(empty_regions), |
265 _empty_regions(empty_regions), |
244 _empty_regions_pos(0), |
266 _empty_regions_pos(0), |
245 _to_region(to_region), |
267 _to_region(to_region), |
246 _from_region(NULL), |
268 _from_region(NULL), |
266 void do_object(oop p) { |
288 void do_object(oop p) { |
267 assert(_from_region != NULL, "must set before work"); |
289 assert(_from_region != NULL, "must set before work"); |
268 assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); |
290 assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); |
269 assert(!_heap->complete_marking_context()->allocated_after_mark_start((HeapWord*) p), "must be truly marked"); |
291 assert(!_heap->complete_marking_context()->allocated_after_mark_start((HeapWord*) p), "must be truly marked"); |
270 |
292 |
271 size_t obj_size = p->size() + ShenandoahForwarding::word_size(); |
293 size_t obj_size = p->size(); |
272 if (_compact_point + obj_size > _to_region->end()) { |
294 if (_compact_point + obj_size > _to_region->end()) { |
273 finish_region(); |
295 finish_region(); |
274 |
296 |
275 // Object doesn't fit. Pick next empty region and start compacting there. |
297 // Object doesn't fit. Pick next empty region and start compacting there. |
276 ShenandoahHeapRegion* new_to_region; |
298 ShenandoahHeapRegion* new_to_region; |
289 } |
311 } |
290 |
312 |
291 // Object fits into current region, record new location: |
313 // Object fits into current region, record new location: |
292 assert(_compact_point + obj_size <= _to_region->end(), "must fit"); |
314 assert(_compact_point + obj_size <= _to_region->end(), "must fit"); |
293 shenandoah_assert_not_forwarded(NULL, p); |
315 shenandoah_assert_not_forwarded(NULL, p); |
294 ShenandoahForwarding::set_forwardee_raw(p, _compact_point + ShenandoahForwarding::word_size()); |
316 _preserved_marks->push_if_necessary(p, p->mark_raw()); |
|
317 p->forward_to(oop(_compact_point)); |
295 _compact_point += obj_size; |
318 _compact_point += obj_size; |
296 } |
319 } |
297 }; |
320 }; |
298 |
321 |
299 class ShenandoahPrepareForCompactionTask : public AbstractGangTask { |
322 class ShenandoahPrepareForCompactionTask : public AbstractGangTask { |
300 private: |
323 private: |
|
324 PreservedMarksSet* const _preserved_marks; |
301 ShenandoahHeap* const _heap; |
325 ShenandoahHeap* const _heap; |
302 ShenandoahHeapRegionSet** const _worker_slices; |
326 ShenandoahHeapRegionSet** const _worker_slices; |
303 ShenandoahRegionIterator _heap_regions; |
327 ShenandoahRegionIterator _heap_regions; |
304 |
328 |
305 ShenandoahHeapRegion* next_from_region(ShenandoahHeapRegionSet* slice) { |
329 ShenandoahHeapRegion* next_from_region(ShenandoahHeapRegionSet* slice) { |
318 |
342 |
319 return from_region; |
343 return from_region; |
320 } |
344 } |
321 |
345 |
322 public: |
346 public: |
323 ShenandoahPrepareForCompactionTask(ShenandoahHeapRegionSet** worker_slices) : |
347 ShenandoahPrepareForCompactionTask(PreservedMarksSet* preserved_marks, ShenandoahHeapRegionSet** worker_slices) : |
324 AbstractGangTask("Shenandoah Prepare For Compaction Task"), |
348 AbstractGangTask("Shenandoah Prepare For Compaction Task"), |
|
349 _preserved_marks(preserved_marks), |
325 _heap(ShenandoahHeap::heap()), _worker_slices(worker_slices) { |
350 _heap(ShenandoahHeap::heap()), _worker_slices(worker_slices) { |
326 } |
351 } |
327 |
352 |
328 void work(uint worker_id) { |
353 void work(uint worker_id) { |
329 ShenandoahHeapRegionSet* slice = _worker_slices[worker_id]; |
354 ShenandoahHeapRegionSet* slice = _worker_slices[worker_id]; |
335 |
360 |
336 // Sliding compaction. Walk all regions in the slice, and compact them. |
361 // Sliding compaction. Walk all regions in the slice, and compact them. |
337 // Remember empty regions and reuse them as needed. |
362 // Remember empty regions and reuse them as needed. |
338 ResourceMark rm; |
363 ResourceMark rm; |
339 GrowableArray<ShenandoahHeapRegion*> empty_regions((int)_heap->num_regions()); |
364 GrowableArray<ShenandoahHeapRegion*> empty_regions((int)_heap->num_regions()); |
340 ShenandoahPrepareForCompactionObjectClosure cl(empty_regions, from_region); |
365 ShenandoahPrepareForCompactionObjectClosure cl(_preserved_marks->get(worker_id), empty_regions, from_region); |
341 while (from_region != NULL) { |
366 while (from_region != NULL) { |
342 cl.set_from_region(from_region); |
367 cl.set_from_region(from_region); |
343 if (from_region->has_live()) { |
368 if (from_region->has_live()) { |
344 _heap->marked_object_iterate(from_region, &cl); |
369 _heap->marked_object_iterate(from_region, &cl); |
345 } |
370 } |
375 // detected, then sliding restarts towards that non-movable region. |
400 // detected, then sliding restarts towards that non-movable region. |
376 |
401 |
377 size_t to_begin = heap->num_regions(); |
402 size_t to_begin = heap->num_regions(); |
378 size_t to_end = heap->num_regions(); |
403 size_t to_end = heap->num_regions(); |
379 |
404 |
380 for (size_t c = heap->num_regions() - 1; c > 0; c--) { |
405 for (size_t c = heap->num_regions(); c > 0; c--) { |
381 ShenandoahHeapRegion *r = heap->get_region(c); |
406 ShenandoahHeapRegion *r = heap->get_region(c - 1); |
382 if (r->is_humongous_continuation() || (r->new_top() == r->bottom())) { |
407 if (r->is_humongous_continuation() || (r->new_top() == r->bottom())) { |
383 // To-region candidate: record this, and continue scan |
408 // To-region candidate: record this, and continue scan |
384 to_begin = r->region_number(); |
409 to_begin = r->region_number(); |
385 continue; |
410 continue; |
386 } |
411 } |
387 |
412 |
388 if (r->is_humongous_start() && r->is_move_allowed()) { |
413 if (r->is_humongous_start() && r->is_move_allowed()) { |
389 // From-region candidate: movable humongous region |
414 // From-region candidate: movable humongous region |
390 oop old_obj = oop(r->bottom() + ShenandoahForwarding::word_size()); |
415 oop old_obj = oop(r->bottom()); |
391 size_t words_size = old_obj->size() + ShenandoahForwarding::word_size(); |
416 size_t words_size = old_obj->size(); |
392 size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize); |
417 size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize); |
393 |
418 |
394 size_t start = to_end - num_regions; |
419 size_t start = to_end - num_regions; |
395 |
420 |
396 if (start >= to_begin && start != r->region_number()) { |
421 if (start >= to_begin && start != r->region_number()) { |
397 // Fits into current window, and the move is non-trivial. Record the move then, and continue scan. |
422 // Fits into current window, and the move is non-trivial. Record the move then, and continue scan. |
398 ShenandoahForwarding::set_forwardee_raw(old_obj, heap->get_region(start)->bottom() + ShenandoahForwarding::word_size()); |
423 _preserved_marks->get(0)->push_if_necessary(old_obj, old_obj->mark_raw()); |
|
424 old_obj->forward_to(oop(heap->get_region(start)->bottom())); |
399 to_end = start; |
425 to_end = start; |
400 continue; |
426 continue; |
401 } |
427 } |
402 } |
428 } |
403 |
429 |
441 _heap(ShenandoahHeap::heap()), |
467 _heap(ShenandoahHeap::heap()), |
442 _ctx(ShenandoahHeap::heap()->complete_marking_context()) {} |
468 _ctx(ShenandoahHeap::heap()->complete_marking_context()) {} |
443 |
469 |
444 void heap_region_do(ShenandoahHeapRegion* r) { |
470 void heap_region_do(ShenandoahHeapRegion* r) { |
445 if (r->is_humongous_start()) { |
471 if (r->is_humongous_start()) { |
446 oop humongous_obj = oop(r->bottom() + ShenandoahForwarding::word_size()); |
472 oop humongous_obj = oop(r->bottom()); |
447 if (!_ctx->is_marked(humongous_obj)) { |
473 if (!_ctx->is_marked(humongous_obj)) { |
448 assert(!r->has_live(), |
474 assert(!r->has_live(), |
449 "Region " SIZE_FORMAT " is not marked, should not have live", r->region_number()); |
475 "Region " SIZE_FORMAT " is not marked, should not have live", r->region_number()); |
450 _heap->trash_humongous_region_at(r); |
476 _heap->trash_humongous_region_at(r); |
451 } else { |
477 } else { |
504 inline void do_oop_work(T* p) { |
530 inline void do_oop_work(T* p) { |
505 T o = RawAccess<>::oop_load(p); |
531 T o = RawAccess<>::oop_load(p); |
506 if (!CompressedOops::is_null(o)) { |
532 if (!CompressedOops::is_null(o)) { |
507 oop obj = CompressedOops::decode_not_null(o); |
533 oop obj = CompressedOops::decode_not_null(o); |
508 assert(_ctx->is_marked(obj), "must be marked"); |
534 assert(_ctx->is_marked(obj), "must be marked"); |
509 oop forw = oop(ShenandoahForwarding::get_forwardee_raw(obj)); |
535 if (obj->is_forwarded()) { |
510 RawAccess<IS_NOT_NULL>::oop_store(p, forw); |
536 oop forw = obj->forwardee(); |
|
537 RawAccess<IS_NOT_NULL>::oop_store(p, forw); |
|
538 } |
511 } |
539 } |
512 } |
540 } |
513 |
541 |
514 public: |
542 public: |
515 ShenandoahAdjustPointersClosure() : |
543 ShenandoahAdjustPointersClosure() : |
529 ShenandoahAdjustPointersObjectClosure() : |
557 ShenandoahAdjustPointersObjectClosure() : |
530 _heap(ShenandoahHeap::heap()) { |
558 _heap(ShenandoahHeap::heap()) { |
531 } |
559 } |
532 void do_object(oop p) { |
560 void do_object(oop p) { |
533 assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); |
561 assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); |
534 HeapWord* forw = ShenandoahForwarding::get_forwardee_raw(p); |
|
535 p->oop_iterate(&_cl); |
562 p->oop_iterate(&_cl); |
536 } |
563 } |
537 }; |
564 }; |
538 |
565 |
539 class ShenandoahAdjustPointersTask : public AbstractGangTask { |
566 class ShenandoahAdjustPointersTask : public AbstractGangTask { |
560 }; |
587 }; |
561 |
588 |
562 class ShenandoahAdjustRootPointersTask : public AbstractGangTask { |
589 class ShenandoahAdjustRootPointersTask : public AbstractGangTask { |
563 private: |
590 private: |
564 ShenandoahRootAdjuster* _rp; |
591 ShenandoahRootAdjuster* _rp; |
565 |
592 PreservedMarksSet* _preserved_marks; |
566 public: |
593 public: |
567 ShenandoahAdjustRootPointersTask(ShenandoahRootAdjuster* rp) : |
594 ShenandoahAdjustRootPointersTask(ShenandoahRootAdjuster* rp, PreservedMarksSet* preserved_marks) : |
568 AbstractGangTask("Shenandoah Adjust Root Pointers Task"), |
595 AbstractGangTask("Shenandoah Adjust Root Pointers Task"), |
569 _rp(rp) {} |
596 _rp(rp), |
|
597 _preserved_marks(preserved_marks) {} |
570 |
598 |
571 void work(uint worker_id) { |
599 void work(uint worker_id) { |
572 ShenandoahAdjustPointersClosure cl; |
600 ShenandoahAdjustPointersClosure cl; |
573 _rp->roots_do(worker_id, &cl); |
601 _rp->roots_do(worker_id, &cl); |
|
602 _preserved_marks->get(worker_id)->adjust_during_full_gc(); |
574 } |
603 } |
575 }; |
604 }; |
576 |
605 |
577 void ShenandoahMarkCompact::phase3_update_references() { |
606 void ShenandoahMarkCompact::phase3_update_references() { |
578 GCTraceTime(Info, gc, phases) time("Phase 3: Adjust pointers", _gc_timer); |
607 GCTraceTime(Info, gc, phases) time("Phase 3: Adjust pointers", _gc_timer); |
585 { |
614 { |
586 #if COMPILER2_OR_JVMCI |
615 #if COMPILER2_OR_JVMCI |
587 DerivedPointerTable::clear(); |
616 DerivedPointerTable::clear(); |
588 #endif |
617 #endif |
589 ShenandoahRootAdjuster rp(nworkers, ShenandoahPhaseTimings::full_gc_roots); |
618 ShenandoahRootAdjuster rp(nworkers, ShenandoahPhaseTimings::full_gc_roots); |
590 ShenandoahAdjustRootPointersTask task(&rp); |
619 ShenandoahAdjustRootPointersTask task(&rp, _preserved_marks); |
591 workers->run_task(&task); |
620 workers->run_task(&task); |
592 #if COMPILER2_OR_JVMCI |
621 #if COMPILER2_OR_JVMCI |
593 DerivedPointerTable::update_pointers(); |
622 DerivedPointerTable::update_pointers(); |
594 #endif |
623 #endif |
595 } |
624 } |
608 _heap(ShenandoahHeap::heap()), _worker_id(worker_id) {} |
637 _heap(ShenandoahHeap::heap()), _worker_id(worker_id) {} |
609 |
638 |
610 void do_object(oop p) { |
639 void do_object(oop p) { |
611 assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); |
640 assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); |
612 size_t size = (size_t)p->size(); |
641 size_t size = (size_t)p->size(); |
613 HeapWord* compact_to = ShenandoahForwarding::get_forwardee_raw(p); |
642 if (p->is_forwarded()) { |
614 HeapWord* compact_from = (HeapWord*) p; |
643 HeapWord* compact_from = (HeapWord*) p; |
615 if (compact_from != compact_to) { |
644 HeapWord* compact_to = (HeapWord*) p->forwardee(); |
616 Copy::aligned_conjoint_words(compact_from, compact_to, size); |
645 Copy::aligned_conjoint_words(compact_from, compact_to, size); |
617 } |
646 oop new_obj = oop(compact_to); |
618 oop new_obj = oop(compact_to); |
647 new_obj->init_mark_raw(); |
619 ShenandoahForwarding::initialize(new_obj); |
648 } |
620 } |
649 } |
621 }; |
650 }; |
622 |
651 |
623 class ShenandoahCompactObjectsTask : public AbstractGangTask { |
652 class ShenandoahCompactObjectsTask : public AbstractGangTask { |
624 private: |
653 private: |
705 // humongous regions are already compacted, and do not require further moves, which alleviates |
734 // humongous regions are already compacted, and do not require further moves, which alleviates |
706 // sliding costs. We may consider doing this in parallel in future. |
735 // sliding costs. We may consider doing this in parallel in future. |
707 |
736 |
708 ShenandoahHeap* heap = ShenandoahHeap::heap(); |
737 ShenandoahHeap* heap = ShenandoahHeap::heap(); |
709 |
738 |
710 for (size_t c = heap->num_regions() - 1; c > 0; c--) { |
739 for (size_t c = heap->num_regions(); c > 0; c--) { |
711 ShenandoahHeapRegion* r = heap->get_region(c); |
740 ShenandoahHeapRegion* r = heap->get_region(c - 1); |
712 if (r->is_humongous_start()) { |
741 if (r->is_humongous_start()) { |
713 oop old_obj = oop(r->bottom() + ShenandoahForwarding::word_size()); |
742 oop old_obj = oop(r->bottom()); |
714 size_t words_size = old_obj->size() + ShenandoahForwarding::word_size(); |
743 if (!old_obj->is_forwarded()) { |
|
744 // No need to move the object, it stays at the same slot |
|
745 continue; |
|
746 } |
|
747 size_t words_size = old_obj->size(); |
715 size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize); |
748 size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize); |
716 |
749 |
717 size_t old_start = r->region_number(); |
750 size_t old_start = r->region_number(); |
718 size_t old_end = old_start + num_regions - 1; |
751 size_t old_end = old_start + num_regions - 1; |
719 size_t new_start = heap->heap_region_index_containing(ShenandoahForwarding::get_forwardee_raw(old_obj)); |
752 size_t new_start = heap->heap_region_index_containing(old_obj->forwardee()); |
720 size_t new_end = new_start + num_regions - 1; |
753 size_t new_end = new_start + num_regions - 1; |
721 |
754 assert(old_start != new_start, "must be real move"); |
722 if (old_start == new_start) { |
|
723 // No need to move the object, it stays at the same slot |
|
724 continue; |
|
725 } |
|
726 |
|
727 assert (r->is_move_allowed(), "should be movable"); |
755 assert (r->is_move_allowed(), "should be movable"); |
728 |
756 |
729 Copy::aligned_conjoint_words(heap->get_region(old_start)->bottom(), |
757 Copy::aligned_conjoint_words(heap->get_region(old_start)->bottom(), |
730 heap->get_region(new_start)->bottom(), |
758 heap->get_region(new_start)->bottom(), |
731 ShenandoahHeapRegion::region_size_words()*num_regions); |
759 ShenandoahHeapRegion::region_size_words()*num_regions); |
732 |
760 |
733 oop new_obj = oop(heap->get_region(new_start)->bottom() + ShenandoahForwarding::word_size()); |
761 oop new_obj = oop(heap->get_region(new_start)->bottom()); |
734 ShenandoahForwarding::initialize(new_obj); |
762 new_obj->init_mark_raw(); |
735 |
763 |
736 { |
764 { |
737 for (size_t c = old_start; c <= old_end; c++) { |
765 for (size_t c = old_start; c <= old_end; c++) { |
738 ShenandoahHeapRegion* r = heap->get_region(c); |
766 ShenandoahHeapRegion* r = heap->get_region(c); |
739 r->make_regular_bypass(); |
767 r->make_regular_bypass(); |