1 /* 2 * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. 3 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHALLOCREQUEST_HPP 27 #define SHARE_GC_SHENANDOAH_SHENANDOAHALLOCREQUEST_HPP 28 29 #include "gc/shenandoah/shenandoahAffiliation.hpp" 30 #include "memory/allocation.hpp" 31 32 class ShenandoahAllocRequest : StackObj { 33 public: 34 enum Type { 35 _alloc_shared, // Allocate common, outside of TLAB 36 _alloc_shared_gc, // Allocate common, outside of GCLAB/PLAB 37 _alloc_tlab, // Allocate TLAB 38 _alloc_gclab, // Allocate GCLAB 39 _alloc_plab, // Allocate PLAB 40 _ALLOC_LIMIT 41 }; 42 43 static const char* alloc_type_to_string(Type type) { 44 switch (type) { 45 case _alloc_shared: 46 return "Shared"; 47 case _alloc_shared_gc: 48 return "Shared GC"; 49 case _alloc_tlab: 50 return "TLAB"; 51 case _alloc_gclab: 52 return "GCLAB"; 53 case _alloc_plab: 54 return "PLAB"; 55 default: 56 ShouldNotReachHere(); 57 return ""; 58 } 59 } 60 61 private: 62 // When ShenandoahElasticTLAB is enabled, the request cannot be made smaller than _min_size. 63 size_t _min_size; 64 65 // The size of the request in words. 66 size_t _requested_size; 67 68 // The allocation may be increased for padding or decreased to fit in the remaining space of a region. 69 size_t _actual_size; 70 71 // For a humongous object, the _waste is the amount of free memory in the last region. 72 // For other requests, the _waste will be non-zero if the request enountered one or more regions 73 // with less memory than _min_size. This waste does not contribute to the used memory for 74 // the heap, but it does contribute to the allocation rate for heuristics. 75 size_t _waste; 76 77 // This is the type of the request. 78 Type _alloc_type; 79 80 // This is the generation which the request is targeting. 81 ShenandoahAffiliation const _affiliation; 82 83 // True if this request is trying to copy any object from young to old (promote). 84 bool _is_promotion; 85 86 #ifdef ASSERT 87 // Check that this is set before being read. 88 bool _actual_size_set; 89 #endif 90 91 ShenandoahAllocRequest(size_t _min_size, size_t _requested_size, Type _alloc_type, ShenandoahAffiliation affiliation, bool is_promotion = false) : 92 _min_size(_min_size), _requested_size(_requested_size), 93 _actual_size(0), _waste(0), _alloc_type(_alloc_type), _affiliation(affiliation), _is_promotion(is_promotion) 94 #ifdef ASSERT 95 , _actual_size_set(false) 96 #endif 97 {} 98 99 public: 100 static inline ShenandoahAllocRequest for_tlab(size_t min_size, size_t requested_size) { 101 return ShenandoahAllocRequest(min_size, requested_size, _alloc_tlab, ShenandoahAffiliation::YOUNG_GENERATION); 102 } 103 104 static inline ShenandoahAllocRequest for_gclab(size_t min_size, size_t requested_size) { 105 return ShenandoahAllocRequest(min_size, requested_size, _alloc_gclab, ShenandoahAffiliation::YOUNG_GENERATION); 106 } 107 108 static inline ShenandoahAllocRequest for_plab(size_t min_size, size_t requested_size) { 109 return ShenandoahAllocRequest(min_size, requested_size, _alloc_plab, ShenandoahAffiliation::OLD_GENERATION); 110 } 111 112 static inline ShenandoahAllocRequest for_shared_gc(size_t requested_size, ShenandoahAffiliation affiliation, bool is_promotion = false) { 113 if (is_promotion) { 114 assert(affiliation == ShenandoahAffiliation::OLD_GENERATION, "Should only promote to old generation"); 115 return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc, affiliation, true); 116 } 117 return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc, affiliation); 118 } 119 120 static inline ShenandoahAllocRequest for_shared(size_t requested_size) { 121 return ShenandoahAllocRequest(0, requested_size, _alloc_shared, ShenandoahAffiliation::YOUNG_GENERATION); 122 } 123 124 inline size_t size() const { 125 return _requested_size; 126 } 127 128 inline Type type() const { 129 return _alloc_type; 130 } 131 132 inline const char* type_string() const { 133 return alloc_type_to_string(_alloc_type); 134 } 135 136 inline size_t min_size() const { 137 assert (is_lab_alloc(), "Only access for LAB allocs"); 138 return _min_size; 139 } 140 141 inline size_t actual_size() const { 142 assert (_actual_size_set, "Should be set"); 143 return _actual_size; 144 } 145 146 inline void set_actual_size(size_t v) { 147 #ifdef ASSERT 148 assert (!_actual_size_set, "Should not be set"); 149 _actual_size_set = true; 150 #endif 151 _actual_size = v; 152 } 153 154 inline size_t waste() const { 155 return _waste; 156 } 157 158 inline void set_waste(size_t v) { 159 _waste = v; 160 } 161 162 inline bool is_mutator_alloc() const { 163 switch (_alloc_type) { 164 case _alloc_tlab: 165 case _alloc_shared: 166 return true; 167 case _alloc_gclab: 168 case _alloc_plab: 169 case _alloc_shared_gc: 170 return false; 171 default: 172 ShouldNotReachHere(); 173 return false; 174 } 175 } 176 177 inline bool is_gc_alloc() const { 178 switch (_alloc_type) { 179 case _alloc_tlab: 180 case _alloc_shared: 181 return false; 182 case _alloc_gclab: 183 case _alloc_plab: 184 case _alloc_shared_gc: 185 return true; 186 default: 187 ShouldNotReachHere(); 188 return false; 189 } 190 } 191 192 inline bool is_lab_alloc() const { 193 switch (_alloc_type) { 194 case _alloc_tlab: 195 case _alloc_gclab: 196 case _alloc_plab: 197 return true; 198 case _alloc_shared: 199 case _alloc_shared_gc: 200 return false; 201 default: 202 ShouldNotReachHere(); 203 return false; 204 } 205 } 206 207 bool is_old() const { 208 return _affiliation == OLD_GENERATION; 209 } 210 211 bool is_young() const { 212 return _affiliation == YOUNG_GENERATION; 213 } 214 215 ShenandoahAffiliation affiliation() const { 216 return _affiliation; 217 } 218 219 const char* affiliation_name() const { 220 return shenandoah_affiliation_name(_affiliation); 221 } 222 223 bool is_promotion() const { 224 return _is_promotion; 225 } 226 }; 227 228 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHALLOCREQUEST_HPP