Tue, 08 Aug 2017 15:57:29 +0800
merge
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. |
aoqi@0 | 8 | * |
aoqi@0 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 13 | * accompanied this code). |
aoqi@0 | 14 | * |
aoqi@0 | 15 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 18 | * |
aoqi@0 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 20 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 21 | * questions. |
aoqi@0 | 22 | * |
aoqi@0 | 23 | */ |
aoqi@0 | 24 | |
aoqi@0 | 25 | #ifndef SHARE_VM_MEMORY_ADAPTIVEFREELIST_HPP |
aoqi@0 | 26 | #define SHARE_VM_MEMORY_ADAPTIVEFREELIST_HPP |
aoqi@0 | 27 | |
aoqi@0 | 28 | #include "memory/freeList.hpp" |
aoqi@0 | 29 | #include "gc_implementation/shared/allocationStats.hpp" |
aoqi@0 | 30 | |
aoqi@0 | 31 | class CompactibleFreeListSpace; |
aoqi@0 | 32 | |
aoqi@0 | 33 | // A class for maintaining a free list of Chunk's. The FreeList |
aoqi@0 | 34 | // maintains a the structure of the list (head, tail, etc.) plus |
aoqi@0 | 35 | // statistics for allocations from the list. The links between items |
aoqi@0 | 36 | // are not part of FreeList. The statistics are |
aoqi@0 | 37 | // used to make decisions about coalescing Chunk's when they |
aoqi@0 | 38 | // are swept during collection. |
aoqi@0 | 39 | // |
aoqi@0 | 40 | // See the corresponding .cpp file for a description of the specifics |
aoqi@0 | 41 | // for that implementation. |
aoqi@0 | 42 | |
aoqi@0 | 43 | class Mutex; |
aoqi@0 | 44 | |
aoqi@0 | 45 | template <class Chunk> |
aoqi@0 | 46 | class AdaptiveFreeList : public FreeList<Chunk> { |
aoqi@0 | 47 | friend class CompactibleFreeListSpace; |
aoqi@0 | 48 | friend class VMStructs; |
aoqi@0 | 49 | // friend class PrintTreeCensusClosure<Chunk, FreeList_t>; |
aoqi@0 | 50 | |
aoqi@0 | 51 | size_t _hint; // next larger size list with a positive surplus |
aoqi@0 | 52 | |
aoqi@0 | 53 | AllocationStats _allocation_stats; // allocation-related statistics |
aoqi@0 | 54 | |
aoqi@0 | 55 | public: |
aoqi@0 | 56 | |
aoqi@0 | 57 | AdaptiveFreeList(); |
aoqi@0 | 58 | |
aoqi@0 | 59 | using FreeList<Chunk>::assert_proper_lock_protection; |
aoqi@0 | 60 | #ifdef ASSERT |
aoqi@0 | 61 | using FreeList<Chunk>::protecting_lock; |
aoqi@0 | 62 | #endif |
aoqi@0 | 63 | using FreeList<Chunk>::count; |
aoqi@0 | 64 | using FreeList<Chunk>::size; |
aoqi@0 | 65 | using FreeList<Chunk>::verify_chunk_in_free_list; |
aoqi@0 | 66 | using FreeList<Chunk>::getFirstNChunksFromList; |
aoqi@0 | 67 | using FreeList<Chunk>::print_on; |
aoqi@0 | 68 | void return_chunk_at_head(Chunk* fc, bool record_return); |
aoqi@0 | 69 | void return_chunk_at_head(Chunk* fc); |
aoqi@0 | 70 | void return_chunk_at_tail(Chunk* fc, bool record_return); |
aoqi@0 | 71 | void return_chunk_at_tail(Chunk* fc); |
aoqi@0 | 72 | using FreeList<Chunk>::return_chunk_at_tail; |
aoqi@0 | 73 | using FreeList<Chunk>::remove_chunk; |
aoqi@0 | 74 | using FreeList<Chunk>::prepend; |
aoqi@0 | 75 | using FreeList<Chunk>::print_labels_on; |
aoqi@0 | 76 | using FreeList<Chunk>::get_chunk_at_head; |
aoqi@0 | 77 | |
aoqi@0 | 78 | // Initialize. |
aoqi@0 | 79 | void initialize(); |
aoqi@0 | 80 | |
aoqi@0 | 81 | // Reset the head, tail, hint, and count of a free list. |
aoqi@0 | 82 | void reset(size_t hint); |
aoqi@0 | 83 | |
aoqi@0 | 84 | void assert_proper_lock_protection_work() const PRODUCT_RETURN; |
aoqi@0 | 85 | |
aoqi@0 | 86 | void print_on(outputStream* st, const char* c = NULL) const; |
aoqi@0 | 87 | |
aoqi@0 | 88 | size_t hint() const { |
aoqi@0 | 89 | return _hint; |
aoqi@0 | 90 | } |
aoqi@0 | 91 | void set_hint(size_t v) { |
aoqi@0 | 92 | assert_proper_lock_protection(); |
aoqi@0 | 93 | assert(v == 0 || size() < v, "Bad hint"); |
aoqi@0 | 94 | _hint = v; |
aoqi@0 | 95 | } |
aoqi@0 | 96 | |
aoqi@0 | 97 | size_t get_better_size(); |
aoqi@0 | 98 | |
aoqi@0 | 99 | // Accessors for statistics |
aoqi@0 | 100 | void init_statistics(bool split_birth = false); |
aoqi@0 | 101 | |
aoqi@0 | 102 | AllocationStats* allocation_stats() { |
aoqi@0 | 103 | assert_proper_lock_protection(); |
aoqi@0 | 104 | return &_allocation_stats; |
aoqi@0 | 105 | } |
aoqi@0 | 106 | |
aoqi@0 | 107 | ssize_t desired() const { |
aoqi@0 | 108 | return _allocation_stats.desired(); |
aoqi@0 | 109 | } |
aoqi@0 | 110 | void set_desired(ssize_t v) { |
aoqi@0 | 111 | assert_proper_lock_protection(); |
aoqi@0 | 112 | _allocation_stats.set_desired(v); |
aoqi@0 | 113 | } |
aoqi@0 | 114 | void compute_desired(float inter_sweep_current, |
aoqi@0 | 115 | float inter_sweep_estimate, |
aoqi@0 | 116 | float intra_sweep_estimate) { |
aoqi@0 | 117 | assert_proper_lock_protection(); |
aoqi@0 | 118 | _allocation_stats.compute_desired(count(), |
aoqi@0 | 119 | inter_sweep_current, |
aoqi@0 | 120 | inter_sweep_estimate, |
aoqi@0 | 121 | intra_sweep_estimate); |
aoqi@0 | 122 | } |
aoqi@0 | 123 | ssize_t coal_desired() const { |
aoqi@0 | 124 | return _allocation_stats.coal_desired(); |
aoqi@0 | 125 | } |
aoqi@0 | 126 | void set_coal_desired(ssize_t v) { |
aoqi@0 | 127 | assert_proper_lock_protection(); |
aoqi@0 | 128 | _allocation_stats.set_coal_desired(v); |
aoqi@0 | 129 | } |
aoqi@0 | 130 | |
aoqi@0 | 131 | ssize_t surplus() const { |
aoqi@0 | 132 | return _allocation_stats.surplus(); |
aoqi@0 | 133 | } |
aoqi@0 | 134 | void set_surplus(ssize_t v) { |
aoqi@0 | 135 | assert_proper_lock_protection(); |
aoqi@0 | 136 | _allocation_stats.set_surplus(v); |
aoqi@0 | 137 | } |
aoqi@0 | 138 | void increment_surplus() { |
aoqi@0 | 139 | assert_proper_lock_protection(); |
aoqi@0 | 140 | _allocation_stats.increment_surplus(); |
aoqi@0 | 141 | } |
aoqi@0 | 142 | void decrement_surplus() { |
aoqi@0 | 143 | assert_proper_lock_protection(); |
aoqi@0 | 144 | _allocation_stats.decrement_surplus(); |
aoqi@0 | 145 | } |
aoqi@0 | 146 | |
aoqi@0 | 147 | ssize_t bfr_surp() const { |
aoqi@0 | 148 | return _allocation_stats.bfr_surp(); |
aoqi@0 | 149 | } |
aoqi@0 | 150 | void set_bfr_surp(ssize_t v) { |
aoqi@0 | 151 | assert_proper_lock_protection(); |
aoqi@0 | 152 | _allocation_stats.set_bfr_surp(v); |
aoqi@0 | 153 | } |
aoqi@0 | 154 | ssize_t prev_sweep() const { |
aoqi@0 | 155 | return _allocation_stats.prev_sweep(); |
aoqi@0 | 156 | } |
aoqi@0 | 157 | void set_prev_sweep(ssize_t v) { |
aoqi@0 | 158 | assert_proper_lock_protection(); |
aoqi@0 | 159 | _allocation_stats.set_prev_sweep(v); |
aoqi@0 | 160 | } |
aoqi@0 | 161 | ssize_t before_sweep() const { |
aoqi@0 | 162 | return _allocation_stats.before_sweep(); |
aoqi@0 | 163 | } |
aoqi@0 | 164 | void set_before_sweep(ssize_t v) { |
aoqi@0 | 165 | assert_proper_lock_protection(); |
aoqi@0 | 166 | _allocation_stats.set_before_sweep(v); |
aoqi@0 | 167 | } |
aoqi@0 | 168 | |
aoqi@0 | 169 | ssize_t coal_births() const { |
aoqi@0 | 170 | return _allocation_stats.coal_births(); |
aoqi@0 | 171 | } |
aoqi@0 | 172 | void set_coal_births(ssize_t v) { |
aoqi@0 | 173 | assert_proper_lock_protection(); |
aoqi@0 | 174 | _allocation_stats.set_coal_births(v); |
aoqi@0 | 175 | } |
aoqi@0 | 176 | void increment_coal_births() { |
aoqi@0 | 177 | assert_proper_lock_protection(); |
aoqi@0 | 178 | _allocation_stats.increment_coal_births(); |
aoqi@0 | 179 | } |
aoqi@0 | 180 | |
aoqi@0 | 181 | ssize_t coal_deaths() const { |
aoqi@0 | 182 | return _allocation_stats.coal_deaths(); |
aoqi@0 | 183 | } |
aoqi@0 | 184 | void set_coal_deaths(ssize_t v) { |
aoqi@0 | 185 | assert_proper_lock_protection(); |
aoqi@0 | 186 | _allocation_stats.set_coal_deaths(v); |
aoqi@0 | 187 | } |
aoqi@0 | 188 | void increment_coal_deaths() { |
aoqi@0 | 189 | assert_proper_lock_protection(); |
aoqi@0 | 190 | _allocation_stats.increment_coal_deaths(); |
aoqi@0 | 191 | } |
aoqi@0 | 192 | |
aoqi@0 | 193 | ssize_t split_births() const { |
aoqi@0 | 194 | return _allocation_stats.split_births(); |
aoqi@0 | 195 | } |
aoqi@0 | 196 | void set_split_births(ssize_t v) { |
aoqi@0 | 197 | assert_proper_lock_protection(); |
aoqi@0 | 198 | _allocation_stats.set_split_births(v); |
aoqi@0 | 199 | } |
aoqi@0 | 200 | void increment_split_births() { |
aoqi@0 | 201 | assert_proper_lock_protection(); |
aoqi@0 | 202 | _allocation_stats.increment_split_births(); |
aoqi@0 | 203 | } |
aoqi@0 | 204 | |
aoqi@0 | 205 | ssize_t split_deaths() const { |
aoqi@0 | 206 | return _allocation_stats.split_deaths(); |
aoqi@0 | 207 | } |
aoqi@0 | 208 | void set_split_deaths(ssize_t v) { |
aoqi@0 | 209 | assert_proper_lock_protection(); |
aoqi@0 | 210 | _allocation_stats.set_split_deaths(v); |
aoqi@0 | 211 | } |
aoqi@0 | 212 | void increment_split_deaths() { |
aoqi@0 | 213 | assert_proper_lock_protection(); |
aoqi@0 | 214 | _allocation_stats.increment_split_deaths(); |
aoqi@0 | 215 | } |
aoqi@0 | 216 | |
aoqi@0 | 217 | #ifndef PRODUCT |
aoqi@0 | 218 | // For debugging. The "_returned_bytes" in all the lists are summed |
aoqi@0 | 219 | // and compared with the total number of bytes swept during a |
aoqi@0 | 220 | // collection. |
aoqi@0 | 221 | size_t returned_bytes() const { return _allocation_stats.returned_bytes(); } |
aoqi@0 | 222 | void set_returned_bytes(size_t v) { _allocation_stats.set_returned_bytes(v); } |
aoqi@0 | 223 | void increment_returned_bytes_by(size_t v) { |
aoqi@0 | 224 | _allocation_stats.set_returned_bytes(_allocation_stats.returned_bytes() + v); |
aoqi@0 | 225 | } |
aoqi@0 | 226 | // Stats verification |
aoqi@0 | 227 | void verify_stats() const; |
aoqi@0 | 228 | #endif // NOT PRODUCT |
aoqi@0 | 229 | }; |
aoqi@0 | 230 | |
aoqi@0 | 231 | #endif // SHARE_VM_MEMORY_ADAPTIVEFREELIST_HPP |