< prev index next >
src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp
Print this page
rev 10658 : [backport] Single marking bitmap
rev 10671 : [backport] Clean up declarations and uses of marked_object_iterate
rev 10673 : [backport] Homogenize unimplemented stubs handling
rev 10674 : [backport] Move ShenandoahAllocType and ShenandoahAllocRequest to separate file
rev 10675 : [backport] Inline ShHeap::prepare_concurrent_evacuation
rev 10676 : [backport] Remove ShHeap::region_in_collection_set in favor of SHR::in_cset
rev 10677 : [backport] Inline ShHeap::do_marked_object_complete
rev 10678 : [backport] Rename concurrentMark -> concurrent_mark
rev 10679 : [backport] Remove ShHeap::_heap_expansion_count
rev 10680 : [backport] Remove useless ShHeap::heap_region_iterate
rev 10681 : [backport] Inline trivial ShHeap methods right in header
rev 10685 : [backport] Rename ShHeap::shenandoahPolicy -> ShHeap::shenandoah_policy
rev 10687 : [backport] Inline ShHeap::monitoring_support into header
rev 10688 : [backport] Sort ShenandoahHeap methods/fields into logical groups
rev 10690 : [backport] Cleanup header files and forward declarations
rev 10694 : [backport] Common liveness cache in ShHeap
rev 10715 : [backport] Cleanup up superfluous newlines
rev 10718 : [backport] Partial infrastructure for suspendible workers
rev 10740 : [backport] Protect more internal code from false sharing
rev 10743 : [backport] Clean up ShHeap::heap_region_iterate uses
rev 10744 : [backport] Parallel heap region iteration
rev 10771 : Enable heap inspection for Shenandoah
rev 10772 : [backport] Update copyrights
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013, 2017, Red Hat, Inc. and/or its affiliates.
+ * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
*
* 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,19 +23,19 @@
#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP
#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP
#include "gc_implementation/shared/markBitMap.hpp"
+#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
+#include "gc_implementation/shenandoah/shenandoahAllocRequest.hpp"
#include "gc_implementation/shenandoah/shenandoahHeapLock.hpp"
#include "gc_implementation/shenandoah/shenandoahEvacOOMHandler.hpp"
#include "gc_implementation/shenandoah/shenandoahSharedVariables.hpp"
-#include "gc_implementation/shenandoah/shenandoahWorkGroup.hpp"
class ConcurrentGCTimer;
class ShenandoahAllocTracker;
-class ShenandoahAsserts;
class ShenandoahCollectionSet;
class ShenandoahCollectorPolicy;
class ShenandoahConcurrentMark;
class ShenandoahControlThread;
class ShenandoahGCSession;
@@ -48,16 +48,20 @@
class ShenandoahMarkingContext;
class ShenandoahPhaseTimings;
class ShenandoahPacer;
class ShenandoahVerifier;
class ShenandoahWorkGang;
+class VMStructs;
class ShenandoahRegionIterator : public StackObj {
private:
- volatile jint _index;
ShenandoahHeap* _heap;
+ char _pad0[DEFAULT_CACHE_LINE_SIZE];
+ volatile jint _index;
+ char _pad1[DEFAULT_CACHE_LINE_SIZE];
+
// No implicit copying: iterators should be passed by reference to capture the state
ShenandoahRegionIterator(const ShenandoahRegionIterator& that);
ShenandoahRegionIterator& operator=(const ShenandoahRegionIterator& o);
public:
@@ -76,12 +80,12 @@
bool has_next() const;
};
class ShenandoahHeapRegionClosure : public StackObj {
public:
- // typically called on each region until it returns true;
- virtual bool heap_region_do(ShenandoahHeapRegion* r) = 0;
+ virtual void heap_region_do(ShenandoahHeapRegion* r) = 0;
+ virtual bool is_thread_safe() { return false; }
};
class ShenandoahUpdateRefsClosure: public OopClosure {
private:
ShenandoahHeap* _heap;
@@ -125,32 +129,138 @@
public:
ShenandoahIsAliveClosure();
bool do_object_b(oop obj);
};
-class VMStructs;
-
-// // A "ShenandoahHeap" is an implementation of a java heap for HotSpot.
-// // It uses a new pauseless GC algorithm based on Brooks pointers.
-// // Derived from G1
-
-// //
-// // CollectedHeap
-// // SharedHeap
-// // ShenandoahHeap
+class ShenandoahIsAliveSelector : public StackObj {
+private:
+ ShenandoahIsAliveClosure _alive_cl;
+ ShenandoahForwardedIsAliveClosure _fwd_alive_cl;
+public:
+ BoolObjectClosure* is_alive_closure();
+};
+// Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers
+// to encode forwarding data. See BrooksPointer for details on forwarding data encoding.
+// See ShenandoahControlThread for GC cycle structure.
+//
class ShenandoahHeap : public SharedHeap {
friend class ShenandoahAsserts;
friend class VMStructs;
friend class ShenandoahGCSession;
+
+// ---------- Locks that guard important data structures in Heap
+//
+private:
+ ShenandoahHeapLock _lock;
+
+public:
+ ShenandoahHeapLock* lock() {
+ return &_lock;
+ }
+
+ void assert_heaplock_owned_by_current_thread() PRODUCT_RETURN;
+ void assert_heaplock_not_owned_by_current_thread() PRODUCT_RETURN;
+ void assert_heaplock_or_safepoint() PRODUCT_RETURN;
+
+// ---------- Initialization, termination, identification, printing routines
+//
+public:
+ static ShenandoahHeap* heap();
+ static ShenandoahHeap* heap_no_check();
+ static size_t conservative_max_heap_alignment();
+
+ const char* name() const { return "Shenandoah"; }
+ ShenandoahHeap::Name kind() const { return CollectedHeap::ShenandoahHeap; }
+
+ ShenandoahHeap(ShenandoahCollectorPolicy* policy);
+ jint initialize();
+ void post_initialize();
+ void initialize_heuristics();
+
+ void print_on(outputStream* st) const;
+ void print_extended_on(outputStream *st) const;
+ void print_tracing_info() const;
+ void print_gc_threads_on(outputStream* st) const;
+ void print_heap_regions_on(outputStream* st) const;
+
+ void stop();
+
+ void prepare_for_verify();
+ void verify(bool silent, VerifyOption vo);
+
+// ---------- Heap counters and metrics
+//
+private:
+ size_t _initial_size;
+ char _pad0[DEFAULT_CACHE_LINE_SIZE];
+ volatile jlong _used;
+ volatile size_t _committed;
+ volatile jlong _bytes_allocated_since_gc_start;
+ char _pad1[DEFAULT_CACHE_LINE_SIZE];
+
+public:
+ void increase_used(size_t bytes);
+ void decrease_used(size_t bytes);
+ void set_used(size_t bytes);
+
+ void increase_committed(size_t bytes);
+ void decrease_committed(size_t bytes);
+ void increase_allocated(size_t bytes);
+
+ size_t bytes_allocated_since_gc_start();
+ void reset_bytes_allocated_since_gc_start();
+
+ size_t max_capacity() const;
+ size_t initial_capacity() const;
+ size_t capacity() const;
+ size_t used() const;
+ size_t committed() const;
+
+// ---------- Workers handling
+//
+private:
+ uint _max_workers;
+ ShenandoahWorkGang* _workers;
+
+public:
+ uint max_workers();
+ void assert_gc_workers(uint nworker) PRODUCT_RETURN;
+
+ ShenandoahWorkGang* workers() const;
+
+ void gc_threads_do(ThreadClosure* tcl) const;
+
+// ---------- Heap regions handling machinery
+//
+private:
+ MemRegion _heap_region;
+ size_t _num_regions;
+ ShenandoahHeapRegion** _regions;
+ ShenandoahRegionIterator _update_refs_iterator;
+
+public:
+ inline size_t num_regions() const { return _num_regions; }
+
+ inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const;
+ inline size_t heap_region_index_containing(const void* addr) const;
+
+ inline ShenandoahHeapRegion* const get_region(size_t region_idx) const;
+
+ void heap_region_iterate(ShenandoahHeapRegionClosure* blk) const;
+ void parallel_heap_region_iterate(ShenandoahHeapRegionClosure* blk) const;
+
+// ---------- GC state machinery
+//
+// GC state describes the important parts of collector state, that may be
+// used to make barrier selection decisions in the native and generated code.
+// Multiple bits can be set at once.
+//
+// Important invariant: when GC state is zero, the heap is stable, and no barriers
+// are required.
+//
public:
- // GC state describes the important parts of collector state, that may be
- // used to make barrier selection decisions in the native and generated code.
- // Multiple bits can be set at once.
- //
- // Important invariant: when GC state is zero, the heap is stable, and no barriers
- // are required.
enum GCStateBitPos {
// Heap has forwarded objects: need RB, ACMP, CAS barriers.
HAS_FORWARDED_BITPOS = 0,
// Heap is under marking: needs SATB barriers.
@@ -169,10 +279,47 @@
MARKING = 1 << MARKING_BITPOS,
EVACUATION = 1 << EVACUATION_BITPOS,
UPDATEREFS = 1 << UPDATEREFS_BITPOS,
};
+private:
+ ShenandoahSharedBitmap _gc_state;
+ ShenandoahSharedFlag _degenerated_gc_in_progress;
+ ShenandoahSharedFlag _full_gc_in_progress;
+ ShenandoahSharedFlag _full_gc_move_in_progress;
+ ShenandoahSharedFlag _progress_last_gc;
+
+ void set_gc_state_mask(uint mask, bool value);
+
+public:
+ char gc_state();
+ static address gc_state_addr();
+
+ void set_concurrent_mark_in_progress(bool in_progress);
+ void set_evacuation_in_progress(bool in_progress);
+ void set_update_refs_in_progress(bool in_progress);
+ void set_degenerated_gc_in_progress(bool in_progress);
+ void set_full_gc_in_progress(bool in_progress);
+ void set_full_gc_move_in_progress(bool in_progress);
+ void set_has_forwarded_objects(bool cond);
+
+ inline bool is_stable() const;
+ inline bool is_idle() const;
+ inline bool is_concurrent_mark_in_progress() const;
+ inline bool is_update_refs_in_progress() const;
+ inline bool is_evacuation_in_progress() const;
+ inline bool is_degenerated_gc_in_progress() const;
+ inline bool is_full_gc_in_progress() const;
+ inline bool is_full_gc_move_in_progress() const;
+ inline bool has_forwarded_objects() const;
+ inline bool is_gc_in_progress_mask(uint mask) const;
+
+// ---------- GC cancellation and degeneration machinery
+//
+// Cancelled GC flag is used to notify concurrent phases that they should terminate.
+//
+public:
enum ShenandoahDegenPoint {
_degenerated_unset,
_degenerated_outside_cycle,
_degenerated_mark,
_degenerated_evac,
@@ -197,573 +344,363 @@
return "ERROR";
}
};
private:
- ShenandoahSharedBitmap _gc_state;
- ShenandoahHeapLock _lock;
- ShenandoahCollectorPolicy* _shenandoah_policy;
- ShenandoahHeuristics* _heuristics;
- size_t _bitmap_size;
- size_t _bitmap_regions_per_slice;
- size_t _bitmap_bytes_per_slice;
- MemRegion _heap_region;
- MemRegion _bitmap0_region;
- MemRegion _bitmap1_region;
- MemRegion _aux_bitmap_region;
+ ShenandoahSharedFlag _cancelled_gc;
+ inline bool try_cancel_gc();
- ShenandoahHeapRegion** _regions;
- ShenandoahFreeSet* _free_set;
- ShenandoahCollectionSet* _collection_set;
+public:
+ static address cancelled_gc_addr();
- ShenandoahRegionIterator _update_refs_iterator;
+ inline bool cancelled_gc() const;
- ShenandoahConcurrentMark* _scm;
- ShenandoahMarkCompact* _full_gc;
- ShenandoahVerifier* _verifier;
- ShenandoahPacer* _pacer;
+ inline void clear_cancelled_gc();
+ void cancel_gc(GCCause::Cause cause);
+// ---------- GC operations entry points
+//
+public:
+ // Entry points to STW GC operations, these cause a related safepoint, that then
+ // call the entry method below
+ void vmop_entry_init_mark();
+ void vmop_entry_final_mark();
+ void vmop_entry_final_evac();
+ void vmop_entry_init_updaterefs();
+ void vmop_entry_final_updaterefs();
+ void vmop_entry_full(GCCause::Cause cause);
+ void vmop_degenerated(ShenandoahDegenPoint point);
- ShenandoahControlThread* _control_thread;
+ // Entry methods to normally STW GC operations. These set up logging, monitoring
+ // and workers for net VM operation
+ void entry_init_mark();
+ void entry_final_mark();
+ void entry_final_evac();
+ void entry_init_updaterefs();
+ void entry_final_updaterefs();
+ void entry_full(GCCause::Cause cause);
+ void entry_degenerated(int point);
- ShenandoahMonitoringSupport* _monitoring_support;
+ // Entry methods to normally concurrent GC operations. These set up logging, monitoring
+ // for concurrent operation.
+ void entry_reset();
+ void entry_mark();
+ void entry_preclean();
+ void entry_cleanup();
+ void entry_evac();
+ void entry_updaterefs();
+ void entry_uncommit(double shrink_before);
- ShenandoahPhaseTimings* _phase_timings;
- ShenandoahAllocTracker* _alloc_tracker;
+private:
+ // Actual work for the phases
+ void op_init_mark();
+ void op_final_mark();
+ void op_final_evac();
+ void op_init_updaterefs();
+ void op_final_updaterefs();
+ void op_full(GCCause::Cause cause);
+ void op_degenerated(ShenandoahDegenPoint point);
+ void op_degenerated_fail();
+ void op_degenerated_futile();
- size_t _num_regions;
- size_t _initial_size;
- uint _max_workers;
+ void op_reset();
+ void op_mark();
+ void op_preclean();
+ void op_cleanup();
+ void op_conc_evac();
+ void op_stw_evac();
+ void op_updaterefs();
+ void op_uncommit(double shrink_before);
- ShenandoahWorkGang* _workers;
+ // Messages for GC trace event, they have to be immortal for
+ // passing around the logging/tracing systems
+ const char* init_mark_event_message() const;
+ const char* final_mark_event_message() const;
+ const char* conc_mark_event_message() const;
+ const char* degen_event_message(ShenandoahDegenPoint point) const;
- volatile jlong _used;
- volatile size_t _committed;
+// ---------- GC subsystems
+//
+private:
+ ShenandoahControlThread* _control_thread;
+ ShenandoahCollectorPolicy* _shenandoah_policy;
+ ShenandoahHeuristics* _heuristics;
+ ShenandoahFreeSet* _free_set;
+ ShenandoahConcurrentMark* _scm;
+ ShenandoahMarkCompact* _full_gc;
+ ShenandoahPacer* _pacer;
+ ShenandoahVerifier* _verifier;
- MarkBitMap _verification_bit_map;
- MarkBitMap _aux_bit_map;
+ ShenandoahAllocTracker* _alloc_tracker;
+ ShenandoahPhaseTimings* _phase_timings;
- ShenandoahMarkingContext* _complete_marking_context;
- ShenandoahMarkingContext* _next_marking_context;
+ ShenandoahControlThread* control_thread() { return _control_thread; }
+ ShenandoahMarkCompact* full_gc() { return _full_gc; }
- volatile jlong _bytes_allocated_since_gc_start;
+public:
+ ShenandoahCollectorPolicy* shenandoah_policy() const { return _shenandoah_policy; }
+ ShenandoahHeuristics* heuristics() const { return _heuristics; }
+ ShenandoahFreeSet* free_set() const { return _free_set; }
+ ShenandoahConcurrentMark* concurrent_mark() { return _scm; }
+ ShenandoahPacer* pacer() const { return _pacer; }
- ShenandoahSharedFlag _progress_last_gc;
+ ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }
+ ShenandoahAllocTracker* alloc_tracker() const { return _alloc_tracker; }
- ShenandoahSharedFlag _degenerated_gc_in_progress;
- ShenandoahSharedFlag _full_gc_in_progress;
- ShenandoahSharedFlag _full_gc_move_in_progress;
+ ShenandoahVerifier* verifier();
- ShenandoahSharedFlag _inject_alloc_failure;
+// ---------- VM subsystem bindings
+//
+private:
+ ShenandoahMonitoringSupport* _monitoring_support;
+ ConcurrentGCTimer* _gc_timer;
- ShenandoahSharedFlag _process_references;
- ShenandoahSharedFlag _unload_classes;
+public:
+ ShenandoahMonitoringSupport* monitoring_support() { return _monitoring_support; }
- ShenandoahSharedFlag _cancelled_gc;
+ GCTracer* tracer();
+ GCTimer* gc_timer() const;
+ CollectorPolicy* collector_policy() const;
+// ---------- Reference processing
+//
+private:
ReferenceProcessor* _ref_processor;
+ ShenandoahSharedFlag _process_references;
- ConcurrentGCTimer* _gc_timer;
+ void ref_processing_init();
- ShenandoahEvacOOMHandler _oom_evac_handler;
+public:
+ ReferenceProcessor* ref_processor() { return _ref_processor;}
+ void set_process_references(bool pr);
+ bool process_references() const;
-#ifdef ASSERT
- int _heap_expansion_count;
-#endif
+// ---------- Class Unloading
+//
+private:
+ ShenandoahSharedFlag _unload_classes;
public:
- ShenandoahHeap(ShenandoahCollectorPolicy* policy);
+ void set_unload_classes(bool uc);
+ bool unload_classes() const;
- void initialize_heuristics();
+ // Delete entries for dead interned string and clean up unreferenced symbols
+ // in symbol table, possibly in parallel.
+ void unload_classes_and_cleanup_tables(bool full_gc);
- const char* name() const /* override */;
- HeapWord* allocate_new_tlab(size_t word_size) /* override */;
- void print_on(outputStream* st) const /* override */;
- void print_extended_on(outputStream *st) const /* override */;
+// ---------- Generic interface hooks
+// Minor things that super-interface expects us to implement to play nice with
+// the rest of runtime. Some of the things here are not required to be implemented,
+// and can be stubbed out.
+//
+public:
+ AdaptiveSizePolicy* size_policy() shenandoah_not_implemented_return(NULL);
+ bool is_maximal_no_gc() const shenandoah_not_implemented_return(false);
+
+ bool is_in(const void* p) const;
+
+ // All objects can potentially move
+ bool is_scavengable(const void* addr) { return true; }
+
+ void collect(GCCause::Cause cause);
+ void do_full_collection(bool clear_all_soft_refs);
+
+ // Used for parsing heap during error printing
+ HeapWord* block_start(const void* addr) const;
+ size_t block_size(const HeapWord* addr) const;
+ bool block_is_obj(const HeapWord* addr) const;
+
+ // Used for native heap walkers: heap dumpers, mostly
+ void object_iterate(ObjectClosure* cl);
+ void safe_object_iterate(ObjectClosure* cl);
+ void space_iterate(SpaceClosure* scl);
+ void oop_iterate(ExtendedOopClosure* cl);
+ Space* space_containing(const void* oop) const;
- ShenandoahHeap::Name kind() const /* override */{
- return CollectedHeap::ShenandoahHeap;
- }
+ // Used by RMI
+ jlong millis_since_last_gc();
- jint initialize() /* override */;
- void post_initialize() /* override */;
- size_t capacity() const /* override */;
- size_t used() const /* override */;
- size_t committed() const;
- bool is_maximal_no_gc() const /* override */;
- size_t max_capacity() const /* override */;
- size_t initial_capacity() const /* override */;
- bool is_in(const void* p) const /* override */;
- bool is_scavengable(const void* addr) /* override */;
- HeapWord* mem_allocate(size_t size, bool* what) /* override */;
- bool can_elide_tlab_store_barriers() const /* override */;
- oop new_store_pre_barrier(JavaThread* thread, oop new_obj) /* override */;
- bool can_elide_initializing_store_barrier(oop new_obj) /* override */;
- bool card_mark_must_follow_store() const /* override */;
- void collect(GCCause::Cause cause) /* override */;
- void do_full_collection(bool clear_all_soft_refs) /* override */;
- AdaptiveSizePolicy* size_policy() /* override */;
- CollectorPolicy* collector_policy() const /* override */;
- void ensure_parsability(bool retire_tlabs) /* override */;
- HeapWord* block_start(const void* addr) const /* override */;
- size_t block_size(const HeapWord* addr) const /* override */;
- bool block_is_obj(const HeapWord* addr) const /* override */;
- jlong millis_since_last_gc() /* override */;
- void prepare_for_verify() /* override */;
- void print_gc_threads_on(outputStream* st) const /* override */;
- void gc_threads_do(ThreadClosure* tcl) const /* override */;
- void print_tracing_info() const /* override */;
- void verify(bool silent, VerifyOption vo) /* override */;
- bool supports_tlab_allocation() const /* override */;
- size_t tlab_capacity(Thread *thr) const /* override */;
- void object_iterate(ObjectClosure* cl) /* override */;
- void safe_object_iterate(ObjectClosure* cl) /* override */;
- size_t unsafe_max_tlab_alloc(Thread *thread) const /* override */;
- size_t max_tlab_size() const /* override */;
- void resize_all_tlabs() /* override */;
- void accumulate_statistics_all_gclabs() /* override */;
- HeapWord* tlab_post_allocation_setup(HeapWord* obj) /* override */;
- uint oop_extra_words() /* override */;
- size_t tlab_used(Thread* ignored) const /* override */;
- void stop() /* override */;
- bool is_in_partial_collection(const void* p) /* override */;
- bool supports_heap_inspection() const /* override */;
+ bool can_elide_tlab_store_barriers() const { return true; }
+ oop new_store_pre_barrier(JavaThread* thread, oop new_obj) { return new_obj; }
+ bool can_elide_initializing_store_barrier(oop new_obj) { return true; }
+ bool card_mark_must_follow_store() const { return false; }
- void space_iterate(SpaceClosure* scl) /* override */;
- void oop_iterate(ExtendedOopClosure* cl) /* override */;
+ bool is_in_partial_collection(const void* p) shenandoah_not_implemented_return(false);
+ bool supports_heap_inspection() const { return true; }
- Space* space_containing(const void* oop) const;
void gc_prologue(bool b);
void gc_epilogue(bool b);
-#ifndef CC_INTERP
- void compile_prepare_oop(MacroAssembler* masm, Register obj) /* override */;
-#endif
+ void acquire_pending_refs_lock();
+ void release_pending_refs_lock();
+// ---------- Code roots handling hooks
+//
+public:
void register_nmethod(nmethod* nm);
void unregister_nmethod(nmethod* nm);
- /* override: object pinning support */
+// ---------- Pinning hooks
+//
+public:
+ // Shenandoah supports per-object (per-region) pinning
bool supports_object_pinning() const { return true; }
+
oop pin_object(JavaThread* thread, oop obj);
void unpin_object(JavaThread* thread, oop obj);
- static ShenandoahHeap* heap();
- static ShenandoahHeap* heap_no_check();
- static size_t conservative_max_heap_alignment();
- static address in_cset_fast_test_addr();
- static address cancelled_gc_addr();
- static address gc_state_addr();
-
- ShenandoahCollectorPolicy *shenandoahPolicy() const { return _shenandoah_policy; }
- ShenandoahHeuristics* heuristics() const { return _heuristics; }
- ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }
- ShenandoahAllocTracker* alloc_tracker() const { return _alloc_tracker; }
-
- inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const;
- inline size_t heap_region_index_containing(const void* addr) const;
- inline bool requires_marking(const void* entry) const;
-
- template <class T>
- inline oop maybe_update_with_forwarded(T* p);
-
- template <class T>
- inline oop maybe_update_with_forwarded_not_null(T* p, oop obj);
-
- template <class T>
- inline oop update_with_forwarded_not_null(T* p, oop obj);
-
- void trash_cset_regions();
-
- void stop_concurrent_marking();
-
- void prepare_for_concurrent_evacuation();
- void evacuate_and_update_roots();
-
- void update_heap_references(bool concurrent);
-
- void roots_iterate(OopClosure* cl);
-
+// ---------- Allocation support
+//
private:
- void set_gc_state_mask(uint mask, bool value);
+ HeapWord* allocate_memory_under_lock(ShenandoahAllocRequest& request, bool& in_new_region);
+ inline HeapWord* allocate_from_gclab(Thread* thread, size_t size);
+ HeapWord* allocate_from_gclab_slow(Thread* thread, size_t size);
+ HeapWord* allocate_new_gclab(size_t min_size, size_t word_size, size_t* actual_size);
public:
- void set_concurrent_mark_in_progress(bool in_progress);
- void set_evacuation_in_progress(bool in_progress);
- void set_update_refs_in_progress(bool in_progress);
- void set_degenerated_gc_in_progress(bool in_progress);
- void set_full_gc_in_progress(bool in_progress);
- void set_full_gc_move_in_progress(bool in_progress);
- void set_has_forwarded_objects(bool cond);
-
- char gc_state();
-
- void set_process_references(bool pr);
- void set_unload_classes(bool uc);
-
- inline bool is_stable() const;
- inline bool is_idle() const;
- inline bool is_concurrent_mark_in_progress() const;
- inline bool is_update_refs_in_progress() const;
- inline bool is_evacuation_in_progress() const;
- inline bool is_degenerated_gc_in_progress() const;
- inline bool is_full_gc_in_progress() const;
- inline bool is_full_gc_move_in_progress() const;
- inline bool has_forwarded_objects() const;
- inline bool is_gc_in_progress_mask(uint mask) const;
-
- bool process_references() const;
- bool unload_classes() const;
-
- void force_satb_flush_all_threads();
-
- bool last_gc_made_progress() const;
-
- inline bool region_in_collection_set(size_t region_index) const;
-
- void acquire_pending_refs_lock();
- void release_pending_refs_lock();
-
- // Mainly there to avoid accidentally calling the templated
- // method below with ShenandoahHeapRegion* which would be *wrong*.
- inline bool in_collection_set(ShenandoahHeapRegion* r) const;
-
- template <class T>
- inline bool in_collection_set(T obj) const;
-
- // Evacuates object src. Returns the evacuated object if this thread
- // succeeded, otherwise rolls back the evacuation and returns the
- // evacuated object by the competing thread. 'succeeded' is an out
- // param and set to true if this thread succeeded, otherwise to false.
- inline oop evacuate_object(oop src, Thread* thread, bool& evacuated);
- inline bool cancelled_gc() const;
- inline bool try_cancel_gc();
- inline void clear_cancelled_gc();
-
- inline ShenandoahHeapRegion* const get_region(size_t region_idx) const;
- void heap_region_iterate(ShenandoahHeapRegionClosure& cl) const;
-
- ShenandoahFreeSet* free_set() const { return _free_set; }
- ShenandoahCollectionSet* collection_set() const { return _collection_set; }
-
- void increase_used(size_t bytes);
- void decrease_used(size_t bytes);
-
- void set_used(size_t bytes);
+#ifndef CC_INTERP
+ void compile_prepare_oop(MacroAssembler* masm, Register obj);
+#endif
- void increase_committed(size_t bytes);
- void decrease_committed(size_t bytes);
+ HeapWord* allocate_memory(ShenandoahAllocRequest& request);
+ HeapWord* mem_allocate(size_t size, bool* what);
- void increase_allocated(size_t bytes);
+ uint oop_extra_words();
void notify_mutator_alloc_words(size_t words, bool waste);
- void reset_next_mark_bitmap();
+ // Shenandoah supports TLAB allocation
+ bool supports_tlab_allocation() const { return true; }
- inline ShenandoahMarkingContext* complete_marking_context() const {
- return _complete_marking_context;
- }
+ HeapWord* allocate_new_tlab(size_t word_size);
+ size_t tlab_capacity(Thread *thr) const;
+ size_t unsafe_max_tlab_alloc(Thread *thread) const;
+ size_t max_tlab_size() const;
+ size_t tlab_used(Thread* ignored) const;
- inline ShenandoahMarkingContext* next_marking_context() const {
- return _next_marking_context;
- }
-
- bool commit_bitmap_slice(ShenandoahHeapRegion *r);
- bool uncommit_bitmap_slice(ShenandoahHeapRegion *r);
- bool is_bitmap_slice_committed(ShenandoahHeapRegion* r, bool skip_self = false);
-
- void print_heap_regions_on(outputStream* st) const;
+ HeapWord* tlab_post_allocation_setup(HeapWord* obj);
- size_t bytes_allocated_since_gc_start();
- void reset_bytes_allocated_since_gc_start();
-
- void trash_humongous_region_at(ShenandoahHeapRegion *r);
-
- ShenandoahMonitoringSupport* monitoring_support();
- ShenandoahConcurrentMark* concurrentMark() { return _scm; }
- ShenandoahMarkCompact* full_gc() { return _full_gc; }
- ShenandoahVerifier* verifier();
- ShenandoahPacer* pacer() const;
-
- ReferenceProcessor* ref_processor() { return _ref_processor;}
-
- ShenandoahWorkGang* workers() const { return _workers;}
+ void resize_tlabs();
+ void resize_all_tlabs();
- uint max_workers();
+ void accumulate_statistics_tlabs();
+ void accumulate_statistics_all_gclabs();
- void assert_gc_workers(uint nworker) PRODUCT_RETURN;
+ void make_parsable(bool retire_tlabs);
+ void ensure_parsability(bool retire_tlabs);
- ShenandoahHeapRegion* next_compaction_region(const ShenandoahHeapRegion* r);
+// ---------- Marking support
+//
+private:
+ ShenandoahMarkingContext* _marking_context;
+ MemRegion _bitmap_region;
+ MemRegion _aux_bitmap_region;
+ MarkBitMap _verification_bit_map;
+ MarkBitMap _aux_bit_map;
- void heap_region_iterate(ShenandoahHeapRegionClosure* blk, bool skip_cset_regions = false, bool skip_humongous_continuation = false) const;
+ size_t _bitmap_size;
+ size_t _bitmap_regions_per_slice;
+ size_t _bitmap_bytes_per_slice;
- // Delete entries for dead interned string and clean up unreferenced symbols
- // in symbol table, possibly in parallel.
- void unload_classes_and_cleanup_tables(bool full_gc);
+ // Used for buffering per-region liveness data.
+ // Needed since ShenandoahHeapRegion uses atomics to update liveness.
+ //
+ // The array has max-workers elements, each of which is an array of
+ // jushort * max_regions. The choice of jushort is not accidental:
+ // there is a tradeoff between static/dynamic footprint that translates
+ // into cache pressure (which is already high during marking), and
+ // too many atomic updates. size_t/jint is too large, jbyte is too small.
+ jushort** _liveness_cache;
- inline size_t num_regions() const { return _num_regions; }
+public:
+ inline ShenandoahMarkingContext* complete_marking_context() const;
+ inline ShenandoahMarkingContext* marking_context() const;
+ inline void mark_complete_marking_context();
+ inline void mark_incomplete_marking_context();
- // Call before starting evacuation.
- void enter_evacuation();
- // Call after finished with evacuation.
- void leave_evacuation();
+ template<class T>
+ inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl);
-private:
template<class T>
inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit);
template<class T>
inline void marked_object_oop_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit);
-public:
- template<class T>
- inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl);
-
- template<class T>
- inline void marked_object_safe_iterate(ShenandoahHeapRegion* region, T* cl);
-
- template<class T>
- inline void marked_object_oop_iterate(ShenandoahHeapRegion* region, T* cl);
+ void reset_mark_bitmap();
- template<class T>
- inline void marked_object_oop_safe_iterate(ShenandoahHeapRegion* region, T* cl);
+ // SATB barriers hooks
+ inline bool requires_marking(const void* entry) const;
+ void force_satb_flush_all_threads();
- GCTimer* gc_timer() const;
- GCTracer* tracer();
+ // Support for bitmap uncommits
+ bool commit_bitmap_slice(ShenandoahHeapRegion *r);
+ bool uncommit_bitmap_slice(ShenandoahHeapRegion *r);
+ bool is_bitmap_slice_committed(ShenandoahHeapRegion* r, bool skip_self = false);
- void swap_mark_contexts();
+ // Liveness caching support
+ jushort* get_liveness_cache(uint worker_id);
+ void flush_liveness_cache(uint worker_id);
- void cancel_gc(GCCause::Cause cause);
+// ---------- Evacuation support
+//
+private:
+ ShenandoahCollectionSet* _collection_set;
+ ShenandoahEvacOOMHandler _oom_evac_handler;
- ShenandoahHeapLock* lock() { return &_lock; }
- void assert_heaplock_owned_by_current_thread() PRODUCT_RETURN;
- void assert_heaplock_not_owned_by_current_thread() PRODUCT_RETURN;
- void assert_heaplock_or_safepoint() PRODUCT_RETURN;
+ void evacuate_and_update_roots();
public:
- typedef enum {
- _alloc_shared, // Allocate common, outside of TLAB
- _alloc_shared_gc, // Allocate common, outside of GCLAB
- _alloc_tlab, // Allocate TLAB
- _alloc_gclab, // Allocate GCLAB
- _ALLOC_LIMIT,
- } AllocType;
-
- static const char* alloc_type_to_string(AllocType type) {
- switch (type) {
- case _alloc_shared:
- return "Shared";
- case _alloc_shared_gc:
- return "Shared GC";
- case _alloc_tlab:
- return "TLAB";
- case _alloc_gclab:
- return "GCLAB";
- default:
- ShouldNotReachHere();
- return "";
- }
- }
-
- class ShenandoahAllocationRequest : StackObj {
- private:
- size_t _min_size;
- size_t _requested_size;
- size_t _actual_size;
- AllocType _alloc_type;
-#ifdef ASSERT
- bool _actual_size_set;
-#endif
-
- ShenandoahAllocationRequest(size_t _min_size, size_t _requested_size, AllocType _alloc_type) :
- _min_size(_min_size), _requested_size(_requested_size),
- _actual_size(0), _alloc_type(_alloc_type)
-#ifdef ASSERT
- , _actual_size_set(false)
-#endif
- {}
-
- public:
- static inline ShenandoahAllocationRequest for_tlab(size_t requested_size) {
- return ShenandoahAllocationRequest(requested_size, requested_size, ShenandoahHeap::_alloc_tlab);
- }
-
- static inline ShenandoahAllocationRequest for_gclab(size_t min_size, size_t requested_size) {
- return ShenandoahAllocationRequest(min_size, requested_size, ShenandoahHeap::_alloc_gclab);
- }
-
- static inline ShenandoahAllocationRequest for_shared_gc(size_t requested_size) {
- return ShenandoahAllocationRequest(0, requested_size, ShenandoahHeap::_alloc_shared_gc);
- }
-
- static inline ShenandoahAllocationRequest for_shared(size_t requested_size) {
- return ShenandoahAllocationRequest(0, requested_size, ShenandoahHeap::_alloc_shared);
- }
-
- inline size_t size() {
- return _requested_size;
- }
-
- inline AllocType type() {
- return _alloc_type;
- }
-
- inline size_t min_size() {
- assert (is_lab_alloc(), "Only access for LAB allocs");
- return _min_size;
- }
-
- inline size_t actual_size() {
- assert (_actual_size_set, "Should be set");
- return _actual_size;
- }
-
- inline void set_actual_size(size_t v) {
-#ifdef ASSERT
- assert (!_actual_size_set, "Should not be set");
- _actual_size_set = true;
-#endif
- _actual_size = v;
- }
+ static address in_cset_fast_test_addr();
- inline bool is_mutator_alloc() {
- switch (_alloc_type) {
- case _alloc_tlab:
- case _alloc_shared:
- return true;
- case _alloc_gclab:
- case _alloc_shared_gc:
- return false;
- default:
- ShouldNotReachHere();
- return false;
- }
- }
+ ShenandoahCollectionSet* collection_set() const { return _collection_set; }
- inline bool is_gc_alloc() {
- switch (_alloc_type) {
- case _alloc_tlab:
- case _alloc_shared:
- return false;
- case _alloc_gclab:
- case _alloc_shared_gc:
- return true;
- default:
- ShouldNotReachHere();
- return false;
- }
- }
+ template <class T>
+ inline bool in_collection_set(T obj) const;
- inline bool is_lab_alloc() {
- switch (_alloc_type) {
- case _alloc_tlab:
- case _alloc_gclab:
- return true;
- case _alloc_shared:
- case _alloc_shared_gc:
- return false;
- default:
- ShouldNotReachHere();
- return false;
- }
- }
- };
+ // Avoid accidentally calling the method above with ShenandoahHeapRegion*, which would be *wrong*.
+ inline bool in_collection_set(ShenandoahHeapRegion* r) shenandoah_not_implemented_return(false);
+ // Evacuates object src. Returns the evacuated object, either evacuated
+ // by this thread, or by some other thread.
+ inline oop evacuate_object(oop src, Thread* thread, bool& evacuated);
-private:
- HeapWord* allocate_memory_under_lock(ShenandoahAllocationRequest& request, bool& in_new_region);
- HeapWord* allocate_memory(ShenandoahAllocationRequest& request);
+ // Call before/after evacuation.
+ void enter_evacuation();
+ void leave_evacuation();
- // Shenandoah functionality.
- inline HeapWord* allocate_from_gclab(Thread* thread, size_t size);
- HeapWord* allocate_from_gclab_slow(Thread* thread, size_t size);
- HeapWord* allocate_new_gclab(size_t min_size, size_t word_size, size_t* actual_size);
+// ---------- Helper functions
+//
+public:
+ template <class T>
+ inline oop maybe_update_with_forwarded(T* p);
- template<class T>
- inline void do_object_marked_complete(T* cl, oop obj);
+ template <class T>
+ inline oop maybe_update_with_forwarded_not_null(T* p, oop obj);
- ShenandoahControlThread* control_thread() { return _control_thread; }
+ template <class T>
+ inline oop update_with_forwarded_not_null(T* p, oop obj);
inline oop atomic_compare_exchange_oop(oop n, narrowOop* addr, oop c);
inline oop atomic_compare_exchange_oop(oop n, oop* addr, oop c);
- void ref_processing_init();
-
-public:
- void make_parsable(bool retire_tlabs);
- void accumulate_statistics_tlabs();
- void resize_tlabs();
-
-public:
- // Entry points to STW GC operations, these cause a related safepoint, that then
- // call the entry method below
- void vmop_entry_init_mark();
- void vmop_entry_final_mark();
- void vmop_entry_final_evac();
- void vmop_entry_init_updaterefs();
- void vmop_entry_final_updaterefs();
- void vmop_entry_full(GCCause::Cause cause);
- void vmop_degenerated(ShenandoahDegenPoint point);
+ void trash_humongous_region_at(ShenandoahHeapRegion *r);
- // Entry methods to normally STW GC operations. These set up logging, monitoring
- // and workers for net VM operation
- void entry_init_mark();
- void entry_final_mark();
- void entry_final_evac();
- void entry_init_updaterefs();
- void entry_final_updaterefs();
- void entry_full(GCCause::Cause cause);
- void entry_degenerated(int point);
+ void stop_concurrent_marking();
- // Entry methods to normally concurrent GC operations. These set up logging, monitoring
- // for concurrent operation.
- void entry_mark();
- void entry_preclean();
- void entry_cleanup();
- void entry_cleanup_bitmaps();
- void entry_evac();
- void entry_updaterefs();
- void entry_uncommit(double shrink_before);
+ void roots_iterate(OopClosure* cl);
private:
- // Actual work for the phases
- void op_init_mark();
- void op_final_mark();
- void op_final_evac();
- void op_init_updaterefs();
- void op_final_updaterefs();
- void op_full(GCCause::Cause cause);
- void op_degenerated(ShenandoahDegenPoint point);
- void op_degenerated_fail();
- void op_degenerated_futile();
-
- void op_mark();
- void op_preclean();
- void op_cleanup();
- void op_evac();
- void op_updaterefs();
- void op_cleanup_bitmaps();
- void op_uncommit(double shrink_before);
-
- // Messages for GC trace event, they have to be immortal for
- // passing around the logging/tracing systems
- const char* init_mark_event_message() const;
- const char* final_mark_event_message() const;
- const char* conc_mark_event_message() const;
- const char* degen_event_message(ShenandoahDegenPoint point) const;
+ void trash_cset_regions();
+ void update_heap_references(bool concurrent);
+// ---------- Testing helpers functions
+//
private:
+ ShenandoahSharedFlag _inject_alloc_failure;
+
void try_inject_alloc_failure();
bool should_inject_alloc_failure();
};
-class ShenandoahIsAliveSelector : public StackObj {
-private:
- ShenandoahIsAliveClosure _alive_cl;
- ShenandoahForwardedIsAliveClosure _fwd_alive_cl;
-public:
- BoolObjectClosure* is_alive_closure();
-};
-
-
#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP
< prev index next >