1 /*
  2  * Copyright (c) 2016, 2019, 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_SHENANDOAHFREESET_HPP
 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHFREESET_HPP
 27 
 28 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
 29 #include "gc/shenandoah/shenandoahHeap.hpp"
 30 
 31 class ShenandoahFreeSet : public CHeapObj<mtGC> {
 32 private:
 33   ShenandoahHeap* const _heap;
 34   CHeapBitMap _mutator_free_bitmap;
 35   CHeapBitMap _collector_free_bitmap;
 36   size_t _max;
 37 
 38   // Left-most and right-most region indexes. There are no free regions outside
 39   // of [left-most; right-most] index intervals
 40   size_t _mutator_leftmost, _mutator_rightmost;
 41   size_t _collector_leftmost, _collector_rightmost;
 42 
 43   size_t _capacity;
 44   size_t _used;
 45 
 46   void assert_bounds() const NOT_DEBUG_RETURN;
 47 
 48   bool is_mutator_free(size_t idx) const;
 49   bool is_collector_free(size_t idx) const;
 50 
 51   HeapWord* try_allocate_in(ShenandoahHeapRegion* region, ShenandoahAllocRequest& req, bool& in_new_region);
 52   HeapWord* allocate_with_affiliation(ShenandoahRegionAffiliation affiliation, ShenandoahAllocRequest& req, bool& in_new_region);
 53 
 54   // While holding the heap lock, allocate memory for a single object which is to be entirely contained
 55   // within a single HeapRegion as characterized by req.  The req.size() value is known to be less than or
 56   // equal to ShenandoahHeapRegion::humongous_threshold_words().  The caller of allocate_single is responsible
 57   // for registering the resulting object and setting the remembered set card values as appropriate.  The
 58   // most common case is that we are allocating a PLAB in which case object registering and card dirtying
 59   // is managed after the PLAB is divided into individual objects.
 60   HeapWord* allocate_single(ShenandoahAllocRequest& req, bool& in_new_region);
 61   HeapWord* allocate_contiguous(ShenandoahAllocRequest& req);
 62 
 63   void flip_to_gc(ShenandoahHeapRegion* r);
 64 
 65   void recompute_bounds();
 66   void adjust_bounds();
 67   bool touches_bounds(size_t num) const;
 68 
 69   void increase_used(size_t amount);
 70   void clear_internal();
 71 
 72   size_t collector_count() const { return _collector_free_bitmap.count_one_bits(); }
 73   size_t mutator_count()   const { return _mutator_free_bitmap.count_one_bits();   }
 74 
 75   void try_recycle_trashed(ShenandoahHeapRegion *r);
 76 
 77   bool can_allocate_from(ShenandoahHeapRegion *r);
 78   size_t alloc_capacity(ShenandoahHeapRegion *r);
 79   bool has_no_alloc_capacity(ShenandoahHeapRegion *r);
 80 
 81 public:
 82   ShenandoahFreeSet(ShenandoahHeap* heap, size_t max_regions);
 83 
 84   void clear();
 85   void rebuild();
 86 
 87   void recycle_trash();
 88 
 89   void log_status();
 90 
 91   size_t capacity()  const { return _capacity; }
 92   size_t used()      const { return _used;     }
 93   size_t available() const {
 94     assert(_used <= _capacity, "must use less than capacity");
 95     return _capacity - _used;
 96   }
 97 
 98   HeapWord* allocate(ShenandoahAllocRequest& req, bool& in_new_region);
 99   size_t unsafe_peek_free() const;
100 
101   double internal_fragmentation();
102   double external_fragmentation();
103 
104   void print_on(outputStream* out) const;
105 };
106 
107 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHFREESET_HPP