< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Print this page

        

*** 21,43 **** * */ #include "precompiled.hpp" #include "memory/allocation.hpp" - #include "memory/universe.hpp" - #include "gc/shared/gcArguments.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/memAllocator.hpp" #include "gc/shared/parallelCleaning.hpp" #include "gc/shared/plab.hpp" #include "gc/shenandoah/shenandoahAllocTracker.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" ! #include "gc/shenandoah/shenandoahForwarding.hpp" ! #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahControlThread.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" --- 21,40 ---- * */ #include "precompiled.hpp" #include "memory/allocation.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/memAllocator.hpp" #include "gc/shared/parallelCleaning.hpp" #include "gc/shared/plab.hpp" #include "gc/shenandoah/shenandoahAllocTracker.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" ! #include "gc/shenandoah/shenandoahBrooksPointer.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahControlThread.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp"
*** 50,62 **** #include "gc/shenandoah/shenandoahMemoryPool.hpp" #include "gc/shenandoah/shenandoahMetrics.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahPacer.inline.hpp" ! #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" - #include "gc/shenandoah/shenandoahTaskqueue.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "gc/shenandoah/shenandoahVerifier.hpp" #include "gc/shenandoah/shenandoahCodeRoots.hpp" #include "gc/shenandoah/shenandoahVMOperations.hpp" #include "gc/shenandoah/shenandoahWorkGroup.hpp" --- 47,58 ---- #include "gc/shenandoah/shenandoahMemoryPool.hpp" #include "gc/shenandoah/shenandoahMetrics.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahPacer.inline.hpp" ! #include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "gc/shenandoah/shenandoahVerifier.hpp" #include "gc/shenandoah/shenandoahCodeRoots.hpp" #include "gc/shenandoah/shenandoahVMOperations.hpp" #include "gc/shenandoah/shenandoahWorkGroup.hpp"
*** 65,86 **** #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp" - #if INCLUDE_JFR - #include "gc/shenandoah/shenandoahJfrSupport.hpp" - #endif #include "memory/metaspace.hpp" - #include "oops/compressedOops.inline.hpp" - #include "runtime/globals.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/safepointMechanism.hpp" #include "runtime/vmThread.hpp" #include "services/mallocTracker.hpp" #ifdef ASSERT template <class T> void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) { T o = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(o)) { --- 61,79 ---- #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp" #include "memory/metaspace.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/safepointMechanism.hpp" #include "runtime/vmThread.hpp" #include "services/mallocTracker.hpp" + ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() : _heap(ShenandoahHeap::heap()) {} + #ifdef ASSERT template <class T> void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) { T o = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(o)) {
*** 137,158 **** } } }; jint ShenandoahHeap::initialize() { ! ShenandoahForwarding::initial_checks(); initialize_heuristics(); // // Figure out heap sizing // ! size_t init_byte_size = InitialHeapSize; ! size_t min_byte_size = MinHeapSize; ! size_t max_byte_size = MaxHeapSize; ! size_t heap_alignment = HeapAlignment; size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes(); if (ShenandoahAlwaysPreTouch) { // Enabled pre-touch means the entire heap is committed right away. --- 130,150 ---- } } }; jint ShenandoahHeap::initialize() { ! ShenandoahBrooksPointer::initial_checks(); initialize_heuristics(); // // Figure out heap sizing // ! size_t init_byte_size = collector_policy()->initial_heap_byte_size(); ! size_t max_byte_size = collector_policy()->max_heap_byte_size(); ! size_t heap_alignment = collector_policy()->heap_alignment(); size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes(); if (ShenandoahAlwaysPreTouch) { // Enabled pre-touch means the entire heap is committed right away.
*** 165,181 **** _num_regions = ShenandoahHeapRegion::region_count(); size_t num_committed_regions = init_byte_size / reg_size_bytes; num_committed_regions = MIN2(num_committed_regions, _num_regions); assert(num_committed_regions <= _num_regions, "sanity"); - _initial_size = num_committed_regions * reg_size_bytes; - - size_t num_min_regions = min_byte_size / reg_size_bytes; - num_min_regions = MIN2(num_min_regions, _num_regions); - assert(num_min_regions <= _num_regions, "sanity"); - _minimum_size = num_min_regions * reg_size_bytes; _committed = _initial_size; size_t heap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); --- 157,168 ---- _num_regions = ShenandoahHeapRegion::region_count(); size_t num_committed_regions = init_byte_size / reg_size_bytes; num_committed_regions = MIN2(num_committed_regions, _num_regions); assert(num_committed_regions <= _num_regions, "sanity"); + _initial_size = num_committed_regions * reg_size_bytes; _committed = _initial_size; size_t heap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size();
*** 189,210 **** _heap_region_special = heap_rs.special(); assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, "Misaligned heap: " PTR_FORMAT, p2i(base())); - #if SHENANDOAH_OPTIMIZED_OBJTASK - // The optimized ObjArrayChunkedTask takes some bits away from the full object bits. - // Fail if we ever attempt to address more than we can. - if ((uintptr_t)heap_rs.end() >= ObjArrayChunkedTask::max_addressable()) { - FormatBuffer<512> buf("Shenandoah reserved [" PTR_FORMAT ", " PTR_FORMAT") for the heap, \n" - "but max object address is " PTR_FORMAT ". Try to reduce heap size, or try other \n" - "VM options that allocate heap at lower addresses (HeapBaseMinAddress, AllocateHeapAt, etc).", - p2i(heap_rs.base()), p2i(heap_rs.end()), ObjArrayChunkedTask::max_addressable()); - vm_exit_during_initialization("Fatal Error", buf); - } - #endif - ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); if (!_heap_region_special) { os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false, "Cannot commit heap memory"); } --- 176,185 ----
*** 277,287 **** // Create regions and region sets // _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); _free_set = new ShenandoahFreeSet(this, _num_regions); ! _collection_set = new ShenandoahCollectionSet(this, sh_rs.base(), sh_rs.size()); { ShenandoahHeapLocker locker(lock()); size_t size_words = ShenandoahHeapRegion::region_size_words(); --- 252,262 ---- // Create regions and region sets // _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); _free_set = new ShenandoahFreeSet(this, _num_regions); ! _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)sh_rs.base()); { ShenandoahHeapLocker locker(lock()); size_t size_words = ShenandoahHeapRegion::region_size_words();
*** 374,388 **** new ShenandoahTraversalGC(this, _num_regions) : NULL; _control_thread = new ShenandoahControlThread(); ! log_info(gc, init)("Initialize Shenandoah heap: " SIZE_FORMAT "%s initial, " SIZE_FORMAT "%s min, " SIZE_FORMAT "%s max", ! byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size), ! byte_size_in_proper_unit(_minimum_size), proper_unit_for_byte_size(_minimum_size), ! byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity()) ! ); log_info(gc, init)("Safepointing mechanism: %s", SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" : (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown")); --- 349,360 ---- new ShenandoahTraversalGC(this, _num_regions) : NULL; _control_thread = new ShenandoahControlThread(); ! log_info(gc, init)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s", ! byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size)); log_info(gc, init)("Safepointing mechanism: %s", SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" : (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown"));
*** 476,498 **** BarrierSet::set_barrier_set(new ShenandoahBarrierSet(this)); _max_workers = MAX2(_max_workers, 1U); _workers = new ShenandoahWorkGang("Shenandoah GC Threads", _max_workers, ! /* are_GC_task_threads */ true, ! /* are_ConcurrentGC_threads */ true); if (_workers == NULL) { vm_exit_during_initialization("Failed necessary allocation."); } else { _workers->initialize_workers(); } if (ShenandoahParallelSafepointThreads > 1) { _safepoint_workers = new ShenandoahWorkGang("Safepoint Cleanup Thread", ShenandoahParallelSafepointThreads, ! /* are_GC_task_threads */ false, ! /* are_ConcurrentGC_threads */ false); _safepoint_workers->initialize_workers(); } } #ifdef _MSC_VER --- 448,469 ---- BarrierSet::set_barrier_set(new ShenandoahBarrierSet(this)); _max_workers = MAX2(_max_workers, 1U); _workers = new ShenandoahWorkGang("Shenandoah GC Threads", _max_workers, ! /* are_GC_task_threads */true, ! /* are_ConcurrentGC_threads */false); if (_workers == NULL) { vm_exit_during_initialization("Failed necessary allocation."); } else { _workers->initialize_workers(); } if (ShenandoahParallelSafepointThreads > 1) { _safepoint_workers = new ShenandoahWorkGang("Safepoint Cleanup Thread", ShenandoahParallelSafepointThreads, ! false, false); _safepoint_workers->initialize_workers(); } } #ifdef _MSC_VER
*** 529,539 **** } void ShenandoahHeap::print_on(outputStream* st) const { st->print_cr("Shenandoah Heap"); st->print_cr(" " SIZE_FORMAT "K total, " SIZE_FORMAT "K committed, " SIZE_FORMAT "K used", ! max_capacity() / K, committed() / K, used() / K); st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"K regions", num_regions(), ShenandoahHeapRegion::region_size_bytes() / K); st->print("Status: "); if (has_forwarded_objects()) st->print("has forwarded objects, "); --- 500,510 ---- } void ShenandoahHeap::print_on(outputStream* st) const { st->print_cr("Shenandoah Heap"); st->print_cr(" " SIZE_FORMAT "K total, " SIZE_FORMAT "K committed, " SIZE_FORMAT "K used", ! capacity() / K, committed() / K, used() / K); st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"K regions", num_regions(), ShenandoahHeapRegion::region_size_bytes() / K); st->print("Status: "); if (has_forwarded_objects()) st->print("has forwarded objects, ");
*** 555,573 **** st->print_cr("Reserved region:"); st->print_cr(" - [" PTR_FORMAT ", " PTR_FORMAT ") ", p2i(reserved_region().start()), p2i(reserved_region().end())); - ShenandoahCollectionSet* cset = collection_set(); - st->print_cr("Collection set:"); - if (cset != NULL) { - st->print_cr(" - map (vanilla): " PTR_FORMAT, p2i(cset->map_address())); - st->print_cr(" - map (biased): " PTR_FORMAT, p2i(cset->biased_map_address())); - } else { - st->print_cr(" (NULL)"); - } - st->cr(); MetaspaceUtils::print_on(st); if (Verbose) { print_heap_regions_on(st); --- 526,535 ----
*** 598,609 **** _full_gc->initialize(_gc_timer); ref_processing_init(); _heuristics->initialize(); - - JFR_ONLY(ShenandoahJFRSupport::register_jfr_type_serializers()); } size_t ShenandoahHeap::used() const { return OrderAccess::load_acquire(&_used); } --- 560,569 ----
*** 653,673 **** } } } size_t ShenandoahHeap::capacity() const { ! return committed(); } size_t ShenandoahHeap::max_capacity() const { return _num_regions * ShenandoahHeapRegion::region_size_bytes(); } - size_t ShenandoahHeap::min_capacity() const { - return _minimum_size; - } - size_t ShenandoahHeap::initial_capacity() const { return _initial_size; } bool ShenandoahHeap::is_in(const void* p) const { --- 613,629 ---- } } } size_t ShenandoahHeap::capacity() const { ! return num_regions() * ShenandoahHeapRegion::region_size_bytes(); } size_t ShenandoahHeap::max_capacity() const { return _num_regions * ShenandoahHeapRegion::region_size_bytes(); } size_t ShenandoahHeap::initial_capacity() const { return _initial_size; } bool ShenandoahHeap::is_in(const void* p) const {
*** 677,710 **** } void ShenandoahHeap::op_uncommit(double shrink_before) { assert (ShenandoahUncommit, "should be enabled"); - // Application allocates from the beginning of the heap, and GC allocates at - // the end of it. It is more efficient to uncommit from the end, so that applications - // could enjoy the near committed regions. GC allocations are much less frequent, - // and therefore can accept the committing costs. - size_t count = 0; ! for (size_t i = num_regions(); i > 0; i--) { // care about size_t underflow ! ShenandoahHeapRegion* r = get_region(i - 1); if (r->is_empty_committed() && (r->empty_time() < shrink_before)) { ShenandoahHeapLocker locker(lock()); if (r->is_empty_committed()) { - // Do not uncommit below minimal capacity - if (committed() < min_capacity() + ShenandoahHeapRegion::region_size_bytes()) { - break; - } - r->make_uncommitted(); count++; } } SpinPause(); // allow allocators to take the lock } if (count > 0) { control_thread()->notify_heap_changed(); } } HeapWord* ShenandoahHeap::allocate_from_gclab_slow(Thread* thread, size_t size) { --- 633,658 ---- } void ShenandoahHeap::op_uncommit(double shrink_before) { assert (ShenandoahUncommit, "should be enabled"); size_t count = 0; ! for (size_t i = 0; i < num_regions(); i++) { ! ShenandoahHeapRegion* r = get_region(i); if (r->is_empty_committed() && (r->empty_time() < shrink_before)) { ShenandoahHeapLocker locker(lock()); if (r->is_empty_committed()) { r->make_uncommitted(); count++; } } SpinPause(); // allow allocators to take the lock } if (count > 0) { + log_info(gc)("Uncommitted " SIZE_FORMAT "M. Heap: " SIZE_FORMAT "M reserved, " SIZE_FORMAT "M committed, " SIZE_FORMAT "M used", + count * ShenandoahHeapRegion::region_size_bytes() / M, capacity() / M, committed() / M, used() / M); control_thread()->notify_heap_changed(); } } HeapWord* ShenandoahHeap::allocate_from_gclab_slow(Thread* thread, size_t size) {
*** 879,898 **** class ShenandoahMemAllocator : public MemAllocator { private: MemAllocator& _initializer; public: ShenandoahMemAllocator(MemAllocator& initializer, Klass* klass, size_t word_size, Thread* thread) : ! MemAllocator(klass, word_size + ShenandoahForwarding::word_size(), thread), _initializer(initializer) {} protected: virtual HeapWord* mem_allocate(Allocation& allocation) const { HeapWord* result = MemAllocator::mem_allocate(allocation); // Initialize brooks-pointer if (result != NULL) { ! result += ShenandoahForwarding::word_size(); ! ShenandoahForwarding::initialize(oop(result)); assert(! ShenandoahHeap::heap()->in_collection_set(result), "never allocate in targetted region"); } return result; } --- 827,846 ---- class ShenandoahMemAllocator : public MemAllocator { private: MemAllocator& _initializer; public: ShenandoahMemAllocator(MemAllocator& initializer, Klass* klass, size_t word_size, Thread* thread) : ! MemAllocator(klass, word_size + ShenandoahBrooksPointer::word_size(), thread), _initializer(initializer) {} protected: virtual HeapWord* mem_allocate(Allocation& allocation) const { HeapWord* result = MemAllocator::mem_allocate(allocation); // Initialize brooks-pointer if (result != NULL) { ! result += ShenandoahBrooksPointer::word_size(); ! ShenandoahBrooksPointer::initialize(oop(result)); assert(! ShenandoahHeap::heap()->in_collection_set(result), "never allocate in targetted region"); } return result; }
*** 965,977 **** HeapWord* obj = tlab_post_allocation_setup(start); CollectedHeap::fill_with_object(obj, end); } size_t ShenandoahHeap::min_dummy_object_size() const { ! return CollectedHeap::min_dummy_object_size() + ShenandoahForwarding::word_size(); } class ShenandoahConcurrentEvacuateRegionObjectClosure : public ObjectClosure { private: ShenandoahHeap* const _heap; Thread* const _thread; public: --- 913,962 ---- HeapWord* obj = tlab_post_allocation_setup(start); CollectedHeap::fill_with_object(obj, end); } size_t ShenandoahHeap::min_dummy_object_size() const { ! return CollectedHeap::min_dummy_object_size() + ShenandoahBrooksPointer::word_size(); } + class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure { + private: + ShenandoahHeap* _heap; + Thread* _thread; + public: + ShenandoahEvacuateUpdateRootsClosure() : + _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { + } + + private: + template <class T> + void do_oop_work(T* p) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + + T o = RawAccess<>::oop_load(p); + if (! CompressedOops::is_null(o)) { + oop obj = CompressedOops::decode_not_null(o); + if (_heap->in_collection_set(obj)) { + shenandoah_assert_marked(p, obj); + oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (oopDesc::equals_raw(resolved, obj)) { + resolved = _heap->evacuate_object(obj, _thread); + } + RawAccess<IS_NOT_NULL>::oop_store(p, resolved); + } + } + } + + public: + void do_oop(oop* p) { + do_oop_work(p); + } + void do_oop(narrowOop* p) { + do_oop_work(p); + } + }; + class ShenandoahConcurrentEvacuateRegionObjectClosure : public ObjectClosure { private: ShenandoahHeap* const _heap; Thread* const _thread; public:
*** 1058,1069 **** } void ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) { assert(start->is_humongous_start(), "reclaim regions starting with the first one"); ! oop humongous_obj = oop(start->bottom() + ShenandoahForwarding::word_size()); ! size_t size = humongous_obj->size() + ShenandoahForwarding::word_size(); size_t required_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize); size_t index = start->region_number() + required_regions - 1; assert(!start->has_live(), "liveness must be zero"); --- 1043,1054 ---- } void ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) { assert(start->is_humongous_start(), "reclaim regions starting with the first one"); ! oop humongous_obj = oop(start->bottom() + ShenandoahBrooksPointer::word_size()); ! size_t size = humongous_obj->size() + ShenandoahBrooksPointer::word_size(); size_t required_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize); size_t index = start->region_number() + required_regions - 1; assert(!start->has_live(), "liveness must be zero");
*** 1115,1136 **** void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); ShenandoahEvacOOMScope oom_evac_scope; ShenandoahEvacuateUpdateRootsClosure cl; MarkingCodeBlobClosure blobsCl(&cl, CodeBlobToOopClosure::FixRelocations); ! _rp->roots_do(worker_id, &cl); } }; void ShenandoahHeap::evacuate_and_update_roots() { #if defined(COMPILER2) || INCLUDE_JVMCI DerivedPointerTable::clear(); #endif assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); { ! ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } #if defined(COMPILER2) || INCLUDE_JVMCI --- 1100,1121 ---- void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); ShenandoahEvacOOMScope oom_evac_scope; ShenandoahEvacuateUpdateRootsClosure cl; MarkingCodeBlobClosure blobsCl(&cl, CodeBlobToOopClosure::FixRelocations); ! _rp->process_evacuate_roots(&cl, &blobsCl, worker_id); } }; void ShenandoahHeap::evacuate_and_update_roots() { #if defined(COMPILER2) || INCLUDE_JVMCI DerivedPointerTable::clear(); #endif assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); { ! ShenandoahRootEvacuator rp(this, workers()->active_workers(), ShenandoahPhaseTimings::init_evac); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } #if defined(COMPILER2) || INCLUDE_JVMCI
*** 1179,1188 **** --- 1164,1177 ---- void ShenandoahHeap::do_full_collection(bool clear_all_soft_refs) { //assert(false, "Shouldn't need to do full collections"); } + CollectorPolicy* ShenandoahHeap::collector_policy() const { + return _shenandoah_policy; + } + HeapWord* ShenandoahHeap::block_start(const void* addr) const { Space* sp = heap_region_containing(addr); if (sp != NULL) { return sp->block_start(addr); }
*** 1213,1225 **** } } void ShenandoahHeap::gc_threads_do(ThreadClosure* tcl) const { workers()->threads_do(tcl); ! if (_safepoint_workers != NULL) { ! _safepoint_workers->threads_do(tcl); ! } if (ShenandoahStringDedup::is_enabled()) { ShenandoahStringDedup::threads_do(tcl); } } --- 1202,1212 ---- } } void ShenandoahHeap::gc_threads_do(ThreadClosure* tcl) const { workers()->threads_do(tcl); ! _safepoint_workers->threads_do(tcl); if (ShenandoahStringDedup::is_enabled()) { ShenandoahStringDedup::threads_do(tcl); } }
*** 1330,1342 **** _aux_bit_map.clear(); Stack<oop,mtGC> oop_stack; // First, we process all GC roots. This populates the work stack with initial objects. ! ShenandoahAllRootScanner rp(1, ShenandoahPhaseTimings::_num_phases); ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); ! rp.roots_do(0, &oops); // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { oop obj = oop_stack.pop(); assert(oopDesc::is_oop(obj), "must be a valid oop"); --- 1317,1331 ---- _aux_bit_map.clear(); Stack<oop,mtGC> oop_stack; // First, we process all GC roots. This populates the work stack with initial objects. ! ShenandoahRootProcessor rp(this, 1, ShenandoahPhaseTimings::_num_phases); ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); ! CLDToOopClosure clds(&oops, ClassLoaderData::_claim_none); ! CodeBlobToOopClosure blobs(&oops, false); ! rp.process_all_roots(&oops, &clds, &blobs, NULL, 0); // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { oop obj = oop_stack.pop(); assert(oopDesc::is_oop(obj), "must be a valid oop");
*** 1504,1523 **** if (!cancelled_gc()) { concurrent_mark()->finish_mark_from_roots(/* full_gc = */ false); if (has_forwarded_objects()) { ! // Degen may be caused by failed evacuation of roots ! if (is_degenerated_gc_in_progress()) { ! concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots); ! } else { ! concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::update_roots); ! } ! } ! ! if (ShenandoahVerify) { ! verifier()->verify_roots_no_forwarded(); } stop_concurrent_marking(); { --- 1493,1503 ---- if (!cancelled_gc()) { concurrent_mark()->finish_mark_from_roots(/* full_gc = */ false); if (has_forwarded_objects()) { ! concurrent_mark()->update_roots(ShenandoahPhaseTimings::update_roots); } stop_concurrent_marking(); {
*** 1563,1577 **** evacuate_and_update_roots(); if (ShenandoahPacing) { pacer()->setup_for_evac(); } - - if (ShenandoahVerify) { - verifier()->verify_roots_no_forwarded(); - verifier()->verify_during_evacuation(); - } } else { if (ShenandoahVerify) { verifier()->verify_after_concmark(); } --- 1543,1552 ----
*** 1874,1888 **** set_gc_state_mask(EVACUATION, in_progress); } HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) { // Initialize Brooks pointer for the next object ! HeapWord* result = obj + ShenandoahForwarding::word_size(); ! ShenandoahForwarding::initialize(oop(result)); return result; } void ShenandoahHeap::ref_processing_init() { assert(_max_workers > 0, "Sanity"); _ref_processor = new ReferenceProcessor(&_subject_to_discovery, // is_subject_to_discovery --- 1849,1888 ---- set_gc_state_mask(EVACUATION, in_progress); } HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) { // Initialize Brooks pointer for the next object ! HeapWord* result = obj + ShenandoahBrooksPointer::word_size(); ! ShenandoahBrooksPointer::initialize(oop(result)); return result; } + ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() : + _mark_context(ShenandoahHeap::heap()->marking_context()) { + } + + ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() : + _mark_context(ShenandoahHeap::heap()->marking_context()) { + } + + bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) { + if (CompressedOops::is_null(obj)) { + return false; + } + obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + shenandoah_assert_not_forwarded_if(NULL, obj, ShenandoahHeap::heap()->is_concurrent_mark_in_progress() || ShenandoahHeap::heap()->is_concurrent_traversal_in_progress()); + return _mark_context->is_marked(obj); + } + + bool ShenandoahIsAliveClosure::do_object_b(oop obj) { + if (CompressedOops::is_null(obj)) { + return false; + } + shenandoah_assert_not_forwarded(NULL, obj); + return _mark_context->is_marked(obj); + } + void ShenandoahHeap::ref_processing_init() { assert(_max_workers > 0, "Sanity"); _ref_processor = new ReferenceProcessor(&_subject_to_discovery, // is_subject_to_discovery
*** 2164,2176 **** set_evacuation_in_progress(false); retire_and_reset_gclabs(); if (ShenandoahVerify) { - if (!is_degenerated_gc_in_progress()) { - verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots); - } verifier()->verify_before_updaterefs(); } set_update_refs_in_progress(true); make_parsable(true); --- 2164,2173 ----
*** 2204,2231 **** if (cancelled_gc()) { clear_cancelled_gc(); } assert(!cancelled_gc(), "Should have been done right before"); ! if (ShenandoahVerify && !is_degenerated_gc_in_progress()) { ! verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots); ! } ! ! if (is_degenerated_gc_in_progress()) { ! concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots); ! } else { ! concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::final_update_refs_roots); ! } ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle); trash_cset_regions(); set_has_forwarded_objects(false); set_update_refs_in_progress(false); if (ShenandoahVerify) { - verifier()->verify_roots_no_forwarded(); verifier()->verify_after_updaterefs(); } if (VerifyAfterGC) { Universe::verify(); --- 2201,2221 ---- if (cancelled_gc()) { clear_cancelled_gc(); } assert(!cancelled_gc(), "Should have been done right before"); ! concurrent_mark()->update_roots(is_degenerated_gc_in_progress() ? ! ShenandoahPhaseTimings::degen_gc_update_roots: ! ShenandoahPhaseTimings::final_update_refs_roots); ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle); trash_cset_regions(); set_has_forwarded_objects(false); set_update_refs_in_progress(false); if (ShenandoahVerify) { verifier()->verify_after_updaterefs(); } if (VerifyAfterGC) { Universe::verify();
*** 2853,2863 **** } } } size_t ShenandoahHeap::obj_size(oop obj) const { ! return CollectedHeap::obj_size(obj) + ShenandoahForwarding::word_size(); } ptrdiff_t ShenandoahHeap::cell_header_size() const { ! return ShenandoahForwarding::byte_size(); } --- 2843,2858 ---- } } } size_t ShenandoahHeap::obj_size(oop obj) const { ! return CollectedHeap::obj_size(obj) + ShenandoahBrooksPointer::word_size(); } ptrdiff_t ShenandoahHeap::cell_header_size() const { ! return ShenandoahBrooksPointer::byte_size(); ! } ! ! BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() { ! return ShenandoahHeap::heap()->has_forwarded_objects() ? reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) ! : reinterpret_cast<BoolObjectClosure*>(&_alive_cl); }
< prev index next >