< prev index next > src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp
Print this page
/*
* Copyright (c) 2016, 2023, Red Hat, Inc. All rights reserved.
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*/
#include "precompiled.hpp"
+ #include "gc/shenandoah/shenandoahAgeCensus.hpp"
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
#include "gc/shenandoah/shenandoahUtils.hpp"
_region_size_bytes_shift(ShenandoahHeapRegion::region_size_bytes_shift()),
_map_space(space),
_cset_map(_map_space.base() + ((uintx)heap_base >> _region_size_bytes_shift)),
_biased_cset_map(_map_space.base()),
_heap(heap),
+ _has_old_regions(false),
_garbage(0),
_used(0),
+ _live(0),
_region_count(0),
+ _old_garbage(0),
+ _preselected_regions(nullptr),
_current_index(0) {
// The collection set map is reserved to cover the entire heap *and* zero addresses.
// This is needed to accept in-cset checks for both heap oops and nulls, freeing
// high-performance code from checking for null first.
void ShenandoahCollectionSet::add_region(ShenandoahHeapRegion* r) {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
assert(Thread::current()->is_VM_thread(), "Must be VMThread");
assert(!is_in(r), "Already in collection set");
_cset_map[r->index()] = 1;
_region_count++;
! _garbage += r->garbage();
_used += r->used();
!
// Update the region status too. State transition would be checked internally.
r->make_cset();
}
void ShenandoahCollectionSet::clear() {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
Copy::zero_to_bytes(_cset_map, _map_size);
#ifdef ASSERT
for (size_t index = 0; index < _heap->num_regions(); index ++) {
assert (!_heap->get_region(index)->is_cset(), "should have been cleared before");
}
#endif
_garbage = 0;
_used = 0;
_region_count = 0;
_current_index = 0;
}
ShenandoahHeapRegion* ShenandoahCollectionSet::claim_next() {
// This code is optimized for the case when collection set contains only
// a few regions. In this case, it is more constructive to check for is_in
void ShenandoahCollectionSet::add_region(ShenandoahHeapRegion* r) {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
assert(Thread::current()->is_VM_thread(), "Must be VMThread");
assert(!is_in(r), "Already in collection set");
+ assert(!r->is_humongous(), "Only add regular regions to the collection set");
+
_cset_map[r->index()] = 1;
+ size_t live = r->get_live_data_bytes();
+ size_t garbage = r->garbage();
+ size_t free = r->free();
+ if (r->is_young()) {
+ _young_bytes_to_evacuate += live;
+ _young_available_bytes_collected += free;
+ if (ShenandoahHeap::heap()->mode()->is_generational() && r->age() >= ShenandoahGenerationalHeap::heap()->age_census()->tenuring_threshold()) {
+ _young_bytes_to_promote += live;
+ }
+ } else if (r->is_old()) {
+ _old_bytes_to_evacuate += live;
+ _old_garbage += garbage;
+ }
+
_region_count++;
! _has_old_regions |= r->is_old();
+ _garbage += garbage;
_used += r->used();
! _live += live;
// Update the region status too. State transition would be checked internally.
r->make_cset();
}
void ShenandoahCollectionSet::clear() {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
+
Copy::zero_to_bytes(_cset_map, _map_size);
#ifdef ASSERT
for (size_t index = 0; index < _heap->num_regions(); index ++) {
assert (!_heap->get_region(index)->is_cset(), "should have been cleared before");
}
#endif
_garbage = 0;
+ _old_garbage = 0;
_used = 0;
+ _live = 0;
_region_count = 0;
_current_index = 0;
+
+ _young_bytes_to_evacuate = 0;
+ _young_bytes_to_promote = 0;
+ _old_bytes_to_evacuate = 0;
+
+ _young_available_bytes_collected = 0;
+
+ _has_old_regions = false;
}
ShenandoahHeapRegion* ShenandoahCollectionSet::claim_next() {
// This code is optimized for the case when collection set contains only
// a few regions. In this case, it is more constructive to check for is_in
return nullptr;
}
void ShenandoahCollectionSet::print_on(outputStream* out) const {
! out->print_cr("Collection Set : " SIZE_FORMAT "", count());
debug_only(size_t regions = 0;)
for (size_t index = 0; index < _heap->num_regions(); index ++) {
if (is_in(index)) {
_heap->get_region(index)->print_on(out);
return nullptr;
}
void ShenandoahCollectionSet::print_on(outputStream* out) const {
! out->print_cr("Collection Set: Regions: "
+ SIZE_FORMAT ", Garbage: " SIZE_FORMAT "%s, Live: " SIZE_FORMAT "%s, Used: " SIZE_FORMAT "%s", count(),
+ byte_size_in_proper_unit(garbage()), proper_unit_for_byte_size(garbage()),
+ byte_size_in_proper_unit(live()), proper_unit_for_byte_size(live()),
+ byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used()));
debug_only(size_t regions = 0;)
for (size_t index = 0; index < _heap->num_regions(); index ++) {
if (is_in(index)) {
_heap->get_region(index)->print_on(out);
< prev index next >