Path: blob/master/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
40961 views
/*1* Copyright (c) 2013, 2021, Red Hat, Inc. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 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 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHHEAP_HPP25#define SHARE_GC_SHENANDOAH_SHENANDOAHHEAP_HPP2627#include "gc/shared/markBitMap.hpp"28#include "gc/shared/softRefPolicy.hpp"29#include "gc/shared/collectedHeap.hpp"30#include "gc/shenandoah/shenandoahAsserts.hpp"31#include "gc/shenandoah/shenandoahAllocRequest.hpp"32#include "gc/shenandoah/shenandoahLock.hpp"33#include "gc/shenandoah/shenandoahEvacOOMHandler.hpp"34#include "gc/shenandoah/shenandoahPadding.hpp"35#include "gc/shenandoah/shenandoahSharedVariables.hpp"36#include "gc/shenandoah/shenandoahUnload.hpp"37#include "memory/metaspace.hpp"38#include "services/memoryManager.hpp"39#include "utilities/globalDefinitions.hpp"40#include "utilities/stack.hpp"4142class ConcurrentGCTimer;43class ObjectIterateScanRootClosure;44class ShenandoahCollectorPolicy;45class ShenandoahControlThread;46class ShenandoahGCSession;47class ShenandoahGCStateResetter;48class ShenandoahHeuristics;49class ShenandoahMarkingContext;50class ShenandoahMode;51class ShenandoahPhaseTimings;52class ShenandoahHeap;53class ShenandoahHeapRegion;54class ShenandoahHeapRegionClosure;55class ShenandoahCollectionSet;56class ShenandoahFreeSet;57class ShenandoahConcurrentMark;58class ShenandoahFullGC;59class ShenandoahMonitoringSupport;60class ShenandoahPacer;61class ShenandoahReferenceProcessor;62class ShenandoahVerifier;63class ShenandoahWorkGang;64class VMStructs;6566// Used for buffering per-region liveness data.67// Needed since ShenandoahHeapRegion uses atomics to update liveness.68// The ShenandoahHeap array has max-workers elements, each of which is an array of69// uint16_t * max_regions. The choice of uint16_t is not accidental:70// there is a tradeoff between static/dynamic footprint that translates71// into cache pressure (which is already high during marking), and72// too many atomic updates. uint32_t is too large, uint8_t is too small.73typedef uint16_t ShenandoahLiveData;74#define SHENANDOAH_LIVEDATA_MAX ((ShenandoahLiveData)-1)7576class ShenandoahRegionIterator : public StackObj {77private:78ShenandoahHeap* _heap;7980shenandoah_padding(0);81volatile size_t _index;82shenandoah_padding(1);8384// No implicit copying: iterators should be passed by reference to capture the state85NONCOPYABLE(ShenandoahRegionIterator);8687public:88ShenandoahRegionIterator();89ShenandoahRegionIterator(ShenandoahHeap* heap);9091// Reset iterator to default state92void reset();9394// Returns next region, or NULL if there are no more regions.95// This is multi-thread-safe.96inline ShenandoahHeapRegion* next();9798// This is *not* MT safe. However, in the absence of multithreaded access, it99// can be used to determine if there is more work to do.100bool has_next() const;101};102103class ShenandoahHeapRegionClosure : public StackObj {104public:105virtual void heap_region_do(ShenandoahHeapRegion* r) = 0;106virtual bool is_thread_safe() { return false; }107};108109typedef ShenandoahLock ShenandoahHeapLock;110typedef ShenandoahLocker ShenandoahHeapLocker;111typedef Stack<oop, mtGC> ShenandoahScanObjectStack;112113// Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers114// to encode forwarding data. See BrooksPointer for details on forwarding data encoding.115// See ShenandoahControlThread for GC cycle structure.116//117class ShenandoahHeap : public CollectedHeap {118friend class ShenandoahAsserts;119friend class VMStructs;120friend class ShenandoahGCSession;121friend class ShenandoahGCStateResetter;122friend class ShenandoahParallelObjectIterator;123friend class ShenandoahSafepoint;124// Supported GC125friend class ShenandoahConcurrentGC;126friend class ShenandoahDegenGC;127friend class ShenandoahFullGC;128friend class ShenandoahUnload;129130// ---------- Locks that guard important data structures in Heap131//132private:133ShenandoahHeapLock _lock;134135public:136ShenandoahHeapLock* lock() {137return &_lock;138}139140// ---------- Initialization, termination, identification, printing routines141//142public:143static ShenandoahHeap* heap();144145const char* name() const { return "Shenandoah"; }146ShenandoahHeap::Name kind() const { return CollectedHeap::Shenandoah; }147148ShenandoahHeap(ShenandoahCollectorPolicy* policy);149jint initialize();150void post_initialize();151void initialize_mode();152void initialize_heuristics();153154void initialize_serviceability();155156void print_on(outputStream* st) const;157void print_extended_on(outputStream *st) const;158void print_tracing_info() const;159void print_heap_regions_on(outputStream* st) const;160161void stop();162163void prepare_for_verify();164void verify(VerifyOption vo);165166// WhiteBox testing support.167bool supports_concurrent_gc_breakpoints() const {168return true;169}170171// ---------- Heap counters and metrics172//173private:174size_t _initial_size;175size_t _minimum_size;176volatile size_t _soft_max_size;177shenandoah_padding(0);178volatile size_t _used;179volatile size_t _committed;180volatile size_t _bytes_allocated_since_gc_start;181shenandoah_padding(1);182183public:184void increase_used(size_t bytes);185void decrease_used(size_t bytes);186void set_used(size_t bytes);187188void increase_committed(size_t bytes);189void decrease_committed(size_t bytes);190void increase_allocated(size_t bytes);191192size_t bytes_allocated_since_gc_start();193void reset_bytes_allocated_since_gc_start();194195size_t min_capacity() const;196size_t max_capacity() const;197size_t soft_max_capacity() const;198size_t initial_capacity() const;199size_t capacity() const;200size_t used() const;201size_t committed() const;202203void set_soft_max_capacity(size_t v);204205// ---------- Workers handling206//207private:208uint _max_workers;209ShenandoahWorkGang* _workers;210ShenandoahWorkGang* _safepoint_workers;211212public:213uint max_workers();214void assert_gc_workers(uint nworker) NOT_DEBUG_RETURN;215216WorkGang* workers() const;217WorkGang* safepoint_workers();218219void gc_threads_do(ThreadClosure* tcl) const;220221// ---------- Heap regions handling machinery222//223private:224MemRegion _heap_region;225bool _heap_region_special;226size_t _num_regions;227ShenandoahHeapRegion** _regions;228ShenandoahRegionIterator _update_refs_iterator;229230public:231232inline HeapWord* base() const { return _heap_region.start(); }233234inline size_t num_regions() const { return _num_regions; }235inline bool is_heap_region_special() { return _heap_region_special; }236237inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const;238inline size_t heap_region_index_containing(const void* addr) const;239240inline ShenandoahHeapRegion* const get_region(size_t region_idx) const;241242void heap_region_iterate(ShenandoahHeapRegionClosure* blk) const;243void parallel_heap_region_iterate(ShenandoahHeapRegionClosure* blk) const;244245// ---------- GC state machinery246//247// GC state describes the important parts of collector state, that may be248// used to make barrier selection decisions in the native and generated code.249// Multiple bits can be set at once.250//251// Important invariant: when GC state is zero, the heap is stable, and no barriers252// are required.253//254public:255enum GCStateBitPos {256// Heap has forwarded objects: needs LRB barriers.257HAS_FORWARDED_BITPOS = 0,258259// Heap is under marking: needs SATB barriers.260MARKING_BITPOS = 1,261262// Heap is under evacuation: needs LRB barriers. (Set together with HAS_FORWARDED)263EVACUATION_BITPOS = 2,264265// Heap is under updating: needs no additional barriers.266UPDATEREFS_BITPOS = 3,267268// Heap is under weak-reference/roots processing: needs weak-LRB barriers.269WEAK_ROOTS_BITPOS = 4,270};271272enum GCState {273STABLE = 0,274HAS_FORWARDED = 1 << HAS_FORWARDED_BITPOS,275MARKING = 1 << MARKING_BITPOS,276EVACUATION = 1 << EVACUATION_BITPOS,277UPDATEREFS = 1 << UPDATEREFS_BITPOS,278WEAK_ROOTS = 1 << WEAK_ROOTS_BITPOS,279};280281private:282ShenandoahSharedBitmap _gc_state;283ShenandoahSharedFlag _degenerated_gc_in_progress;284ShenandoahSharedFlag _full_gc_in_progress;285ShenandoahSharedFlag _full_gc_move_in_progress;286ShenandoahSharedFlag _progress_last_gc;287ShenandoahSharedFlag _concurrent_strong_root_in_progress;288289void set_gc_state_all_threads(char state);290void set_gc_state_mask(uint mask, bool value);291292public:293char gc_state() const;294static address gc_state_addr();295296void set_concurrent_mark_in_progress(bool in_progress);297void set_evacuation_in_progress(bool in_progress);298void set_update_refs_in_progress(bool in_progress);299void set_degenerated_gc_in_progress(bool in_progress);300void set_full_gc_in_progress(bool in_progress);301void set_full_gc_move_in_progress(bool in_progress);302void set_has_forwarded_objects(bool cond);303void set_concurrent_strong_root_in_progress(bool cond);304void set_concurrent_weak_root_in_progress(bool cond);305306inline bool is_stable() const;307inline bool is_idle() const;308inline bool is_concurrent_mark_in_progress() const;309inline bool is_update_refs_in_progress() const;310inline bool is_evacuation_in_progress() const;311inline bool is_degenerated_gc_in_progress() const;312inline bool is_full_gc_in_progress() const;313inline bool is_full_gc_move_in_progress() const;314inline bool has_forwarded_objects() const;315inline bool is_gc_in_progress_mask(uint mask) const;316inline bool is_stw_gc_in_progress() const;317inline bool is_concurrent_strong_root_in_progress() const;318inline bool is_concurrent_weak_root_in_progress() const;319320private:321enum CancelState {322// Normal state. GC has not been cancelled and is open for cancellation.323// Worker threads can suspend for safepoint.324CANCELLABLE,325326// GC has been cancelled. Worker threads can not suspend for327// safepoint but must finish their work as soon as possible.328CANCELLED,329330// GC has not been cancelled and must not be cancelled. At least331// one worker thread checks for pending safepoint and may suspend332// if a safepoint is pending.333NOT_CANCELLED334};335336ShenandoahSharedEnumFlag<CancelState> _cancelled_gc;337bool try_cancel_gc();338339public:340static address cancelled_gc_addr();341342inline bool cancelled_gc() const;343inline bool check_cancelled_gc_and_yield(bool sts_active = true);344345inline void clear_cancelled_gc();346347void cancel_gc(GCCause::Cause cause);348349public:350// Elastic heap support351void entry_uncommit(double shrink_before, size_t shrink_until);352void op_uncommit(double shrink_before, size_t shrink_until);353354private:355// GC support356// Reset bitmap, prepare regions for new GC cycle357void prepare_gc();358void prepare_regions_and_collection_set(bool concurrent);359// Evacuation360void prepare_evacuation(bool concurrent);361void evacuate_collection_set(bool concurrent);362// Concurrent root processing363void prepare_concurrent_roots();364void finish_concurrent_roots();365// Concurrent class unloading support366void do_class_unloading();367// Reference updating368void prepare_update_heap_references(bool concurrent);369void update_heap_references(bool concurrent);370// Final update region states371void update_heap_region_states(bool concurrent);372void rebuild_free_set(bool concurrent);373374void rendezvous_threads();375void recycle_trash();376public:377void notify_gc_progress() { _progress_last_gc.set(); }378void notify_gc_no_progress() { _progress_last_gc.unset(); }379380//381// Mark support382private:383ShenandoahControlThread* _control_thread;384ShenandoahCollectorPolicy* _shenandoah_policy;385ShenandoahMode* _gc_mode;386ShenandoahHeuristics* _heuristics;387ShenandoahFreeSet* _free_set;388ShenandoahPacer* _pacer;389ShenandoahVerifier* _verifier;390391ShenandoahPhaseTimings* _phase_timings;392393ShenandoahControlThread* control_thread() { return _control_thread; }394395public:396ShenandoahCollectorPolicy* shenandoah_policy() const { return _shenandoah_policy; }397ShenandoahMode* mode() const { return _gc_mode; }398ShenandoahHeuristics* heuristics() const { return _heuristics; }399ShenandoahFreeSet* free_set() const { return _free_set; }400ShenandoahPacer* pacer() const { return _pacer; }401402ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }403404ShenandoahVerifier* verifier();405406// ---------- VM subsystem bindings407//408private:409ShenandoahMonitoringSupport* _monitoring_support;410MemoryPool* _memory_pool;411GCMemoryManager _stw_memory_manager;412GCMemoryManager _cycle_memory_manager;413ConcurrentGCTimer* _gc_timer;414SoftRefPolicy _soft_ref_policy;415416// For exporting to SA417int _log_min_obj_alignment_in_bytes;418public:419ShenandoahMonitoringSupport* monitoring_support() { return _monitoring_support; }420GCMemoryManager* cycle_memory_manager() { return &_cycle_memory_manager; }421GCMemoryManager* stw_memory_manager() { return &_stw_memory_manager; }422SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; }423424GrowableArray<GCMemoryManager*> memory_managers();425GrowableArray<MemoryPool*> memory_pools();426MemoryUsage memory_usage();427GCTracer* tracer();428ConcurrentGCTimer* gc_timer() const;429430// ---------- Reference processing431//432private:433ShenandoahReferenceProcessor* const _ref_processor;434435public:436ShenandoahReferenceProcessor* ref_processor() { return _ref_processor; }437438// ---------- Class Unloading439//440private:441ShenandoahSharedFlag _unload_classes;442ShenandoahUnload _unloader;443444public:445void set_unload_classes(bool uc);446bool unload_classes() const;447448// Perform STW class unloading and weak root cleaning449void parallel_cleaning(bool full_gc);450451private:452void stw_unload_classes(bool full_gc);453void stw_process_weak_roots(bool full_gc);454void stw_weak_refs(bool full_gc);455456// Heap iteration support457void scan_roots_for_iteration(ShenandoahScanObjectStack* oop_stack, ObjectIterateScanRootClosure* oops);458bool prepare_aux_bitmap_for_iteration();459void reclaim_aux_bitmap_for_iteration();460461// ---------- Generic interface hooks462// Minor things that super-interface expects us to implement to play nice with463// the rest of runtime. Some of the things here are not required to be implemented,464// and can be stubbed out.465//466public:467AdaptiveSizePolicy* size_policy() shenandoah_not_implemented_return(NULL);468bool is_maximal_no_gc() const shenandoah_not_implemented_return(false);469470bool is_in(const void* p) const;471472MemRegion reserved_region() const { return _reserved; }473bool is_in_reserved(const void* addr) const { return _reserved.contains(addr); }474475void collect(GCCause::Cause cause);476void do_full_collection(bool clear_all_soft_refs);477478// Used for parsing heap during error printing479HeapWord* block_start(const void* addr) const;480bool block_is_obj(const HeapWord* addr) const;481bool print_location(outputStream* st, void* addr) const;482483// Used for native heap walkers: heap dumpers, mostly484void object_iterate(ObjectClosure* cl);485// Parallel heap iteration support486virtual ParallelObjectIterator* parallel_object_iterator(uint workers);487488// Keep alive an object that was loaded with AS_NO_KEEPALIVE.489void keep_alive(oop obj);490491// ---------- Safepoint interface hooks492//493public:494void safepoint_synchronize_begin();495void safepoint_synchronize_end();496497// ---------- Code roots handling hooks498//499public:500void register_nmethod(nmethod* nm);501void unregister_nmethod(nmethod* nm);502void flush_nmethod(nmethod* nm);503void verify_nmethod(nmethod* nm) {}504505// ---------- Pinning hooks506//507public:508// Shenandoah supports per-object (per-region) pinning509bool supports_object_pinning() const { return true; }510511oop pin_object(JavaThread* thread, oop obj);512void unpin_object(JavaThread* thread, oop obj);513514void sync_pinned_region_status();515void assert_pinned_region_status() NOT_DEBUG_RETURN;516517// ---------- Concurrent Stack Processing support518//519public:520bool uses_stack_watermark_barrier() const { return true; }521522// ---------- Allocation support523//524private:525HeapWord* allocate_memory_under_lock(ShenandoahAllocRequest& request, bool& in_new_region);526inline HeapWord* allocate_from_gclab(Thread* thread, size_t size);527HeapWord* allocate_from_gclab_slow(Thread* thread, size_t size);528HeapWord* allocate_new_gclab(size_t min_size, size_t word_size, size_t* actual_size);529530public:531HeapWord* allocate_memory(ShenandoahAllocRequest& request);532HeapWord* mem_allocate(size_t size, bool* what);533MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,534size_t size,535Metaspace::MetadataType mdtype);536537void notify_mutator_alloc_words(size_t words, bool waste);538539HeapWord* allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size);540size_t tlab_capacity(Thread *thr) const;541size_t unsafe_max_tlab_alloc(Thread *thread) const;542size_t max_tlab_size() const;543size_t tlab_used(Thread* ignored) const;544545void ensure_parsability(bool retire_labs);546547void labs_make_parsable();548void tlabs_retire(bool resize);549void gclabs_retire(bool resize);550551// ---------- Marking support552//553private:554ShenandoahMarkingContext* _marking_context;555MemRegion _bitmap_region;556MemRegion _aux_bitmap_region;557MarkBitMap _verification_bit_map;558MarkBitMap _aux_bit_map;559560size_t _bitmap_size;561size_t _bitmap_regions_per_slice;562size_t _bitmap_bytes_per_slice;563564size_t _pretouch_heap_page_size;565size_t _pretouch_bitmap_page_size;566567bool _bitmap_region_special;568bool _aux_bitmap_region_special;569570ShenandoahLiveData** _liveness_cache;571572public:573inline ShenandoahMarkingContext* complete_marking_context() const;574inline ShenandoahMarkingContext* marking_context() const;575inline void mark_complete_marking_context();576inline void mark_incomplete_marking_context();577578template<class T>579inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl);580581template<class T>582inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit);583584template<class T>585inline void marked_object_oop_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit);586587void reset_mark_bitmap();588589// SATB barriers hooks590inline bool requires_marking(const void* entry) const;591592// Support for bitmap uncommits593bool commit_bitmap_slice(ShenandoahHeapRegion *r);594bool uncommit_bitmap_slice(ShenandoahHeapRegion *r);595bool is_bitmap_slice_committed(ShenandoahHeapRegion* r, bool skip_self = false);596597// Liveness caching support598ShenandoahLiveData* get_liveness_cache(uint worker_id);599void flush_liveness_cache(uint worker_id);600601size_t pretouch_heap_page_size() { return _pretouch_heap_page_size; }602603// ---------- Evacuation support604//605private:606ShenandoahCollectionSet* _collection_set;607ShenandoahEvacOOMHandler _oom_evac_handler;608609public:610static address in_cset_fast_test_addr();611612ShenandoahCollectionSet* collection_set() const { return _collection_set; }613614// Checks if object is in the collection set.615inline bool in_collection_set(oop obj) const;616617// Checks if location is in the collection set. Can be interior pointer, not the oop itself.618inline bool in_collection_set_loc(void* loc) const;619620// Evacuates object src. Returns the evacuated object, either evacuated621// by this thread, or by some other thread.622inline oop evacuate_object(oop src, Thread* thread);623624// Call before/after evacuation.625inline void enter_evacuation(Thread* t);626inline void leave_evacuation(Thread* t);627628// ---------- Helper functions629//630public:631template <class T>632inline void conc_update_with_forwarded(T* p);633634template <class T>635inline void update_with_forwarded(T* p);636637static inline oop cas_oop(oop n, narrowOop* addr, oop c);638static inline oop cas_oop(oop n, oop* addr, oop c);639static inline oop cas_oop(oop n, narrowOop* addr, narrowOop c);640641void trash_humongous_region_at(ShenandoahHeapRegion *r);642643private:644void trash_cset_regions();645646// ---------- Testing helpers functions647//648private:649ShenandoahSharedFlag _inject_alloc_failure;650651void try_inject_alloc_failure();652bool should_inject_alloc_failure();653};654655#endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAP_HPP656657658