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_implementation/shenandoah/shenandoahAsserts.hpp"
  27 #include "gc_implementation/shenandoah/shenandoahClosures.hpp"
  28 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
  29 #include "runtime/thread.hpp"
  30 
  31 ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :
  32   _mark_context(ShenandoahHeap::heap()->marking_context()) {
  33 }
  34 
  35 bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) {
  36   if (oopDesc::is_null(obj)) {
  37     return false;
  38   }
  39   obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
  40   shenandoah_assert_not_forwarded_if(NULL, obj, ShenandoahHeap::heap()->is_concurrent_mark_in_progress());
  41   return _mark_context->is_marked(obj);
  42 }
  43 
  44 ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() :
  45   _mark_context(ShenandoahHeap::heap()->marking_context()) {
  46 }
  47 
  48 bool ShenandoahIsAliveClosure::do_object_b(oop obj) {
  49   if (oopDesc::is_null(obj)) {
  50     return false;
  51   }
  52   shenandoah_assert_not_forwarded(NULL, obj);
  53   return _mark_context->is_marked(obj);
  54 }
  55 
  56 BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() {
  57   return ShenandoahHeap::heap()->has_forwarded_objects() ?
  58          reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) :
  59          reinterpret_cast<BoolObjectClosure*>(&_alive_cl);
  60 }
  61 
  62 ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() :
  63   _heap(ShenandoahHeap::heap()) {
  64 }
  65 
  66 template <class T>
  67 void ShenandoahUpdateRefsClosure::do_oop_work(T* p) {
  68   T o = oopDesc::load_heap_oop(p);
  69   if (!oopDesc::is_null(o)) {
  70     oop obj = oopDesc::decode_heap_oop_not_null(o);
  71     _heap->update_with_forwarded_not_null(p, obj);
  72   }
  73 }
  74 
  75 void ShenandoahUpdateRefsClosure::do_oop(oop* p)       { do_oop_work(p); }
  76 void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
  77 
  78 ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() :
  79   _heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
  80 }
  81 
  82 template <class T>
  83 void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) {
  84   assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
  85 
  86   T o = oopDesc::load_heap_oop(p);
  87   if (! oopDesc::is_null(o)) {
  88     oop obj = oopDesc::decode_heap_oop_not_null(o);
  89     if (_heap->in_collection_set(obj)) {
  90       shenandoah_assert_marked(p, obj);
  91       oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
  92       if (resolved == obj) {
  93         resolved = _heap->evacuate_object(obj, _thread);
  94       }
  95       oopDesc::encode_store_heap_oop(p, resolved);
  96     }
  97   }
  98 }
  99 
 100 void ShenandoahEvacuateUpdateRootsClosure::do_oop(oop* p) {
 101   do_oop_work(p);
 102 }
 103 
 104 void ShenandoahEvacuateUpdateRootsClosure::do_oop(narrowOop* p) {
 105   do_oop_work(p);
 106 }
 107 
 108 #ifdef ASSERT
 109 template <class T>
 110 void ShenandoahAssertNotForwardedClosure::do_oop_work(T* p) {
 111   T o = oopDesc::load_heap_oop(p);
 112   if (!oopDesc::is_null(o)) {
 113     oop obj = oopDesc::decode_heap_oop_not_null(o);
 114     shenandoah_assert_not_forwarded(p, obj);
 115   }
 116 }
 117 
 118 void ShenandoahAssertNotForwardedClosure::do_oop(narrowOop* p) { do_oop_work(p); }
 119 void ShenandoahAssertNotForwardedClosure::do_oop(oop* p)       { do_oop_work(p); }
 120 #endif
 121 
 122 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP