1 /*
   2  * Copyright (c) 2013, 2015, Red Hat, Inc. and/or its affiliates.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP
  25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP
  26 
  27 #include "gc/shared/cmBitMap.hpp"
  28 
  29 class ConcurrentGCTimer;
  30 
  31 class ShenandoahCollectorPolicy;
  32 class ShenandoahHeapRegion;
  33 class ShenandoahHeapRegionClosure;
  34 class ShenandoahHeapRegionSet;
  35 class ShenandoahCollectionSet;
  36 class ShenandoahFreeSet;
  37 class ShenandoahConcurrentMark;
  38 class ShenandoahConcurrentThread;
  39 class ShenandoahMonitoringSupport;
  40 
  41 class ShenandoahAlwaysTrueClosure : public BoolObjectClosure {
  42 public:
  43   bool do_object_b(oop p) { return true; }
  44 };
  45 
  46 
  47 class ShenandoahIsAliveClosure: public BoolObjectClosure {
  48 private:
  49   ShenandoahHeap* _heap;
  50 public:
  51   ShenandoahIsAliveClosure();
  52   void init(ShenandoahHeap* heap);
  53   bool do_object_b(oop obj);
  54 };
  55 
  56 class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure {
  57 private:
  58   ShenandoahHeap* _heap;
  59 public:
  60   ShenandoahForwardedIsAliveClosure();
  61   void init(ShenandoahHeap* heap);
  62   bool do_object_b(oop obj);
  63 };
  64 
  65 
  66 // // A "ShenandoahHeap" is an implementation of a java heap for HotSpot.
  67 // // It uses a new pauseless GC algorithm based on Brooks pointers.
  68 // // Derived from G1
  69 
  70 // //
  71 // // CollectedHeap
  72 // //    SharedHeap
  73 // //      ShenandoahHeap
  74 
  75 class ShenandoahHeap : public CollectedHeap {
  76 
  77 private:
  78 
  79   static ShenandoahHeap* _pgc;
  80   ShenandoahCollectorPolicy* _shenandoah_policy;
  81   VirtualSpace _storage;
  82   ShenandoahHeapRegion* _first_region;
  83   HeapWord* _first_region_bottom;
  84 
  85   // Sortable array of regions
  86   ShenandoahHeapRegionSet* _ordered_regions;
  87   ShenandoahHeapRegionSet* _sorted_regions;
  88   ShenandoahFreeSet* _free_regions;
  89   ShenandoahCollectionSet* _collection_set;
  90   ShenandoahHeapRegion* _currentAllocationRegion;
  91   ShenandoahConcurrentMark* _scm;
  92 
  93 
  94 
  95   ShenandoahConcurrentThread* _concurrent_gc_thread;
  96 
  97   ShenandoahMonitoringSupport* _monitoring_support;
  98 
  99   size_t _num_regions;
 100   size_t _max_regions;
 101   size_t _initialSize;
 102 #ifndef NDEBUG
 103   uint _numAllocs;
 104 #endif
 105   uint _max_parallel_workers;
 106   uint _max_conc_workers;
 107   uint _max_workers;
 108 
 109   WorkGang* _conc_workers;
 110   WorkGang* _workers;
 111 
 112 
 113   volatile size_t _used;
 114 
 115   CMBitMap _mark_bit_map0;
 116   CMBitMap _mark_bit_map1;
 117   CMBitMap* _prev_mark_bit_map;
 118   CMBitMap* _next_mark_bit_map;
 119 
 120   bool* _in_cset_fast_test;
 121   bool* _in_cset_fast_test_base;
 122   size_t _in_cset_fast_test_length;
 123 
 124   HeapWord** _top_at_mark_starts;
 125   HeapWord** _top_at_mark_starts_base;
 126 
 127   bool _cancelled_concgc;
 128 
 129   jbyte _growing_heap;
 130 
 131   size_t _bytes_allocated_since_cm;
 132   size_t _bytes_allocated_during_cm;
 133   size_t _bytes_allocated_during_cm_start;
 134   size_t _max_allocated_gc;
 135   size_t _allocated_last_gc;
 136   size_t _used_start_gc;
 137 
 138   unsigned int _concurrent_mark_in_progress;
 139 
 140   bool _full_gc_in_progress;
 141 
 142   unsigned int _evacuation_in_progress;
 143   bool _need_update_refs;
 144   bool _need_reset_bitmaps;
 145 
 146   ReferenceProcessor* _ref_processor;
 147 
 148   ShenandoahForwardedIsAliveClosure isAlive;
 149 
 150   ConcurrentGCTimer* _gc_timer;
 151 
 152 public:
 153   ShenandoahHeap(ShenandoahCollectorPolicy* policy);
 154 
 155   HeapWord *first_region_bottom() { return _first_region_bottom; }
 156 
 157   const char* name() const /* override */;
 158   HeapWord* allocate_new_tlab(size_t word_size) /* override */;
 159   void print_on(outputStream* st) const /* override */;
 160 
 161   ShenandoahHeap::Name kind() const  /* override */{
 162     return CollectedHeap::ShenandoahHeap;
 163   }
 164 
 165   jint initialize() /* override */;
 166   void post_initialize() /* override */;
 167   size_t capacity() const /* override */;
 168   size_t used() const /* override */;
 169   bool is_maximal_no_gc() const /* override */;
 170   size_t max_capacity() const /* override */;
 171   size_t min_capacity() const /* override */;
 172   bool is_in(const void* p) const /* override */;
 173   bool is_scavengable(const void* addr) /* override */;
 174   HeapWord* mem_allocate(size_t size, bool* what) /* override */;
 175   bool can_elide_tlab_store_barriers() const /* override */;
 176   oop new_store_pre_barrier(JavaThread* thread, oop new_obj) /* override */;
 177   bool can_elide_initializing_store_barrier(oop new_obj) /* override */;
 178   bool card_mark_must_follow_store() const /* override */;
 179   void collect(GCCause::Cause) /* override */;
 180   void do_full_collection(bool clear_all_soft_refs) /* override */;
 181   AdaptiveSizePolicy* size_policy() /* override */;
 182   CollectorPolicy* collector_policy() const /* override */;
 183   void ensure_parsability(bool retire_tlabs) /* override */;
 184   HeapWord* block_start(const void* addr) const /* override */;
 185   size_t block_size(const HeapWord* addr) const /* override */;
 186   bool block_is_obj(const HeapWord* addr) const /* override */;
 187   jlong millis_since_last_gc() /* override */;
 188   void prepare_for_verify() /* override */;
 189   void print_gc_threads_on(outputStream* st) const /* override */;
 190   void gc_threads_do(ThreadClosure* tcl) const /* override */;
 191   void print_tracing_info() const /* override */;
 192   void verify(VerifyOption vo) /* override */;
 193   bool supports_tlab_allocation() const /* override */;
 194   size_t tlab_capacity(Thread *thr) const /* override */;
 195   void object_iterate(ObjectClosure* cl) /* override */;
 196   void safe_object_iterate(ObjectClosure* cl) /* override */;
 197   size_t unsafe_max_tlab_alloc(Thread *thread) const /* override */;
 198   size_t max_tlab_size() const /* override */;
 199   void resize_all_tlabs() /* override */;
 200   void accumulate_statistics_all_gclabs() /* override */;
 201   HeapWord* tlab_post_allocation_setup(HeapWord* obj) /* override */;
 202   uint oop_extra_words() /* override */;
 203   size_t tlab_used(Thread* ignored) const /* override */;
 204   void stop() /* override */;
 205 
 206   bool needs_reference_pending_list_locker_thread() const /* override */;
 207 
 208 #ifndef CC_INTERP
 209   void compile_prepare_oop(MacroAssembler* masm, Register obj) /* override */;
 210 #endif
 211 
 212   void register_nmethod(nmethod* nm);
 213   void unregister_nmethod(nmethod* nm);
 214 
 215   void pin_object(oop o) /* override */;
 216   void unpin_object(oop o) /* override */;
 217 
 218   static ShenandoahHeap* heap();
 219   static ShenandoahHeap* heap_no_check();
 220   static size_t conservative_max_heap_alignment();
 221   static address in_cset_fast_test_addr();
 222   static address cancelled_concgc_addr();
 223 
 224   static void pretouch_storage(char* start, char* end, WorkGang* workers);
 225 
 226   ShenandoahCollectorPolicy *shenandoahPolicy() { return _shenandoah_policy;}
 227 
 228   inline ShenandoahHeapRegion* heap_region_containing(const void* addr) const;
 229   inline uint heap_region_index_containing(const void* addr) const;
 230   inline bool requires_marking(const void* entry) const;
 231   template <class T>
 232   inline oop maybe_update_oop_ref(T* p);
 233 
 234   void recycle_dirty_regions();
 235 
 236   void start_concurrent_marking();
 237   void stop_concurrent_marking();
 238   inline bool concurrent_mark_in_progress();
 239   static address concurrent_mark_in_progress_addr();
 240 
 241   void prepare_for_concurrent_evacuation();
 242   void evacuate_and_update_roots();
 243   inline bool is_evacuation_in_progress();
 244   void set_evacuation_in_progress(bool in_progress);
 245 
 246   void set_full_gc_in_progress(bool in_progress);
 247   bool is_full_gc_in_progress() const;
 248 
 249   inline bool need_update_refs() const;
 250   void set_need_update_refs(bool update_refs);
 251 
 252   inline bool in_cset_fast_test(HeapWord* obj);
 253   void clear_cset_fast_test();
 254   void register_region_with_in_cset_fast_test(ShenandoahHeapRegion* r);
 255 
 256   inline bool allocated_after_mark_start(HeapWord* addr) const;
 257   void set_top_at_mark_start(HeapWord* region_base, HeapWord* addr);
 258 
 259   inline oop  evacuate_object(oop src, Thread* thread);
 260   inline bool cancelled_concgc() const;
 261   void clear_cancelled_concgc();
 262 
 263   ShenandoahHeapRegionSet* regions() { return _ordered_regions;}
 264   ShenandoahHeapRegionSet* sorted_regions() { return _sorted_regions;}
 265   ShenandoahFreeSet* free_regions();
 266   void clear_free_regions();
 267   void add_free_region(ShenandoahHeapRegion* r);
 268 
 269   void increase_used(size_t bytes);
 270   void decrease_used(size_t bytes);
 271 
 272   void set_used(size_t bytes);
 273   size_t calculateUsed();
 274 
 275   void reset_mark_bitmap(WorkGang* gang);
 276   void reset_prev_mark_bitmap(WorkGang* gang);
 277   void reset_mark_bitmap_range(HeapWord* from, HeapWord* to);
 278   void reset_prev_mark_bitmap_range(HeapWord* from, HeapWord* to);
 279   CMBitMap* prev_mark_bit_map();
 280   CMBitMap* next_mark_bit_map();
 281   inline bool is_marked_prev(oop obj) const;
 282   inline bool mark_current(oop obj) const;
 283   inline bool is_marked_current(oop obj) const;
 284   bool is_obj_dead(const oop obj, const ShenandoahHeapRegion* r) const;
 285   bool is_bitmap_clear();
 286 
 287   void parallel_evacuate_region(ShenandoahHeapRegion* from_region);
 288 
 289   template <class T>
 290   inline oop update_oop_ref_not_null(T* p, oop obj);
 291 
 292   void print_heap_regions(outputStream* st = tty) const;
 293   void print_all_refs(const char* prefix);
 294   void print_heap_locations(HeapWord* start, HeapWord* end);
 295 
 296   size_t bytes_allocated_since_cm();
 297   void set_bytes_allocated_since_cm(size_t bytes);
 298 
 299   size_t max_allocated_gc();
 300 
 301   void reclaim_humongous_region_at(ShenandoahHeapRegion* r);
 302 
 303   VirtualSpace* storage() const;
 304 
 305   ShenandoahMonitoringSupport* monitoring_support();
 306   ShenandoahConcurrentMark* concurrentMark() { return _scm;}
 307 
 308   ReferenceProcessor* ref_processor() { return _ref_processor;}
 309 
 310   WorkGang* conc_workers() const { return _conc_workers;}
 311   WorkGang* workers() const { return _workers;}
 312 
 313   uint max_conc_workers();
 314   uint max_workers();
 315   uint max_parallel_workers();
 316 
 317   void do_evacuation();
 318   ShenandoahHeapRegion* next_compaction_region(const ShenandoahHeapRegion* r);
 319 
 320   void heap_region_iterate(ShenandoahHeapRegionClosure* blk, bool skip_dirty_regions = false, bool skip_humongous_continuation = false) const;
 321 
 322   void verify_heap_after_evacuation();
 323 
 324   // Delete entries for dead interned string and clean up unreferenced symbols
 325   // in symbol table, possibly in parallel.
 326   void unlink_string_and_symbol_table(BoolObjectClosure* is_alive, bool unlink_strings = true, bool unlink_symbols = true);
 327 
 328   size_t num_regions();
 329   size_t max_regions();
 330 
 331   // TODO: consider moving this into ShenandoahHeapRegion.
 332 
 333   template<class T>
 334   inline void marked_prev_object_iterate(ShenandoahHeapRegion* region, T* cl);
 335 
 336   template<class T>
 337   inline void marked_next_object_iterate(ShenandoahHeapRegion* region, T* cl);
 338 
 339   GCTimer* gc_timer() const;
 340 
 341 private:
 342   HeapWord* allocate_new_tlab(size_t word_size, bool mark);
 343   HeapWord* allocate_memory(size_t word_size, bool evacuating);
 344   // Shenandoah functionality.
 345   inline HeapWord* allocate_from_gclab(Thread* thread, size_t size);
 346   HeapWord* allocate_from_gclab_slow(Thread* thread, size_t size);
 347   HeapWord* allocate_new_gclab(size_t word_size);
 348 
 349   void roots_iterate(OopClosure* cl);
 350 
 351   template<class T>
 352   inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl, CMBitMap* mark_bit_map, HeapWord* top_at_mark_start);
 353 
 354   template<class T>
 355   inline void do_marked_object(CMBitMap* bitmap, T* cl, oop obj);
 356 
 357   ShenandoahConcurrentThread* concurrent_thread() { return _concurrent_gc_thread; }
 358 
 359   void swap_mark_bitmaps();
 360 
 361   inline bool mark_current_no_checks(oop obj) const;
 362   inline bool is_marked_current(oop obj, ShenandoahHeapRegion* r) const;
 363 
 364   inline bool is_marked_prev(oop obj, const ShenandoahHeapRegion* r) const;
 365 
 366   void parallel_evacuate();
 367 
 368   template <class T>
 369   inline oop maybe_update_oop_ref_not_null(T* p, oop obj);
 370 
 371   inline oop atomic_compare_exchange_oop(oop n, narrowOop* addr, oop c);
 372   inline oop atomic_compare_exchange_oop(oop n, oop* addr, oop c);
 373 
 374   void evacuate_region(ShenandoahHeapRegion* from_region, ShenandoahHeapRegion* to_region);
 375 
 376 #ifdef ASSERT
 377   void verify_evacuated_region(ShenandoahHeapRegion* from_region);
 378 #endif
 379 
 380   bool is_in_collection_set(const void* p);
 381 
 382   inline void copy_object(oop p, HeapWord* s, size_t words);
 383   void verify_copy(oop p, oop c);
 384   void verify_heap_size_consistency();
 385   void verify_heap_after_marking();
 386   void verify_heap_after_update_refs();
 387   void verify_regions_after_update_refs();
 388 
 389   void ref_processing_init();
 390 
 391   GCTracer* tracer();
 392   ShenandoahCollectionSet* collection_set() { return _collection_set; }
 393 
 394   bool call_from_write_barrier(bool evacuating);
 395   bool check_grow_heap();
 396   void grow_heap_by(size_t num_regions);
 397   void ensure_new_regions(size_t num_new_regions);
 398 
 399   void verify_evacuation(ShenandoahHeapRegion* from_region);
 400   void set_concurrent_mark_in_progress(bool in_progress);
 401 
 402   void oom_during_evacuation();
 403   void cancel_concgc();
 404 
 405   void verify_live();
 406   void verify_liveness_after_concurrent_mark();
 407 
 408   HeapWord* allocate_memory_work(size_t word_size);
 409   HeapWord* allocate_large_memory(size_t word_size);
 410 
 411   void set_from_region_protection(bool protect);
 412 
 413 };
 414 
 415 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP