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/brooksPointer.hpp"
27 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
28 #include "gc/shenandoah/shenandoahHeap.hpp"
29 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
30 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
31 #include "gc/shared/space.inline.hpp"
32 #include "memory/universe.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/java.hpp"
35 #include "runtime/mutexLocker.hpp"
36 #include "runtime/os.hpp"
37 #include "runtime/safepoint.hpp"
38
39 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
40 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
41 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
42 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
43 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
44 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
45 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
46 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
47 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
48
49 // start with 1, reserve 0 for uninitialized value
50 uint64_t ShenandoahHeapRegion::AllocSeqNum = 1;
51
52 ShenandoahHeapRegion::ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start,
53 size_t size_words, size_t index, bool committed) :
54 _heap(heap),
55 _pacer(ShenandoahPacing ? heap->pacer() : NULL),
56 _region_number(index),
57 _live_data(0),
58 _tlab_allocs(0),
59 _gclab_allocs(0),
60 _shared_allocs(0),
61 _reserved(MemRegion(start, size_words)),
62 _root(false),
63 _new_top(NULL),
64 _seqnum_first_alloc_mutator(0),
65 _seqnum_last_alloc_mutator(0),
66 _seqnum_first_alloc_gc(0),
67 _seqnum_last_alloc_gc(0),
68 _state(committed ? _empty_committed : _empty_uncommitted),
69 _empty_time(os::elapsedTime()),
70 _initialized(false),
71 _critical_pins(0) {
72
73 ContiguousSpace::initialize(_reserved, true, committed);
74 }
75
76 size_t ShenandoahHeapRegion::region_number() const {
77 return _region_number;
78 }
79
80 void ShenandoahHeapRegion::report_illegal_transition(const char *method) {
81 ResourceMark rm;
82 stringStream ss;
418 break;
419 case _pinned:
420 st->print("|P ");
421 break;
422 case _pinned_cset:
423 st->print("|CSP");
424 break;
425 default:
426 ShouldNotReachHere();
427 }
428 st->print("|BTE " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12),
429 p2i(bottom()), p2i(top()), p2i(end()));
430 st->print("|TAMS " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12),
431 p2i(_heap->complete_top_at_mark_start(_bottom)),
432 p2i(_heap->next_top_at_mark_start(_bottom)));
433 st->print("|U %3d%%", (int) ((double) used() * 100 / capacity()));
434 st->print("|T %3d%%", (int) ((double) get_tlab_allocs() * 100 / capacity()));
435 st->print("|G %3d%%", (int) ((double) get_gclab_allocs() * 100 / capacity()));
436 st->print("|S %3d%%", (int) ((double) get_shared_allocs() * 100 / capacity()));
437 st->print("|L %3d%%", (int) ((double) get_live_data_bytes() * 100 / capacity()));
438 if (is_root()) {
439 st->print("|R");
440 } else {
441 st->print("| ");
442 }
443 st->print("|CP " SIZE_FORMAT_W(3), _critical_pins);
444 st->print("|SN " UINT64_FORMAT_HEX_W(12) ", " UINT64_FORMAT_HEX_W(8) ", " UINT64_FORMAT_HEX_W(8) ", " UINT64_FORMAT_HEX_W(8),
445 seqnum_first_alloc_mutator(), seqnum_last_alloc_mutator(),
446 seqnum_first_alloc_gc(), seqnum_last_alloc_gc());
447 st->cr();
448 }
449
450 void ShenandoahHeapRegion::oop_iterate(ExtendedOopClosure* blk) {
451 if (!is_active()) return;
452 if (is_humongous()) {
453 oop_iterate_humongous(blk);
454 } else {
455 oop_iterate_objects(blk);
456 }
457 }
458
488 ShenandoahHeapRegion* ShenandoahHeapRegion::humongous_start_region() const {
489 assert(is_humongous(), "Must be a part of the humongous region");
490 size_t reg_num = region_number();
491 ShenandoahHeapRegion* r = const_cast<ShenandoahHeapRegion*>(this);
492 while (!r->is_humongous_start()) {
493 assert(reg_num > 0, "Sanity");
494 reg_num --;
495 r = _heap->get_region(reg_num);
496 assert(r->is_humongous(), "Must be a part of the humongous region");
497 }
498 assert(r->is_humongous_start(), "Must be");
499 return r;
500 }
501
502 void ShenandoahHeapRegion::recycle() {
503 ContiguousSpace::clear(false);
504 if (ZapUnusedHeapArea) {
505 ContiguousSpace::mangle_unused_area_complete();
506 }
507 clear_live_data();
508 _root = false;
509
510 reset_alloc_metadata();
511
512 // Reset C-TAMS pointer to ensure size-based iteration, everything
513 // in that regions is going to be new objects.
514 _heap->set_complete_top_at_mark_start(bottom(), bottom());
515 // We can only safely reset the C-TAMS pointer if the bitmap is clear for that region.
516 assert(_heap->is_complete_bitmap_clear_range(bottom(), end()), "must be clear");
517
518 if (UseShenandoahMatrix) {
519 _heap->connection_matrix()->clear_region(region_number());
520 }
521
522 make_empty();
523 }
524
525 HeapWord* ShenandoahHeapRegion::block_start_const(const void* p) const {
526 assert(MemRegion(bottom(), end()).contains(p),
527 "p ("PTR_FORMAT") not in space ["PTR_FORMAT", "PTR_FORMAT")",
528 p2i(p), p2i(bottom()), p2i(end()));
529 if (p >= top()) {
530 return top();
531 } else {
532 HeapWord* last = bottom() + BrooksPointer::word_size();
533 HeapWord* cur = last;
534 while (cur <= p) {
535 last = cur;
536 cur += oop(cur)->size() + BrooksPointer::word_size();
|
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/brooksPointer.hpp"
27 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
28 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
29 #include "gc/shenandoah/shenandoahHeap.hpp"
30 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
31 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
32 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
33 #include "gc/shared/space.inline.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::RegionSizeBytes = 0;
42 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
43 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
44 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
45 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
46 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
47 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
48 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
49 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
50
51 // start with 1, reserve 0 for uninitialized value
52 uint64_t ShenandoahHeapRegion::AllocSeqNum = 1;
53
54 ShenandoahHeapRegion::ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start,
55 size_t size_words, size_t index, bool committed) :
56 _heap(heap),
57 _pacer(ShenandoahPacing ? heap->pacer() : NULL),
58 _region_number(index),
59 _live_data(0),
60 _tlab_allocs(0),
61 _gclab_allocs(0),
62 _shared_allocs(0),
63 _reserved(MemRegion(start, size_words)),
64 _new_top(NULL),
65 _seqnum_first_alloc_mutator(0),
66 _seqnum_last_alloc_mutator(0),
67 _seqnum_first_alloc_gc(0),
68 _seqnum_last_alloc_gc(0),
69 _state(committed ? _empty_committed : _empty_uncommitted),
70 _empty_time(os::elapsedTime()),
71 _initialized(false),
72 _critical_pins(0) {
73
74 ContiguousSpace::initialize(_reserved, true, committed);
75 }
76
77 size_t ShenandoahHeapRegion::region_number() const {
78 return _region_number;
79 }
80
81 void ShenandoahHeapRegion::report_illegal_transition(const char *method) {
82 ResourceMark rm;
83 stringStream ss;
419 break;
420 case _pinned:
421 st->print("|P ");
422 break;
423 case _pinned_cset:
424 st->print("|CSP");
425 break;
426 default:
427 ShouldNotReachHere();
428 }
429 st->print("|BTE " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12),
430 p2i(bottom()), p2i(top()), p2i(end()));
431 st->print("|TAMS " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12),
432 p2i(_heap->complete_top_at_mark_start(_bottom)),
433 p2i(_heap->next_top_at_mark_start(_bottom)));
434 st->print("|U %3d%%", (int) ((double) used() * 100 / capacity()));
435 st->print("|T %3d%%", (int) ((double) get_tlab_allocs() * 100 / capacity()));
436 st->print("|G %3d%%", (int) ((double) get_gclab_allocs() * 100 / capacity()));
437 st->print("|S %3d%%", (int) ((double) get_shared_allocs() * 100 / capacity()));
438 st->print("|L %3d%%", (int) ((double) get_live_data_bytes() * 100 / capacity()));
439 if (_heap->traversal_gc() != NULL && _heap->traversal_gc()->root_regions()->is_in(region_number())) {
440 st->print("|R");
441 } else {
442 st->print("| ");
443 }
444 st->print("|CP " SIZE_FORMAT_W(3), _critical_pins);
445 st->print("|SN " UINT64_FORMAT_HEX_W(12) ", " UINT64_FORMAT_HEX_W(8) ", " UINT64_FORMAT_HEX_W(8) ", " UINT64_FORMAT_HEX_W(8),
446 seqnum_first_alloc_mutator(), seqnum_last_alloc_mutator(),
447 seqnum_first_alloc_gc(), seqnum_last_alloc_gc());
448 st->cr();
449 }
450
451 void ShenandoahHeapRegion::oop_iterate(ExtendedOopClosure* blk) {
452 if (!is_active()) return;
453 if (is_humongous()) {
454 oop_iterate_humongous(blk);
455 } else {
456 oop_iterate_objects(blk);
457 }
458 }
459
489 ShenandoahHeapRegion* ShenandoahHeapRegion::humongous_start_region() const {
490 assert(is_humongous(), "Must be a part of the humongous region");
491 size_t reg_num = region_number();
492 ShenandoahHeapRegion* r = const_cast<ShenandoahHeapRegion*>(this);
493 while (!r->is_humongous_start()) {
494 assert(reg_num > 0, "Sanity");
495 reg_num --;
496 r = _heap->get_region(reg_num);
497 assert(r->is_humongous(), "Must be a part of the humongous region");
498 }
499 assert(r->is_humongous_start(), "Must be");
500 return r;
501 }
502
503 void ShenandoahHeapRegion::recycle() {
504 ContiguousSpace::clear(false);
505 if (ZapUnusedHeapArea) {
506 ContiguousSpace::mangle_unused_area_complete();
507 }
508 clear_live_data();
509
510 reset_alloc_metadata();
511
512 // Reset C-TAMS pointer to ensure size-based iteration, everything
513 // in that regions is going to be new objects.
514 if (ShenandoahRecycleClearsBitmap && !_heap->is_full_gc_in_progress()) {
515 HeapWord* r_bottom = bottom();
516 HeapWord* top = _heap->complete_top_at_mark_start(r_bottom);
517 if (top > r_bottom) {
518 _heap->complete_mark_bit_map()->clear_range_large(MemRegion(r_bottom, top));
519 }
520
521 assert(_heap->is_next_bitmap_clear_range(bottom(), end()), "must be clear");
522 _heap->set_next_top_at_mark_start(bottom(), bottom());
523 }
524
525 // We can only safely reset the C-TAMS pointer if the bitmap is clear for that region.
526 assert(_heap->is_complete_bitmap_clear_range(bottom(), end()), "must be clear");
527
528 _heap->set_complete_top_at_mark_start(bottom(), bottom());
529
530 if (UseShenandoahMatrix) {
531 _heap->connection_matrix()->clear_region(region_number());
532 }
533
534 make_empty();
535 }
536
537 HeapWord* ShenandoahHeapRegion::block_start_const(const void* p) const {
538 assert(MemRegion(bottom(), end()).contains(p),
539 "p ("PTR_FORMAT") not in space ["PTR_FORMAT", "PTR_FORMAT")",
540 p2i(p), p2i(bottom()), p2i(end()));
541 if (p >= top()) {
542 return top();
543 } else {
544 HeapWord* last = bottom() + BrooksPointer::word_size();
545 HeapWord* cur = last;
546 while (cur <= p) {
547 last = cur;
548 cur += oop(cur)->size() + BrooksPointer::word_size();
|