< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp

Print this page
@@ -1,8 +1,9 @@
  /*
   * 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.

@@ -23,10 +24,11 @@
   *
   */
  
  #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"

@@ -39,13 +41,17 @@
    _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.

@@ -82,34 +88,62 @@
  
  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++;
-   _garbage += r->garbage();
+   _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

@@ -149,11 +183,15 @@
  
    return nullptr;
  }
  
  void ShenandoahCollectionSet::print_on(outputStream* out) const {
-   out->print_cr("Collection Set : " SIZE_FORMAT "", count());
+   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 >