blob: 242acbdea8cea8b2327613a6eb786a5da213f87b [file] [edit]
/*
* 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHGENERATION_HPP
#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHGENERATION_HPP
#include "gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp"
#include "gc/shenandoah/shenandoahAffiliation.hpp"
#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahLock.hpp"
#include "gc/shenandoah/shenandoahMarkingContext.hpp"
#include "memory/allocation.hpp"
class ShenandoahCollectionSet;
class ShenandoahHeap;
class ShenandoahHeapRegion;
class ShenandoahHeapRegionClosure;
class ShenandoahHeuristics;
class ShenandoahMode;
class ShenandoahReferenceProcessor;
class ShenandoahGeneration : public CHeapObj<mtGC>, public ShenandoahSpaceInfo {
friend class VMStructs;
private:
ShenandoahGenerationType const _type;
// Marking task queues and completeness
ShenandoahObjToScanQueueSet* _task_queues;
ShenandoahSharedFlag _is_marking_complete;
ShenandoahReferenceProcessor* const _ref_processor;
volatile size_t _affiliated_region_count;
// How much free memory is left in the last region of humongous objects.
// This is _not_ included in used, but it _is_ deducted from available,
// which gives the heuristics a more accurate view of how much memory remains
// for allocation. This figure is also included the heap status logging.
// The units are bytes. The value is only changed on a safepoint or under the
// heap lock.
size_t _humongous_waste;
// Bytes reserved within this generation to hold evacuated objects from the collection set
size_t _evacuation_reserve;
protected:
// Usage
volatile size_t _used;
volatile size_t _bytes_allocated_since_gc_start;
size_t _max_capacity;
size_t _soft_max_capacity;
ShenandoahHeuristics* _heuristics;
private:
// Compute evacuation budgets prior to choosing collection set.
void compute_evacuation_budgets(ShenandoahHeap* heap);
// Adjust evacuation budgets after choosing collection set.
void adjust_evacuation_budgets(ShenandoahHeap* heap,
ShenandoahCollectionSet* collection_set);
// Preselect for possible inclusion into the collection set exactly the most
// garbage-dense regions, including those that satisfy criteria 1 & 2 below,
// and whose live bytes will fit within old_available budget:
// Criterion 1. region age >= tenuring threshold
// Criterion 2. region garbage percentage > ShenandoahOldGarbageThreshold
//
// Identifies regions eligible for promotion in place,
// being those of at least tenuring_threshold age that have lower garbage
// density.
//
// Updates promotion_potential and pad_for_promote_in_place fields
// of the heap. Returns bytes of live object memory in the preselected
// regions, which are marked in the preselected_regions() indicator
// array of the heap's collection set, which should be initialized
// to false.
size_t select_aged_regions(size_t old_available);
size_t available(size_t capacity) const;
public:
ShenandoahGeneration(ShenandoahGenerationType type,
uint max_workers,
size_t max_capacity,
size_t soft_max_capacity);
~ShenandoahGeneration();
bool is_young() const { return _type == YOUNG; }
bool is_old() const { return _type == OLD; }
bool is_global() const { return _type == GLOBAL || _type == NON_GEN; }
// see description in field declaration
void set_evacuation_reserve(size_t new_val);
size_t get_evacuation_reserve() const;
void augment_evacuation_reserve(size_t increment);
inline ShenandoahGenerationType type() const { return _type; }
virtual ShenandoahHeuristics* heuristics() const { return _heuristics; }
ShenandoahReferenceProcessor* ref_processor() { return _ref_processor; }
virtual ShenandoahHeuristics* initialize_heuristics(ShenandoahMode* gc_mode);
size_t soft_max_capacity() const override { return _soft_max_capacity; }
size_t max_capacity() const override { return _max_capacity; }
virtual size_t used_regions() const;
virtual size_t used_regions_size() const;
virtual size_t free_unaffiliated_regions() const;
size_t used() const override { return Atomic::load(&_used); }
size_t available() const override;
size_t available_with_reserve() const;
size_t used_including_humongous_waste() const {
return used() + get_humongous_waste();
}
// Returns the memory available based on the _soft_ max heap capacity (soft_max_heap - used).
// The soft max heap size may be adjusted lower than the max heap size to cause the trigger
// to believe it has less memory available than is _really_ available. Lowering the soft
// max heap size will cause the adaptive heuristic to run more frequent cycles.
size_t soft_available() const override;
size_t bytes_allocated_since_gc_start() const override;
void reset_bytes_allocated_since_gc_start();
void increase_allocated(size_t bytes);
// These methods change the capacity of the generation by adding or subtracting the given number of bytes from the current
// capacity, returning the capacity of the generation following the change.
size_t increase_capacity(size_t increment);
size_t decrease_capacity(size_t decrement);
// Set the capacity of the generation, returning the value set
size_t set_capacity(size_t byte_size);
void log_status(const char* msg) const;
// Used directly by FullGC
template <bool FOR_CURRENT_CYCLE, bool FULL_GC = false>
void reset_mark_bitmap();
// Used by concurrent and degenerated GC to reset remembered set.
void swap_card_tables();
// Update the read cards with the state of the write table (write table is not cleared).
void merge_write_table();
// Called before init mark, expected to prepare regions for marking.
virtual void prepare_gc();
// Called during final mark, chooses collection set, rebuilds free set.
virtual void prepare_regions_and_collection_set(bool concurrent);
// Cancel marking (used by Full collect and when cancelling cycle).
virtual void cancel_marking();
virtual bool contains(ShenandoahAffiliation affiliation) const = 0;
// Return true if this region is affiliated with this generation.
virtual bool contains(ShenandoahHeapRegion* region) const = 0;
// Return true if this object is affiliated with this generation.
virtual bool contains(oop obj) const = 0;
// Apply closure to all regions affiliated with this generation.
virtual void parallel_heap_region_iterate(ShenandoahHeapRegionClosure* cl) = 0;
// Apply closure to all regions affiliated with this generation (include free regions);
virtual void parallel_heap_region_iterate_free(ShenandoahHeapRegionClosure* cl);
// Apply closure to all regions affiliated with this generation (single threaded).
virtual void heap_region_iterate(ShenandoahHeapRegionClosure* cl) = 0;
// This is public to support cancellation of marking when a Full cycle is started.
virtual void set_concurrent_mark_in_progress(bool in_progress) = 0;
// Check the bitmap only for regions belong to this generation.
bool is_bitmap_clear();
// We need to track the status of marking for different generations.
bool is_mark_complete() { return _is_marking_complete.is_set(); }
virtual void set_mark_complete();
virtual void set_mark_incomplete();
ShenandoahMarkingContext* complete_marking_context();
// Task queues
ShenandoahObjToScanQueueSet* task_queues() const { return _task_queues; }
virtual void reserve_task_queues(uint workers);
virtual ShenandoahObjToScanQueueSet* old_gen_task_queues() const;
// Scan remembered set at start of concurrent young-gen marking.
void scan_remembered_set(bool is_concurrent);
// Return the updated value of affiliated_region_count
size_t increment_affiliated_region_count();
// Return the updated value of affiliated_region_count
size_t decrement_affiliated_region_count();
// Same as decrement_affiliated_region_count, but w/o the need to hold heap lock before being called.
size_t decrement_affiliated_region_count_without_lock();
// Return the updated value of affiliated_region_count
size_t increase_affiliated_region_count(size_t delta);
// Return the updated value of affiliated_region_count
size_t decrease_affiliated_region_count(size_t delta);
void establish_usage(size_t num_regions, size_t num_bytes, size_t humongous_waste);
void increase_used(size_t bytes);
void decrease_used(size_t bytes);
void increase_humongous_waste(size_t bytes);
void decrease_humongous_waste(size_t bytes);
size_t get_humongous_waste() const { return _humongous_waste; }
virtual bool is_concurrent_mark_in_progress() = 0;
void confirm_heuristics_mode();
virtual void record_success_concurrent(bool abbreviated);
};
#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHGENERATION_HPP