1 /*
   2  * Copyright (c) 2020, Red Hat, Inc. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHEVACLOCKINGBITMAP_HPP
  26 #define SHARE_GC_SHENANDOAH_SHENANDOAHEVACLOCKINGBITMAP_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "memory/memRegion.hpp"
  30 #include "oops/oopsHierarchy.hpp"
  31 #include "runtime/globals.hpp"
  32 #include "utilities/bitMap.hpp"
  33 
  34 /*
  35  * Protects the evacuation slow-path from concurrent access/races:
  36  * - Only one thread must be allowed to (successfully) evacuate an object
  37  * - In case of evacuation failure by one thread, no other thread must be allowed to evacuate
  38  *   an object
  39  *
  40  * This is achieved by a locking bitmap. Each bit corresponds to a card of
  41  * 2^ShenandoahEvacGranularity heap words. Before evacuating, a thread must acquire
  42  * the corresponding bit, and release it after evacuation is done. It is preferable
  43  * to use the scoped ShenandoahEvacLocker for that.
  44  */
  45 class ShenandoahEvacLockingBitmap : public CHeapObj<mtGC> {
  46 private:
  47   MemRegion _covered;    // The heap area covered by this bitmap.
  48   const int _shifter;    // Shift amount from heap index to bit index in the bitmap.
  49   CHeapBitMap _bm;        // The actual bitmap.
  50 
  51   // Convert from address to bit offset.
  52   inline size_t addr_to_offset(const HeapWord* addr) const;
  53 
  54 public:
  55   ShenandoahEvacLockingBitmap(MemRegion heap) :
  56   _covered(heap),
  57   _shifter((1 + ShenandoahEvacLockGranularity) * LogHeapWordSize),
  58   _bm(_covered.word_size() >> _shifter, mtGC) {
  59 }
  60 
  61   inline void acquire(oop obj);
  62   inline void release(oop obj);
  63 };
  64 
  65 class ShenandoahEvacLocker : public StackObj {
  66 private:
  67   ShenandoahEvacLockingBitmap* _bitmap;
  68   oop const _obj;
  69 public:
  70   inline ShenandoahEvacLocker(ShenandoahEvacLockingBitmap* bitmap, oop obj);
  71   inline ~ShenandoahEvacLocker();
  72 };
  73 
  74 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHEVACLOCKINGBITMAP_HPP