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   HeapWord* allocate_with_old_affiliation(ShenandoahAllocRequest& req, bool& in_new_region);
 54 
 55   // While holding the heap lock, allocate memory for a single object which is to be entirely contained
 56   // within a single HeapRegion as characterized by req.  The req.size() value is known to be less than or
 57   // equal to ShenandoahHeapRegion::humongous_threshold_words().  The caller of allocate_single is responsible
 58   // for registering the resulting object and setting the remembered set card values as appropriate.  The
 59   // most common case is that we are allocating a PLAB in which case object registering and card dirtying
 60   // is managed after the PLAB is divided into individual objects.
 61   HeapWord* allocate_single(ShenandoahAllocRequest& req, bool& in_new_region);
 62   HeapWord* allocate_contiguous(ShenandoahAllocRequest& req);
 63 
 64   void flip_to_gc(ShenandoahHeapRegion* r);
 65 
 66   void recompute_bounds();
 67   void adjust_bounds();
 68   bool touches_bounds(size_t num) const;
 69 
 70   void increase_used(size_t amount);
 71   void clear_internal();
 72 
 73   void try_recycle_trashed(ShenandoahHeapRegion *r);
 74 
 75   bool can_allocate_from(ShenandoahHeapRegion *r);
 76   size_t alloc_capacity(ShenandoahHeapRegion *r);
 77   bool has_no_alloc_capacity(ShenandoahHeapRegion *r);
 78 
 79 public:
 80   ShenandoahFreeSet(ShenandoahHeap* heap, size_t max_regions);
 81 
 82   // Number of regions dedicated to GC allocations (for evacuation or promotion) that are currently free
 83   size_t collector_count() const { return _collector_free_bitmap.count_one_bits(); }
 84 
 85   // Number of regions dedicated to mutator allocations that are currently free
 86   size_t mutator_count()   const { return _mutator_free_bitmap.count_one_bits();   }
 87 
 88   void clear();
 89   void rebuild();
 90 
 91   void recycle_trash();
 92 
 93   void log_status();
 94 
 95   size_t capacity()  const { return _capacity; }
 96   size_t used()      const { return _used;     }
 97   size_t available() const {
 98     assert(_used <= _capacity, "must use less than capacity");
 99     return _capacity - _used;
100   }
101 
102   HeapWord* allocate(ShenandoahAllocRequest& req, bool& in_new_region);
103   size_t unsafe_peek_free() const;
104 
105   double internal_fragmentation();
106   double external_fragmentation();
107 
108   void print_on(outputStream* out) const;
109 
110   void reserve_regions(size_t to_reserve);
111 };
112 
113 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHFREESET_HPP