6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "memory/allocation.hpp"
26 #include "gc/shenandoah/shenandoahForwarding.hpp"
27 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
32 #include "gc/shared/space.inline.hpp"
33 #include "memory/iterator.inline.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "memory/universe.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "runtime/java.hpp"
38 #include "runtime/mutexLocker.hpp"
39 #include "runtime/os.hpp"
40 #include "runtime/safepoint.hpp"
41
42 size_t ShenandoahHeapRegion::RegionCount = 0;
43 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
44 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
45 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
46 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
435 st->print("|S " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs()));
436 st->print("|L " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes()));
437 st->print("|CP " SIZE_FORMAT_W(3), _critical_pins);
438 st->print("|SN " UINT64_FORMAT_X_W(12) ", " UINT64_FORMAT_X_W(8) ", " UINT64_FORMAT_X_W(8) ", " UINT64_FORMAT_X_W(8),
439 seqnum_first_alloc_mutator(), seqnum_last_alloc_mutator(),
440 seqnum_first_alloc_gc(), seqnum_last_alloc_gc());
441 st->cr();
442 }
443
444 void ShenandoahHeapRegion::oop_iterate(OopIterateClosure* blk) {
445 if (!is_active()) return;
446 if (is_humongous()) {
447 oop_iterate_humongous(blk);
448 } else {
449 oop_iterate_objects(blk);
450 }
451 }
452
453 void ShenandoahHeapRegion::oop_iterate_objects(OopIterateClosure* blk) {
454 assert(! is_humongous(), "no humongous region here");
455 HeapWord* obj_addr = bottom() + ShenandoahForwarding::word_size();
456 HeapWord* t = top();
457 // Could call objects iterate, but this is easier.
458 while (obj_addr < t) {
459 oop obj = oop(obj_addr);
460 obj_addr += obj->oop_iterate_size(blk) + ShenandoahForwarding::word_size();
461 }
462 }
463
464 void ShenandoahHeapRegion::oop_iterate_humongous(OopIterateClosure* blk) {
465 assert(is_humongous(), "only humongous region here");
466 // Find head.
467 ShenandoahHeapRegion* r = humongous_start_region();
468 assert(r->is_humongous_start(), "need humongous head here");
469 oop obj = oop(r->bottom() + ShenandoahForwarding::word_size());
470 obj->oop_iterate(blk, MemRegion(bottom(), top()));
471 }
472
473 ShenandoahHeapRegion* ShenandoahHeapRegion::humongous_start_region() const {
474 assert(is_humongous(), "Must be a part of the humongous region");
475 size_t reg_num = region_number();
476 ShenandoahHeapRegion* r = const_cast<ShenandoahHeapRegion*>(this);
477 while (!r->is_humongous_start()) {
478 assert(reg_num > 0, "Sanity");
479 reg_num --;
480 r = _heap->get_region(reg_num);
481 assert(r->is_humongous(), "Must be a part of the humongous region");
482 }
483 assert(r->is_humongous_start(), "Must be");
484 return r;
485 }
486
487 void ShenandoahHeapRegion::recycle() {
488 ContiguousSpace::clear(false);
489 if (ZapUnusedHeapArea) {
490 ContiguousSpace::mangle_unused_area_complete();
491 }
492 clear_live_data();
493
494 reset_alloc_metadata();
495
496 _heap->marking_context()->reset_top_at_mark_start(this);
497
498 make_empty();
499 }
500
501 HeapWord* ShenandoahHeapRegion::block_start_const(const void* p) const {
502 assert(MemRegion(bottom(), end()).contains(p),
503 "p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
504 p2i(p), p2i(bottom()), p2i(end()));
505 if (p >= top()) {
506 return top();
507 } else {
508 HeapWord* last = bottom() + ShenandoahForwarding::word_size();
509 HeapWord* cur = last;
510 while (cur <= p) {
511 last = cur;
512 cur += oop(cur)->size() + ShenandoahForwarding::word_size();
513 }
514 shenandoah_assert_correct(NULL, oop(last));
515 return last;
516 }
517 }
518
519 void ShenandoahHeapRegion::setup_sizes(size_t initial_heap_size, size_t max_heap_size) {
520 // Absolute minimums we should not ever break.
521 static const size_t MIN_REGION_SIZE = 256*K;
522
523 if (FLAG_IS_DEFAULT(ShenandoahMinRegionSize)) {
524 FLAG_SET_DEFAULT(ShenandoahMinRegionSize, MIN_REGION_SIZE);
525 }
526
527 size_t region_size;
528 if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) {
529 if (ShenandoahMinRegionSize > initial_heap_size / MIN_NUM_REGIONS) {
530 err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
531 "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "K).",
532 initial_heap_size/K, MIN_NUM_REGIONS, ShenandoahMinRegionSize/K);
|
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "memory/allocation.hpp"
26 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
28 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
29 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
30 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
31 #include "gc/shared/space.inline.hpp"
32 #include "memory/iterator.inline.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "memory/universe.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "runtime/java.hpp"
37 #include "runtime/mutexLocker.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/safepoint.hpp"
40
41 size_t ShenandoahHeapRegion::RegionCount = 0;
42 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
43 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
44 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
45 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
434 st->print("|S " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs()));
435 st->print("|L " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes()));
436 st->print("|CP " SIZE_FORMAT_W(3), _critical_pins);
437 st->print("|SN " UINT64_FORMAT_X_W(12) ", " UINT64_FORMAT_X_W(8) ", " UINT64_FORMAT_X_W(8) ", " UINT64_FORMAT_X_W(8),
438 seqnum_first_alloc_mutator(), seqnum_last_alloc_mutator(),
439 seqnum_first_alloc_gc(), seqnum_last_alloc_gc());
440 st->cr();
441 }
442
443 void ShenandoahHeapRegion::oop_iterate(OopIterateClosure* blk) {
444 if (!is_active()) return;
445 if (is_humongous()) {
446 oop_iterate_humongous(blk);
447 } else {
448 oop_iterate_objects(blk);
449 }
450 }
451
452 void ShenandoahHeapRegion::oop_iterate_objects(OopIterateClosure* blk) {
453 assert(! is_humongous(), "no humongous region here");
454 HeapWord* obj_addr = bottom();
455 HeapWord* t = top();
456 // Could call objects iterate, but this is easier.
457 while (obj_addr < t) {
458 oop obj = oop(obj_addr);
459 obj_addr += obj->oop_iterate_size(blk);
460 }
461 }
462
463 void ShenandoahHeapRegion::oop_iterate_humongous(OopIterateClosure* blk) {
464 assert(is_humongous(), "only humongous region here");
465 // Find head.
466 ShenandoahHeapRegion* r = humongous_start_region();
467 assert(r->is_humongous_start(), "need humongous head here");
468 oop obj = oop(r->bottom());
469 obj->oop_iterate(blk, MemRegion(bottom(), top()));
470 }
471
472 ShenandoahHeapRegion* ShenandoahHeapRegion::humongous_start_region() const {
473 assert(is_humongous(), "Must be a part of the humongous region");
474 size_t reg_num = region_number();
475 ShenandoahHeapRegion* r = const_cast<ShenandoahHeapRegion*>(this);
476 while (!r->is_humongous_start()) {
477 assert(reg_num > 0, "Sanity");
478 reg_num --;
479 r = _heap->get_region(reg_num);
480 assert(r->is_humongous(), "Must be a part of the humongous region");
481 }
482 assert(r->is_humongous_start(), "Must be");
483 return r;
484 }
485
486 void ShenandoahHeapRegion::recycle() {
487 ContiguousSpace::clear(false);
488 if (ZapUnusedHeapArea) {
489 ContiguousSpace::mangle_unused_area_complete();
490 }
491 clear_live_data();
492
493 reset_alloc_metadata();
494
495 _heap->marking_context()->reset_top_at_mark_start(this);
496
497 make_empty();
498 }
499
500 HeapWord* ShenandoahHeapRegion::block_start_const(const void* p) const {
501 assert(MemRegion(bottom(), end()).contains(p),
502 "p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
503 p2i(p), p2i(bottom()), p2i(end()));
504 if (p >= top()) {
505 return top();
506 } else {
507 HeapWord* last = bottom();
508 HeapWord* cur = last;
509 while (cur <= p) {
510 last = cur;
511 cur += oop(cur)->size();
512 }
513 shenandoah_assert_correct(NULL, oop(last));
514 return last;
515 }
516 }
517
518 void ShenandoahHeapRegion::setup_sizes(size_t initial_heap_size, size_t max_heap_size) {
519 // Absolute minimums we should not ever break.
520 static const size_t MIN_REGION_SIZE = 256*K;
521
522 if (FLAG_IS_DEFAULT(ShenandoahMinRegionSize)) {
523 FLAG_SET_DEFAULT(ShenandoahMinRegionSize, MIN_REGION_SIZE);
524 }
525
526 size_t region_size;
527 if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) {
528 if (ShenandoahMinRegionSize > initial_heap_size / MIN_NUM_REGIONS) {
529 err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
530 "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "K).",
531 initial_heap_size/K, MIN_NUM_REGIONS, ShenandoahMinRegionSize/K);
|