Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp
38920 views
/*1* Copyright (c) 2013, 2020, Red Hat, Inc. All rights reserved.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation.6*7* This code is distributed in the hope that it will be useful, but WITHOUT8* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or9* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License10* version 2 for more details (a copy is included in the LICENSE file that11* accompanied this code).12*13* You should have received a copy of the GNU General Public License version14* 2 along with this work; if not, write to the Free Software Foundation,15* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.16*17* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA18* or visit www.oracle.com if you need additional information or have any19* questions.20*21*/2223#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP24#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP2526#include "gc_implementation/shared/markBitMap.hpp"27#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"28#include "gc_implementation/shenandoah/shenandoahAllocRequest.hpp"29#include "gc_implementation/shenandoah/shenandoahLock.hpp"30#include "gc_implementation/shenandoah/shenandoahEvacOOMHandler.hpp"31#include "gc_implementation/shenandoah/shenandoahPadding.hpp"32#include "gc_implementation/shenandoah/shenandoahSharedVariables.hpp"3334class ConcurrentGCTimer;3536class ShenandoahCollectionSet;37class ShenandoahCollectorPolicy;38class ShenandoahConcurrentMark;39class ShenandoahControlThread;40class ShenandoahGCSession;41class ShenandoahGCStateResetter;42class ShenandoahFreeSet;43class ShenandoahHeapRegion;44class ShenandoahHeapRegionClosure;45class ShenandoahMarkCompact;46class ShenandoahMonitoringSupport;47class ShenandoahHeuristics;48class ShenandoahMarkingContext;49class ShenandoahMode;50class ShenandoahPhaseTimings;51class ShenandoahPacer;52class ShenandoahVerifier;53class ShenandoahWorkGang;54class VMStructs;5556// Used for buffering per-region liveness data.57// Needed since ShenandoahHeapRegion uses atomics to update liveness.58// The ShenandoahHeap array has max-workers elements, each of which is an array of59// uint16_t * max_regions. The choice of uint16_t is not accidental:60// there is a tradeoff between static/dynamic footprint that translates61// into cache pressure (which is already high during marking), and62// too many atomic updates. uint32_t is too large, uint8_t is too small.63typedef uint16_t ShenandoahLiveData;64#define SHENANDOAH_LIVEDATA_MAX ((ShenandoahLiveData)-1)6566class ShenandoahRegionIterator : public StackObj {67private:68ShenandoahHeap* _heap;6970shenandoah_padding(0);71volatile jint _index;72shenandoah_padding(1);7374// No implicit copying: iterators should be passed by reference to capture the state75ShenandoahRegionIterator(const ShenandoahRegionIterator& that);76ShenandoahRegionIterator& operator=(const ShenandoahRegionIterator& o);7778public:79ShenandoahRegionIterator();80ShenandoahRegionIterator(ShenandoahHeap* heap);8182// Reset iterator to default state83void reset();8485// Returns next region, or NULL if there are no more regions.86// This is multi-thread-safe.87inline ShenandoahHeapRegion* next();8889// This is *not* MT safe. However, in the absence of multithreaded access, it90// can be used to determine if there is more work to do.91bool has_next() const;92};9394class ShenandoahHeapRegionClosure : public StackObj {95public:96virtual void heap_region_do(ShenandoahHeapRegion* r) = 0;97virtual bool is_thread_safe() { return false; }98};99100typedef ShenandoahLock ShenandoahHeapLock;101typedef ShenandoahLocker ShenandoahHeapLocker;102103// Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers104// to encode forwarding data. See BrooksPointer for details on forwarding data encoding.105// See ShenandoahControlThread for GC cycle structure.106//107class ShenandoahHeap : public SharedHeap {108friend class ShenandoahAsserts;109friend class VMStructs;110friend class ShenandoahGCSession;111friend class ShenandoahGCStateResetter;112friend class ShenandoahSafepoint;113114// ---------- Locks that guard important data structures in Heap115//116private:117ShenandoahHeapLock _lock;118119public:120ShenandoahHeapLock* lock() {121return &_lock;122}123124// ---------- Initialization, termination, identification, printing routines125//126private:127static ShenandoahHeap* _heap;128129public:130static ShenandoahHeap* heap();131static size_t conservative_max_heap_alignment();132133const char* name() const { return "Shenandoah"; }134ShenandoahHeap::Name kind() const { return CollectedHeap::ShenandoahHeap; }135136ShenandoahHeap(ShenandoahCollectorPolicy* policy);137jint initialize();138void post_initialize();139void initialize_heuristics();140141void print_on(outputStream* st) const;142void print_extended_on(outputStream *st) const;143void print_tracing_info() const;144void print_gc_threads_on(outputStream* st) const;145void print_heap_regions_on(outputStream* st) const;146147void stop();148149void prepare_for_verify();150void verify(bool silent, VerifyOption vo);151152// ---------- Heap counters and metrics153//154private:155size_t _initial_size;156size_t _minimum_size;157volatile size_t _soft_max_size;158shenandoah_padding(0);159volatile jlong _used;160volatile size_t _committed;161volatile jlong _bytes_allocated_since_gc_start;162shenandoah_padding(1);163164public:165void increase_used(size_t bytes);166void decrease_used(size_t bytes);167void set_used(size_t bytes);168169void increase_committed(size_t bytes);170void decrease_committed(size_t bytes);171void increase_allocated(size_t bytes);172173size_t bytes_allocated_since_gc_start();174void reset_bytes_allocated_since_gc_start();175176size_t min_capacity() const;177size_t max_capacity() const;178size_t soft_max_capacity() const;179size_t initial_capacity() const;180size_t capacity() const;181size_t used() const;182size_t committed() const;183184void set_soft_max_capacity(size_t v);185186// ---------- Workers handling187//188private:189uint _max_workers;190191public:192uint max_workers();193void assert_gc_workers(uint nworker) NOT_DEBUG_RETURN;194195ShenandoahWorkGang* workers() const;196197void gc_threads_do(ThreadClosure* tcl) const;198199// ---------- Heap regions handling machinery200//201private:202MemRegion _heap_region;203bool _heap_region_special;204size_t _num_regions;205ShenandoahHeapRegion** _regions;206ShenandoahRegionIterator _update_refs_iterator;207208public:209inline size_t num_regions() const { return _num_regions; }210inline bool is_heap_region_special() { return _heap_region_special; }211212inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const;213inline size_t heap_region_index_containing(const void* addr) const;214215inline ShenandoahHeapRegion* const get_region(size_t region_idx) const;216217void heap_region_iterate(ShenandoahHeapRegionClosure* blk) const;218void parallel_heap_region_iterate(ShenandoahHeapRegionClosure* blk) const;219220// ---------- GC state machinery221//222// GC state describes the important parts of collector state, that may be223// used to make barrier selection decisions in the native and generated code.224// Multiple bits can be set at once.225//226// Important invariant: when GC state is zero, the heap is stable, and no barriers227// are required.228//229public:230enum GCStateBitPos {231// Heap has forwarded objects: need RB, ACMP, CAS barriers.232HAS_FORWARDED_BITPOS = 0,233234// Heap is under marking: needs SATB barriers.235MARKING_BITPOS = 1,236237// Heap is under evacuation: needs WB barriers. (Set together with UNSTABLE)238EVACUATION_BITPOS = 2,239240// Heap is under updating: needs SVRB/SVWB barriers.241UPDATEREFS_BITPOS = 3,242};243244enum GCState {245STABLE = 0,246HAS_FORWARDED = 1 << HAS_FORWARDED_BITPOS,247MARKING = 1 << MARKING_BITPOS,248EVACUATION = 1 << EVACUATION_BITPOS,249UPDATEREFS = 1 << UPDATEREFS_BITPOS,250};251252private:253ShenandoahSharedBitmap _gc_state;254ShenandoahSharedFlag _degenerated_gc_in_progress;255ShenandoahSharedFlag _full_gc_in_progress;256ShenandoahSharedFlag _full_gc_move_in_progress;257ShenandoahSharedFlag _progress_last_gc;258259void set_gc_state_mask(uint mask, bool value);260261public:262char gc_state();263static address gc_state_addr();264265void set_concurrent_mark_in_progress(bool in_progress);266void set_evacuation_in_progress(bool in_progress);267void set_update_refs_in_progress(bool in_progress);268void set_degenerated_gc_in_progress(bool in_progress);269void set_full_gc_in_progress(bool in_progress);270void set_full_gc_move_in_progress(bool in_progress);271void set_has_forwarded_objects(bool cond);272273inline bool is_stable() const;274inline bool is_idle() const;275inline bool is_concurrent_mark_in_progress() const;276inline bool is_update_refs_in_progress() const;277inline bool is_evacuation_in_progress() const;278inline bool is_degenerated_gc_in_progress() const;279inline bool is_full_gc_in_progress() const;280inline bool is_full_gc_move_in_progress() const;281inline bool has_forwarded_objects() const;282inline bool is_gc_in_progress_mask(uint mask) const;283284// ---------- GC cancellation and degeneration machinery285//286// Cancelled GC flag is used to notify concurrent phases that they should terminate.287//288public:289enum ShenandoahDegenPoint {290_degenerated_unset,291_degenerated_outside_cycle,292_degenerated_mark,293_degenerated_evac,294_degenerated_updaterefs,295_DEGENERATED_LIMIT296};297298static const char* degen_point_to_string(ShenandoahDegenPoint point) {299switch (point) {300case _degenerated_unset:301return "<UNSET>";302case _degenerated_outside_cycle:303return "Outside of Cycle";304case _degenerated_mark:305return "Mark";306case _degenerated_evac:307return "Evacuation";308case _degenerated_updaterefs:309return "Update Refs";310default:311ShouldNotReachHere();312return "ERROR";313}314};315316private:317ShenandoahSharedFlag _cancelled_gc;318inline bool try_cancel_gc();319320public:321static address cancelled_gc_addr();322323inline bool cancelled_gc() const;324325inline void clear_cancelled_gc();326327void cancel_gc(GCCause::Cause cause);328329// ---------- GC operations entry points330//331public:332// Entry points to STW GC operations, these cause a related safepoint, that then333// call the entry method below334void vmop_entry_init_mark();335void vmop_entry_final_mark();336void vmop_entry_init_updaterefs();337void vmop_entry_final_updaterefs();338void vmop_entry_full(GCCause::Cause cause);339void vmop_degenerated(ShenandoahDegenPoint point);340341// Entry methods to normally STW GC operations. These set up logging, monitoring342// and workers for net VM operation343void entry_init_mark();344void entry_final_mark();345void entry_init_updaterefs();346void entry_final_updaterefs();347void entry_full(GCCause::Cause cause);348void entry_degenerated(int point);349350// Entry methods to normally concurrent GC operations. These set up logging, monitoring351// for concurrent operation.352void entry_reset();353void entry_mark();354void entry_preclean();355void entry_cleanup_early();356void entry_evac();357void entry_updaterefs();358void entry_cleanup_complete();359void entry_uncommit(double shrink_before, size_t shrink_until);360361private:362// Actual work for the phases363void op_init_mark();364void op_final_mark();365void op_init_updaterefs();366void op_final_updaterefs();367void op_full(GCCause::Cause cause);368void op_degenerated(ShenandoahDegenPoint point);369void op_degenerated_fail();370void op_degenerated_futile();371372void op_reset();373void op_mark();374void op_preclean();375void op_cleanup_early();376void op_conc_evac();377void op_stw_evac();378void op_updaterefs();379void op_cleanup_complete();380void op_uncommit(double shrink_before, size_t shrink_until);381382// Messages for GC trace event, they have to be immortal for383// passing around the logging/tracing systems384const char* init_mark_event_message() const;385const char* final_mark_event_message() const;386const char* conc_mark_event_message() const;387const char* degen_event_message(ShenandoahDegenPoint point) const;388389// ---------- GC subsystems390//391private:392ShenandoahControlThread* _control_thread;393ShenandoahCollectorPolicy* _shenandoah_policy;394ShenandoahMode* _gc_mode;395ShenandoahHeuristics* _heuristics;396ShenandoahFreeSet* _free_set;397ShenandoahConcurrentMark* _scm;398ShenandoahMarkCompact* _full_gc;399ShenandoahPacer* _pacer;400ShenandoahVerifier* _verifier;401402ShenandoahPhaseTimings* _phase_timings;403404ShenandoahControlThread* control_thread() { return _control_thread; }405ShenandoahMarkCompact* full_gc() { return _full_gc; }406407public:408ShenandoahCollectorPolicy* shenandoah_policy() const { return _shenandoah_policy; }409ShenandoahHeuristics* heuristics() const { return _heuristics; }410ShenandoahFreeSet* free_set() const { return _free_set; }411ShenandoahConcurrentMark* concurrent_mark() { return _scm; }412ShenandoahPacer* pacer() const { return _pacer; }413414ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }415416ShenandoahVerifier* verifier();417418// ---------- VM subsystem bindings419//420private:421ShenandoahMonitoringSupport* _monitoring_support;422ConcurrentGCTimer* _gc_timer;423424public:425ShenandoahMonitoringSupport* monitoring_support() { return _monitoring_support; }426427GCTracer* tracer();428GCTimer* gc_timer() const;429CollectorPolicy* collector_policy() const;430431// ---------- Reference processing432//433private:434ReferenceProcessor* _ref_processor;435ShenandoahSharedFlag _process_references;436437void ref_processing_init();438439public:440ReferenceProcessor* ref_processor() { return _ref_processor;}441void set_process_references(bool pr);442bool process_references() const;443444// ---------- Class Unloading445//446private:447ShenandoahSharedFlag _unload_classes;448449public:450void set_unload_classes(bool uc);451bool unload_classes() const;452453// Delete entries for dead interned string and clean up unreferenced symbols454// in symbol table, possibly in parallel.455void unload_classes_and_cleanup_tables(bool full_gc);456457// ---------- Generic interface hooks458// Minor things that super-interface expects us to implement to play nice with459// the rest of runtime. Some of the things here are not required to be implemented,460// and can be stubbed out.461//462public:463AdaptiveSizePolicy* size_policy() shenandoah_not_implemented_return(NULL);464bool is_maximal_no_gc() const shenandoah_not_implemented_return(false);465466bool is_in(const void* p) const;467468// All objects can potentially move469bool is_scavengable(const void* addr) { return true; }470471void collect(GCCause::Cause cause);472void do_full_collection(bool clear_all_soft_refs);473474// Used for parsing heap during error printing475HeapWord* block_start(const void* addr) const;476size_t block_size(const HeapWord* addr) const;477bool block_is_obj(const HeapWord* addr) const;478479// Used for native heap walkers: heap dumpers, mostly480void object_iterate(ObjectClosure* cl);481void safe_object_iterate(ObjectClosure* cl);482void space_iterate(SpaceClosure* scl) shenandoah_not_implemented;483void oop_iterate(ExtendedOopClosure* cl);484Space* space_containing(const void* oop) const shenandoah_not_implemented_return(NULL);485486// Used by RMI487jlong millis_since_last_gc();488489bool can_elide_tlab_store_barriers() const { return true; }490oop new_store_pre_barrier(JavaThread* thread, oop new_obj) { return new_obj; }491bool can_elide_initializing_store_barrier(oop new_obj) { return true; }492bool card_mark_must_follow_store() const { return false; }493494bool is_in_partial_collection(const void* p) shenandoah_not_implemented_return(false);495bool supports_heap_inspection() const { return true; }496497void gc_prologue(bool b);498void gc_epilogue(bool b);499500void acquire_pending_refs_lock();501void release_pending_refs_lock();502503// ---------- Code roots handling hooks504//505public:506void register_nmethod(nmethod* nm);507void unregister_nmethod(nmethod* nm);508509// ---------- Pinning hooks510//511public:512// Shenandoah supports per-object (per-region) pinning513bool supports_object_pinning() const { return true; }514515oop pin_object(JavaThread* thread, oop obj);516void unpin_object(JavaThread* thread, oop obj);517518void sync_pinned_region_status();519void assert_pinned_region_status() NOT_DEBUG_RETURN;520521// ---------- Allocation support522//523private:524HeapWord* allocate_memory_under_lock(ShenandoahAllocRequest& request, bool& in_new_region);525inline HeapWord* allocate_from_gclab(Thread* thread, size_t size);526HeapWord* allocate_from_gclab_slow(Thread* thread, size_t size);527HeapWord* allocate_new_gclab(size_t min_size, size_t word_size, size_t* actual_size);528529public:530HeapWord* allocate_memory(ShenandoahAllocRequest& request);531HeapWord* mem_allocate(size_t size, bool* what);532533void notify_mutator_alloc_words(size_t words, bool waste);534535// Shenandoah supports TLAB allocation536bool supports_tlab_allocation() const { return true; }537538HeapWord* allocate_new_tlab(size_t word_size);539size_t tlab_capacity(Thread *thr) const;540size_t unsafe_max_tlab_alloc(Thread *thread) const;541size_t max_tlab_size() const;542size_t tlab_used(Thread* ignored) const;543544void resize_tlabs();545void resize_all_tlabs();546547void accumulate_statistics_tlabs();548void accumulate_statistics_all_gclabs();549550void make_parsable(bool retire_tlabs);551void ensure_parsability(bool retire_tlabs);552553// ---------- Marking support554//555private:556ShenandoahMarkingContext* _marking_context;557MemRegion _bitmap_region;558MemRegion _aux_bitmap_region;559MarkBitMap _verification_bit_map;560MarkBitMap _aux_bit_map;561562size_t _bitmap_size;563size_t _bitmap_regions_per_slice;564size_t _bitmap_bytes_per_slice;565566size_t _pretouch_heap_page_size;567size_t _pretouch_bitmap_page_size;568569bool _bitmap_region_special;570bool _aux_bitmap_region_special;571572ShenandoahLiveData** _liveness_cache;573574public:575inline ShenandoahMarkingContext* complete_marking_context() const;576inline ShenandoahMarkingContext* marking_context() const;577inline void mark_complete_marking_context();578inline void mark_incomplete_marking_context();579580template<class T>581inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl);582583template<class T>584inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit);585586template<class T>587inline void marked_object_oop_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit);588589void reset_mark_bitmap();590591// SATB barriers hooks592inline bool requires_marking(const void* entry) const;593void force_satb_flush_all_threads();594595// Support for bitmap uncommits596bool commit_bitmap_slice(ShenandoahHeapRegion *r);597bool uncommit_bitmap_slice(ShenandoahHeapRegion *r);598bool is_bitmap_slice_committed(ShenandoahHeapRegion* r, bool skip_self = false);599600// Liveness caching support601ShenandoahLiveData* get_liveness_cache(uint worker_id);602void flush_liveness_cache(uint worker_id);603604size_t pretouch_heap_page_size() { return _pretouch_heap_page_size; }605606// ---------- Evacuation support607//608private:609ShenandoahCollectionSet* _collection_set;610ShenandoahEvacOOMHandler _oom_evac_handler;611612void evacuate_and_update_roots();613614public:615static address in_cset_fast_test_addr();616617ShenandoahCollectionSet* collection_set() const { return _collection_set; }618619// Checks if object is in the collection set.620inline bool in_collection_set(oop obj) const;621622// Checks if location is in the collection set. Can be interior pointer, not the oop itself.623inline bool in_collection_set_loc(void* loc) const;624625// Evacuates object src. Returns the evacuated object, either evacuated626// by this thread, or by some other thread.627inline oop evacuate_object(oop src, Thread* thread);628629// Call before/after evacuation.630void enter_evacuation();631void leave_evacuation();632633// ---------- Helper functions634//635public:636template <class T>637inline oop evac_update_with_forwarded(T* p);638639template <class T>640inline oop maybe_update_with_forwarded(T* p);641642template <class T>643inline oop maybe_update_with_forwarded_not_null(T* p, oop obj);644645template <class T>646inline oop update_with_forwarded_not_null(T* p, oop obj);647648static inline oop cas_oop(oop n, narrowOop* addr, oop c);649static inline oop cas_oop(oop n, oop* addr, oop c);650static inline oop cas_oop(oop n, narrowOop* addr, narrowOop c);651652void trash_humongous_region_at(ShenandoahHeapRegion *r);653654void complete_marking();655656private:657void trash_cset_regions();658void update_heap_references(bool concurrent);659660// ---------- Testing helpers functions661//662private:663ShenandoahSharedFlag _inject_alloc_failure;664665void try_inject_alloc_failure();666bool should_inject_alloc_failure();667};668669#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP670671672