1 /* 2 * Copyright (c) 2019, Red Hat, Inc. All rights reserved. 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 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP 24 #define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP 25 26 #include "gc/shenandoah/shenandoahAsserts.hpp" 27 #include "gc/shenandoah/shenandoahClosures.hpp" 28 #include "gc/shenandoah/shenandoahHeap.inline.hpp" 29 #include "gc/shenandoah/shenandoahTraversalGC.hpp" 30 #include "oops/compressedOops.inline.hpp" 31 #include "runtime/thread.hpp" 32 33 ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() : 34 _mark_context(ShenandoahHeap::heap()->marking_context()) { 35 } 36 37 bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) { 38 if (CompressedOops::is_null(obj)) { 39 return false; 40 } 41 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); 42 shenandoah_assert_not_forwarded_if(NULL, obj, 43 (ShenandoahHeap::heap()->is_concurrent_mark_in_progress() || 44 ShenandoahHeap::heap()->is_concurrent_traversal_in_progress())); 45 return _mark_context->is_marked(obj); 46 } 47 48 ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() : 49 _mark_context(ShenandoahHeap::heap()->marking_context()) { 50 } 51 52 bool ShenandoahIsAliveClosure::do_object_b(oop obj) { 53 if (CompressedOops::is_null(obj)) { 54 return false; 55 } 56 shenandoah_assert_not_forwarded(NULL, obj); 57 return _mark_context->is_marked(obj); 58 } 59 60 BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() { 61 return ShenandoahHeap::heap()->has_forwarded_objects() ? 62 reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) : 63 reinterpret_cast<BoolObjectClosure*>(&_alive_cl); 64 } 65 66 ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() : 67 _heap(ShenandoahHeap::heap()) { 68 } 69 70 template <class T> 71 void ShenandoahUpdateRefsClosure::do_oop_work(T* p) { 72 T o = RawAccess<>::oop_load(p); 73 if (!CompressedOops::is_null(o)) { 74 oop obj = CompressedOops::decode_not_null(o); 75 _heap->update_with_forwarded_not_null(p, obj); 76 } 77 } 78 79 void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); } 80 void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); } 81 82 ShenandoahTraversalUpdateRefsClosure::ShenandoahTraversalUpdateRefsClosure() : 83 _heap(ShenandoahHeap::heap()), 84 _traversal_set(ShenandoahHeap::heap()->traversal_gc()->traversal_set()) { 85 assert(_heap->is_traversal_mode(), "Why we here?"); 86 } 87 88 template <class T> 89 void ShenandoahTraversalUpdateRefsClosure::do_oop_work(T* p) { 90 T o = RawAccess<>::oop_load(p); 91 if (!CompressedOops::is_null(o)) { 92 oop obj = CompressedOops::decode_not_null(o); 93 if (_heap->in_collection_set(obj) || _traversal_set->is_in((HeapWord*)obj)) { 94 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); 95 RawAccess<IS_NOT_NULL>::oop_store(p, obj); 96 } else { 97 shenandoah_assert_not_forwarded(p, obj); 98 } 99 } 100 } 101 102 void ShenandoahTraversalUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); } 103 void ShenandoahTraversalUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); } 104 105 ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() : 106 _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { 107 } 108 109 template <class T> 110 void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) { 111 assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); 112 113 T o = RawAccess<>::oop_load(p); 114 if (! CompressedOops::is_null(o)) { 115 oop obj = CompressedOops::decode_not_null(o); 116 if (_heap->in_collection_set(obj)) { 117 shenandoah_assert_marked(p, obj); 118 oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); 119 if (resolved == obj) { 120 resolved = _heap->evacuate_object(obj, _thread); 121 } 122 RawAccess<IS_NOT_NULL>::oop_store(p, resolved); 123 } 124 } 125 } 126 void ShenandoahEvacuateUpdateRootsClosure::do_oop(oop* p) { 127 do_oop_work(p); 128 } 129 130 void ShenandoahEvacuateUpdateRootsClosure::do_oop(narrowOop* p) { 131 do_oop_work(p); 132 } 133 134 ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsClosure() : 135 _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { 136 } 137 138 void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { 139 assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); 140 141 oop obj = RawAccess<>::oop_load(p); 142 if (! CompressedOops::is_null(obj)) { 143 if (_heap->in_collection_set(obj)) { 144 shenandoah_assert_marked(p, obj); 145 oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); 146 if (resolved == obj) { 147 resolved = _heap->evacuate_object(obj, _thread); 148 } 149 150 Atomic::cmpxchg(p, obj, resolved); 151 } 152 } 153 } 154 155 void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(narrowOop* p) { 156 ShouldNotReachHere(); 157 } 158 159 #ifdef ASSERT 160 template <class T> 161 void ShenandoahAssertNotForwardedClosure::do_oop_work(T* p) { 162 T o = RawAccess<>::oop_load(p); 163 if (!CompressedOops::is_null(o)) { 164 oop obj = CompressedOops::decode_not_null(o); 165 shenandoah_assert_not_forwarded(p, obj); 166 } 167 } 168 169 void ShenandoahAssertNotForwardedClosure::do_oop(narrowOop* p) { do_oop_work(p); } 170 void ShenandoahAssertNotForwardedClosure::do_oop(oop* p) { do_oop_work(p); } 171 #endif 172 173 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP