< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2017, 2018, 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 
  24 #include "precompiled.hpp"
  25 #include "code/codeCache.hpp"
  26 #include "code/nmethod.hpp"
  27 #include "gc/shenandoah/shenandoahHeap.hpp"
  28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  29 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  30 #include "memory/resourceArea.hpp"
  31 
  32 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) {
  33   _length = heaps->length();
  34   _iters = NEW_C_HEAP_ARRAY(ShenandoahParallelCodeHeapIterator, _length, mtGC);
  35   for (int h = 0; h < _length; h++) {
  36     _iters[h] = ShenandoahParallelCodeHeapIterator(heaps->at(h));
  37   }
  38 }
  39 
  40 ShenandoahParallelCodeCacheIterator::~ShenandoahParallelCodeCacheIterator() {
  41   FREE_C_HEAP_ARRAY(ParallelCodeHeapIterator, _iters);
  42 }
  43 
  44 void ShenandoahParallelCodeCacheIterator::parallel_blobs_do(CodeBlobClosure* f) {
  45   for (int c = 0; c < _length; c++) {
  46     _iters[c].parallel_blobs_do(f);
  47   }


 103 
 104 public:
 105   ShenandoahNMethodOopDetector() : _oops(10) {};
 106 
 107   void do_oop(oop* o) {
 108     _oops.append(o);
 109   }
 110   void do_oop(narrowOop* o) {
 111     fatal("NMethods should not have compressed oops embedded.");
 112   }
 113 
 114   GrowableArray<oop*>* oops() {
 115     return &_oops;
 116   }
 117 
 118   bool has_oops() {
 119     return !_oops.is_empty();
 120   }
 121 };
 122 
 123 class ShenandoahNMethodOopInitializer : public OopClosure {
 124 private:
 125   ShenandoahHeap* const _heap;
 126 
 127 public:
 128   ShenandoahNMethodOopInitializer() : _heap(ShenandoahHeap::heap()) {};
 129 
 130 private:
 131   template <class T>
 132   inline void do_oop_work(T* p) {
 133     T o = RawAccess<>::oop_load(p);
 134     if (! CompressedOops::is_null(o)) {
 135       oop obj1 = CompressedOops::decode_not_null(o);
 136       oop obj2 = ShenandoahBarrierSet::barrier_set()->write_barrier(obj1);
 137       if (! oopDesc::equals_raw(obj1, obj2)) {
 138         shenandoah_assert_not_in_cset(NULL, obj2);
 139         RawAccess<IS_NOT_NULL>::oop_store(p, obj2);
 140         if (_heap->is_concurrent_traversal_in_progress()) {
 141           ShenandoahBarrierSet::barrier_set()->enqueue(obj2);
 142         }
 143       }
 144     }
 145   }
 146 
 147 public:
 148   void do_oop(oop* o) {
 149     do_oop_work(o);
 150   }
 151   void do_oop(narrowOop* o) {
 152     do_oop_work(o);
 153   }
 154 };
 155 
 156 ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock;
 157 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
 158 
 159 void ShenandoahCodeRoots::initialize() {
 160   _recorded_nms_lock._lock = 0;
 161   _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
 162 }
 163 
 164 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
 165   switch (ShenandoahCodeRootsStyle) {
 166     case 0:
 167     case 1: {
 168       ShenandoahNMethodOopInitializer init;
 169       nm->oops_do(&init);
 170       nm->fix_oop_relocations();
 171       break;
 172     }
 173     case 2: {
 174       ShenandoahNMethodOopDetector detector;
 175       nm->oops_do(&detector);
 176 
 177       if (detector.has_oops()) {
 178         ShenandoahNMethodOopInitializer init;
 179         nm->oops_do(&init);
 180         nm->fix_oop_relocations();
 181 
 182         ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
 183         nmr->assert_alive_and_correct();
 184 
 185         ShenandoahCodeRootsLock lock(true);
 186 
 187         int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
 188         if (idx != -1) {
 189           ShenandoahNMethod* old = _recorded_nms->at(idx);
 190           _recorded_nms->at_put(idx, nmr);
 191           delete old;
 192         } else {
 193           _recorded_nms->append(nmr);
 194         }
 195       }
 196       break;
 197     }
 198     default:
 199       ShouldNotReachHere();
 200   }
 201 };


   1 /*
   2  * Copyright (c) 2017, 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 
  24 #include "precompiled.hpp"
  25 #include "code/codeCache.hpp"
  26 #include "code/nmethod.hpp"

  27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  28 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  29 #include "memory/resourceArea.hpp"
  30 
  31 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) {
  32   _length = heaps->length();
  33   _iters = NEW_C_HEAP_ARRAY(ShenandoahParallelCodeHeapIterator, _length, mtGC);
  34   for (int h = 0; h < _length; h++) {
  35     _iters[h] = ShenandoahParallelCodeHeapIterator(heaps->at(h));
  36   }
  37 }
  38 
  39 ShenandoahParallelCodeCacheIterator::~ShenandoahParallelCodeCacheIterator() {
  40   FREE_C_HEAP_ARRAY(ParallelCodeHeapIterator, _iters);
  41 }
  42 
  43 void ShenandoahParallelCodeCacheIterator::parallel_blobs_do(CodeBlobClosure* f) {
  44   for (int c = 0; c < _length; c++) {
  45     _iters[c].parallel_blobs_do(f);
  46   }


 102 
 103 public:
 104   ShenandoahNMethodOopDetector() : _oops(10) {};
 105 
 106   void do_oop(oop* o) {
 107     _oops.append(o);
 108   }
 109   void do_oop(narrowOop* o) {
 110     fatal("NMethods should not have compressed oops embedded.");
 111   }
 112 
 113   GrowableArray<oop*>* oops() {
 114     return &_oops;
 115   }
 116 
 117   bool has_oops() {
 118     return !_oops.is_empty();
 119   }
 120 };
 121 

































 122 ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock;
 123 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
 124 
 125 void ShenandoahCodeRoots::initialize() {
 126   _recorded_nms_lock._lock = 0;
 127   _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
 128 }
 129 
 130 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
 131   switch (ShenandoahCodeRootsStyle) {
 132     case 0:
 133     case 1:



 134       break;

 135     case 2: {
 136       ShenandoahNMethodOopDetector detector;
 137       nm->oops_do(&detector);
 138 
 139       if (detector.has_oops()) {




 140         ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
 141         nmr->assert_alive_and_correct();
 142 
 143         ShenandoahCodeRootsLock lock(true);
 144 
 145         int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
 146         if (idx != -1) {
 147           ShenandoahNMethod* old = _recorded_nms->at(idx);
 148           _recorded_nms->at_put(idx, nmr);
 149           delete old;
 150         } else {
 151           _recorded_nms->append(nmr);
 152         }
 153       }
 154       break;
 155     }
 156     default:
 157       ShouldNotReachHere();
 158   }
 159 };


< prev index next >