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 #include "gc/shenandoah/shenandoahWorkGroup.hpp" 29 30 class ConcurrentGCTimer; 31 32 class ShenandoahCollectorPolicy; 33 class ShenandoahConnectionMatrix; 34 class ShenandoahHeapRegion; 35 class ShenandoahHeapRegionClosure; 36 class ShenandoahHeapRegionSet; 37 class ShenandoahCollectionSet; 38 class ShenandoahFreeSet; 39 class ShenandoahConcurrentMark; 40 class ShenandoahPartialGC; 41 class ShenandoahConcurrentThread; 42 class ShenandoahMonitoringSupport; 43 44 class SCMUpdateRefsClosure: public OopClosure { 45 private: 46 ShenandoahHeap* _heap; 47 48 template <class T> 49 inline void do_oop_work(T* p); 50 51 public: 52 SCMUpdateRefsClosure(); 53 54 public: 55 inline void do_oop(oop* p); 56 inline void do_oop(narrowOop* p); 57 }; 58 59 #ifdef ASSERT 60 class AssertToSpaceClosure : public OopClosure { 61 private: 62 template <class T> 63 void do_oop_nv(T* p); 64 public: 65 void do_oop(narrowOop* p); 66 void do_oop(oop* p); 67 }; 68 #endif 69 70 class ShenandoahAlwaysTrueClosure : public BoolObjectClosure { 71 public: 72 bool do_object_b(oop p) { return true; } 73 }; 74 75 76 class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure { 77 78 private: 79 ShenandoahHeap* _heap; 80 public: 81 ShenandoahForwardedIsAliveClosure(); 82 void init(ShenandoahHeap* heap); 83 bool do_object_b(oop obj); 84 }; 85 86 87 // // A "ShenandoahHeap" is an implementation of a java heap for HotSpot. 88 // // It uses a new pauseless GC algorithm based on Brooks pointers. 89 // // Derived from G1 90 91 // // 92 // // CollectedHeap 93 // // SharedHeap 94 // // ShenandoahHeap 95 96 class ShenandoahHeap : public CollectedHeap { 97 enum LockState { unlocked = 0, locked = 1 }; 98 99 public: 100 class ShenandoahHeapLock : public StackObj { 101 private: 102 ShenandoahHeap* _heap; 103 104 public: 105 ShenandoahHeapLock(ShenandoahHeap* heap) : _heap(heap) { 106 while (OrderAccess::load_acquire(& _heap->_heap_lock) == locked || Atomic::cmpxchg(locked, &_heap->_heap_lock, unlocked) == locked) { 107 SpinPause(); 108 } 109 assert(_heap->_heap_lock == locked, "sanity"); 110 111 #ifdef ASSERT 112 assert(_heap->_heap_lock_owner == NULL, "must not be owned"); 113 _heap->_heap_lock_owner = Thread::current(); 114 #endif 115 } 116 117 ~ShenandoahHeapLock() { 118 #ifdef ASSERT 119 _heap->assert_heaplock_owned_by_current_thread(); 120 _heap->_heap_lock_owner = NULL; 121 #endif 122 OrderAccess::release_store_fence(&_heap->_heap_lock, unlocked); 123 } 124 125 }; 126 127 public: 128 enum ShenandoahCancelCause { 129 _oom_evacuation, 130 _vm_stop, 131 }; 132 private: 133 134 ShenandoahCollectorPolicy* _shenandoah_policy; 135 VirtualSpace _storage; 136 size_t _bitmap_size; 137 MemRegion _heap_region; 138 139 // Sortable array of regions 140 ShenandoahHeapRegionSet* _ordered_regions; 141 ShenandoahFreeSet* _free_regions; 142 ShenandoahCollectionSet* _collection_set; 143 144 ShenandoahConcurrentMark* _scm; 145 ShenandoahPartialGC* _partial_gc; 146 147 ShenandoahConcurrentThread* _concurrent_gc_thread; 148 149 ShenandoahMonitoringSupport* _monitoring_support; 150 151 size_t _num_regions; 152 size_t _max_regions; 153 size_t _initialSize; 154 155 uint _max_workers; 156 ShenandoahWorkGang* _workers; 157 158 volatile size_t _used; 159 160 CMBitMap _verification_bit_map; 161 CMBitMap _mark_bit_map0; 162 CMBitMap _mark_bit_map1; 163 CMBitMap* _complete_mark_bit_map; 164 CMBitMap* _next_mark_bit_map; 165 166 bool* _in_cset_fast_test; 167 bool* _in_cset_fast_test_base; 168 size_t _in_cset_fast_test_length; 169 170 HeapWord** _complete_top_at_mark_starts; 171 HeapWord** _complete_top_at_mark_starts_base; 172 173 HeapWord** _next_top_at_mark_starts; 174 HeapWord** _next_top_at_mark_starts_base; 175 176 volatile jbyte _cancelled_concgc; 177 178 size_t _bytes_allocated_since_cm; 179 size_t _bytes_allocated_during_cm; 180 size_t _allocated_last_gc; 181 size_t _used_start_gc; 182 183 unsigned int _concurrent_mark_in_progress; 184 185 bool _full_gc_in_progress; 186 bool _update_refs_in_progress; 187 188 unsigned int _evacuation_in_progress; 189 bool _need_update_refs; 190 bool _need_reset_bitmaps; 191 192 ReferenceProcessor* _ref_processor; 193 194 ShenandoahForwardedIsAliveClosure isAlive; 195 196 ConcurrentGCTimer* _gc_timer; 197 198 // See allocate_memory() 199 volatile jbyte _heap_lock; 200 201 ShenandoahConnectionMatrix* _connection_matrix; 202 203 #ifdef ASSERT 204 Thread* volatile _heap_lock_owner; 205 #endif 206 207 public: 208 ShenandoahHeap(ShenandoahCollectorPolicy* policy); 209 210 const char* name() const /* override */; 211 HeapWord* allocate_new_tlab(size_t word_size) /* override */; 212 void print_on(outputStream* st) const /* override */; 213 214 ShenandoahHeap::Name kind() const /* override */{ 215 return CollectedHeap::ShenandoahHeap; 216 } 217 218 jint initialize() /* override */; 219 void post_initialize() /* override */; 220 size_t capacity() const /* override */; 221 size_t used() const /* override */; 222 bool is_maximal_no_gc() const /* override */; 223 size_t max_capacity() const /* override */; 224 size_t min_capacity() const /* override */; 225 bool is_in(const void* p) const /* override */; 226 bool is_scavengable(const void* addr) /* override */; 227 HeapWord* mem_allocate(size_t size, bool* what) /* override */; 228 bool can_elide_tlab_store_barriers() const /* override */; 229 oop new_store_pre_barrier(JavaThread* thread, oop new_obj) /* override */; 230 bool can_elide_initializing_store_barrier(oop new_obj) /* override */; 231 bool card_mark_must_follow_store() const /* override */; 232 void collect(GCCause::Cause) /* override */; 233 void do_full_collection(bool clear_all_soft_refs) /* override */; 234 AdaptiveSizePolicy* size_policy() /* override */; 235 CollectorPolicy* collector_policy() const /* override */; 236 void ensure_parsability(bool retire_tlabs) /* override */; 237 HeapWord* block_start(const void* addr) const /* override */; 238 size_t block_size(const HeapWord* addr) const /* override */; 239 bool block_is_obj(const HeapWord* addr) const /* override */; 240 jlong millis_since_last_gc() /* override */; 241 void prepare_for_verify() /* override */; 242 void print_gc_threads_on(outputStream* st) const /* override */; 243 void gc_threads_do(ThreadClosure* tcl) const /* override */; 244 void print_tracing_info() const /* override */; 245 void verify(VerifyOption vo) /* override */; 246 bool supports_tlab_allocation() const /* override */; 247 size_t tlab_capacity(Thread *thr) const /* override */; 248 void object_iterate(ObjectClosure* cl) /* override */; 249 void safe_object_iterate(ObjectClosure* cl) /* override */; 250 size_t unsafe_max_tlab_alloc(Thread *thread) const /* override */; 251 size_t max_tlab_size() const /* override */; 252 void resize_all_tlabs() /* override */; 253 void accumulate_statistics_all_gclabs() /* override */; 254 HeapWord* tlab_post_allocation_setup(HeapWord* obj) /* override */; 255 uint oop_extra_words() /* override */; 256 size_t tlab_used(Thread* ignored) const /* override */; 257 void stop() /* override */; 258 259 #ifndef CC_INTERP 260 void compile_prepare_oop(MacroAssembler* masm, Register obj) /* override */; 261 #endif 262 263 void register_nmethod(nmethod* nm); 264 void unregister_nmethod(nmethod* nm); 265 266 void pin_object(oop o) /* override */; 267 void unpin_object(oop o) /* override */; 268 269 static ShenandoahHeap* heap(); 270 static ShenandoahHeap* heap_no_check(); 271 static size_t conservative_max_heap_alignment(); 272 static address in_cset_fast_test_addr(); 273 static address cancelled_concgc_addr(); 274 275 ShenandoahCollectorPolicy *shenandoahPolicy() { return _shenandoah_policy;} 276 277 inline ShenandoahHeapRegion* heap_region_containing(const void* addr) const; 278 inline size_t heap_region_index_containing(const void* addr) const; 279 inline bool requires_marking(const void* entry) const; 280 template <class T> 281 inline oop maybe_update_oop_ref(T* p); 282 283 void recycle_dirty_regions(); 284 285 void start_concurrent_marking(); 286 void stop_concurrent_marking(); 287 inline bool concurrent_mark_in_progress(); 288 static address concurrent_mark_in_progress_addr(); 289 290 void prepare_for_concurrent_evacuation(); 291 void evacuate_and_update_roots(); 292 293 void do_partial_collection(); 294 295 void update_heap_references(ShenandoahHeapRegionSet* regions); 296 void concurrent_update_heap_references(); 297 void prepare_update_refs(); 298 void finish_update_refs(); 299 void verify_update_refs(); 300 301 private: 302 void set_evacuation_in_progress(bool in_progress); 303 public: 304 inline bool is_evacuation_in_progress(); 305 void set_evacuation_in_progress_concurrently(bool in_progress); 306 void set_evacuation_in_progress_at_safepoint(bool in_progress); 307 308 void set_full_gc_in_progress(bool in_progress); 309 bool is_full_gc_in_progress() const; 310 311 void set_update_refs_in_progress(bool in_progress); 312 bool is_update_refs_in_progress() const; 313 static address update_refs_in_progress_addr(); 314 315 inline bool need_update_refs() const; 316 void set_need_update_refs(bool update_refs); 317 318 inline bool region_in_collection_set(size_t region_index) const; 319 320 void set_region_in_collection_set(size_t region_index, bool b); 321 322 // Mainly there to avoid accidentally calling the templated 323 // method below with ShenandoahHeapRegion* which would be *wrong*. 324 inline bool in_collection_set(ShenandoahHeapRegion* r) const; 325 326 template <class T> 327 inline bool in_collection_set(T obj) const; 328 329 void clear_cset_fast_test(); 330 331 inline bool allocated_after_next_mark_start(HeapWord* addr) const; 332 void set_next_top_at_mark_start(HeapWord* region_base, HeapWord* addr); 333 HeapWord* next_top_at_mark_start(HeapWord* region_base); 334 335 inline bool allocated_after_complete_mark_start(HeapWord* addr) const; 336 void set_complete_top_at_mark_start(HeapWord* region_base, HeapWord* addr); 337 HeapWord* complete_top_at_mark_start(HeapWord* region_base); 338 339 // Evacuates object src. Returns the evacuated object if this thread 340 // succeeded, otherwise rolls back the evacuation and returns the 341 // evacuated object by the competing thread. 'succeeded' is an out 342 // param and set to true if this thread succeeded, otherwise to false. 343 inline oop evacuate_object(oop src, Thread* thread, bool& evacuated); 344 inline bool cancelled_concgc() const; 345 inline bool try_cancel_concgc(); 346 inline void clear_cancelled_concgc(); 347 348 ShenandoahHeapRegionSet* regions() { return _ordered_regions;} 349 ShenandoahFreeSet* free_regions(); 350 ShenandoahCollectionSet* collection_set() { return _collection_set; } 351 void clear_free_regions(); 352 void add_free_region(ShenandoahHeapRegion* r); 353 354 ShenandoahConnectionMatrix* connection_matrix(); 355 356 void increase_used(size_t bytes); 357 void decrease_used(size_t bytes); 358 359 void set_used(size_t bytes); 360 size_t calculateUsed(); 361 362 size_t garbage(); 363 364 void reset_next_mark_bitmap(WorkGang* gang); 365 void reset_complete_mark_bitmap(WorkGang* gang); 366 367 CMBitMap* complete_mark_bit_map(); 368 CMBitMap* next_mark_bit_map(); 369 inline bool is_marked_complete(oop obj) const; 370 inline bool mark_next(oop obj) const; 371 inline bool is_marked_next(oop obj) const; 372 bool is_next_bitmap_clear(); 373 bool is_complete_bitmap_clear_range(HeapWord* start, HeapWord* end); 374 375 void parallel_evacuate_region(ShenandoahHeapRegion* from_region); 376 377 template <class T> 378 inline oop update_oop_ref_not_null(T* p, oop obj); 379 380 template <class T> 381 inline oop maybe_update_oop_ref_not_null(T* p, oop obj); 382 383 void print_heap_regions(outputStream* st = tty) const; 384 void print_all_refs(const char* prefix); 385 void print_heap_locations(HeapWord* start, HeapWord* end); 386 387 size_t bytes_allocated_since_cm(); 388 void set_bytes_allocated_since_cm(size_t bytes); 389 390 void reclaim_humongous_region_at(ShenandoahHeapRegion* r); 391 392 VirtualSpace* storage() const; 393 394 ShenandoahMonitoringSupport* monitoring_support(); 395 ShenandoahConcurrentMark* concurrentMark() { return _scm;} 396 ShenandoahPartialGC* partial_gc(); 397 398 ReferenceProcessor* ref_processor() { return _ref_processor;} 399 400 WorkGang* workers() const { return _workers;} 401 402 uint max_workers(); 403 404 void do_evacuation(); 405 ShenandoahHeapRegion* next_compaction_region(const ShenandoahHeapRegion* r); 406 407 void heap_region_iterate(ShenandoahHeapRegionClosure* blk, bool skip_dirty_regions = false, bool skip_humongous_continuation = false) const; 408 409 void verify_heap_after_evacuation(); 410 void verify_heap_after_marking(); 411 void verify_heap_reachable_at_safepoint(); 412 413 // Delete entries for dead interned string and clean up unreferenced symbols 414 // in symbol table, possibly in parallel. 415 void unload_classes_and_cleanup_tables(); 416 417 size_t num_regions(); 418 size_t max_regions(); 419 420 // TODO: consider moving this into ShenandoahHeapRegion. 421 422 private: 423 template<class T> 424 inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit); 425 426 template<class T> 427 inline void marked_object_oop_iterate(ShenandoahHeapRegion* region, T* cl, HeapWord* limit); 428 429 public: 430 template<class T> 431 inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl); 432 433 template<class T> 434 inline void marked_object_safe_iterate(ShenandoahHeapRegion* region, T* cl); 435 436 template<class T> 437 inline void marked_object_oop_iterate(ShenandoahHeapRegion* region, T* cl); 438 439 template<class T> 440 inline void marked_object_oop_safe_iterate(ShenandoahHeapRegion* region, T* cl); 441 442 GCTimer* gc_timer() const; 443 444 void swap_mark_bitmaps(); 445 446 void cancel_concgc(GCCause::Cause cause); 447 void cancel_concgc(ShenandoahCancelCause cause); 448 449 void assert_heaplock_owned_by_current_thread() PRODUCT_RETURN; 450 void assert_heaplock_or_safepoint() PRODUCT_RETURN; 451 452 public: 453 typedef enum { 454 _lab_thread, 455 _lab_gc, 456 } LabType; 457 private: 458 HeapWord* allocate_new_lab(size_t word_size, LabType type); 459 HeapWord* allocate_memory_under_lock(size_t word_size, LabType type); 460 HeapWord* allocate_memory(size_t word_size, LabType type); 461 // Shenandoah functionality. 462 inline HeapWord* allocate_from_gclab(Thread* thread, size_t size); 463 HeapWord* allocate_from_gclab_slow(Thread* thread, size_t size); 464 HeapWord* allocate_new_gclab(size_t word_size); 465 466 void roots_iterate(OopClosure* cl); 467 468 template<class T> 469 inline void do_marked_object(CMBitMap* bitmap, T* cl, oop obj); 470 471 ShenandoahConcurrentThread* concurrent_thread() { return _concurrent_gc_thread; } 472 473 inline bool mark_next_no_checks(oop obj) const; 474 475 void parallel_evacuate(); 476 477 public: 478 inline oop atomic_compare_exchange_oop(oop n, narrowOop* addr, oop c); 479 inline oop atomic_compare_exchange_oop(oop n, oop* addr, oop c); 480 481 private: 482 #ifdef ASSERT 483 void verify_evacuated_region(ShenandoahHeapRegion* from_region); 484 #endif 485 486 inline void copy_object(oop p, HeapWord* s, size_t words); 487 void verify_copy(oop p, oop c); 488 void verify_heap_size_consistency(); 489 private: 490 void ref_processing_init(); 491 492 GCTracer* tracer(); 493 494 void grow_heap_by(size_t num_regions); 495 void ensure_new_regions(size_t num_new_regions); 496 497 void verify_evacuation(ShenandoahHeapRegion* from_region); 498 void set_concurrent_mark_in_progress(bool in_progress); 499 500 void oom_during_evacuation(); 501 502 HeapWord* allocate_memory_work(size_t word_size, LabType type); 503 HeapWord* allocate_large_memory(size_t word_size); 504 505 const char* cancel_cause_to_string(ShenandoahCancelCause cause); 506 507 private: 508 size_t* _recycled_regions; 509 size_t _recycled_region_count; 510 511 public: 512 void start_deferred_recycling(); 513 void defer_recycle(ShenandoahHeapRegion* r); 514 void finish_deferred_recycle(); 515 516 bool supports_per_thread_monitor_deflation() const { 517 return true; 518 } 519 520 void deflate_idle_monitors_all_threads(); 521 }; 522 523 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_HPP