< 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 >