src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp

Thu, 12 Oct 2017 21:27:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 21:27:07 +0800
changeset 7535
7ae4e26cb1e0
parent 7476
c2844108a708
parent 6876
710a3c8b516e
permissions
-rw-r--r--

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_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
aoqi@0 26 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
jmasa@7031 27 #include "gc_interface/collectedHeap.hpp"
aoqi@0 28 #include "memory/allocation.hpp"
aoqi@0 29 #include "memory/blockOffsetTable.hpp"
aoqi@0 30 #include "memory/threadLocalAllocBuffer.hpp"
aoqi@0 31 #include "utilities/globalDefinitions.hpp"
aoqi@0 32
aoqi@0 33 // Forward decl.
aoqi@0 34
aoqi@0 35 class PLABStats;
aoqi@0 36
aoqi@0 37 // A per-thread allocation buffer used during GC.
aoqi@0 38 class ParGCAllocBuffer: public CHeapObj<mtGC> {
aoqi@0 39 protected:
aoqi@0 40 char head[32];
aoqi@0 41 size_t _word_sz; // in HeapWord units
aoqi@0 42 HeapWord* _bottom;
aoqi@0 43 HeapWord* _top;
aoqi@0 44 HeapWord* _end; // last allocatable address + 1
aoqi@0 45 HeapWord* _hard_end; // _end + AlignmentReserve
aoqi@0 46 bool _retained; // whether we hold a _retained_filler
aoqi@0 47 MemRegion _retained_filler;
aoqi@0 48 // In support of ergonomic sizing of PLAB's
aoqi@0 49 size_t _allocated; // in HeapWord units
aoqi@0 50 size_t _wasted; // in HeapWord units
aoqi@0 51 char tail[32];
aoqi@0 52 static size_t FillerHeaderSize;
aoqi@0 53 static size_t AlignmentReserve;
aoqi@0 54
aoqi@0 55 // Flush the stats supporting ergonomic sizing of PLAB's
aoqi@0 56 // Should not be called directly
aoqi@0 57 void flush_stats(PLABStats* stats);
aoqi@0 58
aoqi@0 59 public:
aoqi@0 60 // Initializes the buffer to be empty, but with the given "word_sz".
aoqi@0 61 // Must get initialized with "set_buf" for an allocation to succeed.
aoqi@0 62 ParGCAllocBuffer(size_t word_sz);
tschatzl@6929 63 virtual ~ParGCAllocBuffer() {}
aoqi@0 64
aoqi@0 65 static const size_t min_size() {
mgerdin@7470 66 // Make sure that we return something that is larger than AlignmentReserve
mgerdin@7470 67 return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve;
aoqi@0 68 }
aoqi@0 69
aoqi@0 70 static const size_t max_size() {
aoqi@0 71 return ThreadLocalAllocBuffer::max_size();
aoqi@0 72 }
aoqi@0 73
aoqi@0 74 // If an allocation of the given "word_sz" can be satisfied within the
aoqi@0 75 // buffer, do the allocation, returning a pointer to the start of the
aoqi@0 76 // allocated block. If the allocation request cannot be satisfied,
aoqi@0 77 // return NULL.
aoqi@0 78 HeapWord* allocate(size_t word_sz) {
aoqi@0 79 HeapWord* res = _top;
aoqi@0 80 if (pointer_delta(_end, _top) >= word_sz) {
aoqi@0 81 _top = _top + word_sz;
aoqi@0 82 return res;
aoqi@0 83 } else {
aoqi@0 84 return NULL;
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87
jmasa@7031 88 // Allocate the object aligned to "alignment_in_bytes".
jmasa@7031 89 HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes);
jmasa@7031 90
aoqi@0 91 // Undo the last allocation in the buffer, which is required to be of the
aoqi@0 92 // "obj" of the given "word_sz".
aoqi@0 93 void undo_allocation(HeapWord* obj, size_t word_sz) {
aoqi@0 94 assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo");
aoqi@0 95 assert(pointer_delta(_top, obj) == word_sz, "Bad undo");
aoqi@0 96 _top = obj;
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 // The total (word) size of the buffer, including both allocated and
aoqi@0 100 // unallocted space.
aoqi@0 101 size_t word_sz() { return _word_sz; }
aoqi@0 102
aoqi@0 103 // Should only be done if we are about to reset with a new buffer of the
aoqi@0 104 // given size.
aoqi@0 105 void set_word_size(size_t new_word_sz) {
aoqi@0 106 assert(new_word_sz > AlignmentReserve, "Too small");
aoqi@0 107 _word_sz = new_word_sz;
aoqi@0 108 }
aoqi@0 109
aoqi@0 110 // The number of words of unallocated space remaining in the buffer.
aoqi@0 111 size_t words_remaining() {
aoqi@0 112 assert(_end >= _top, "Negative buffer");
aoqi@0 113 return pointer_delta(_end, _top, HeapWordSize);
aoqi@0 114 }
aoqi@0 115
aoqi@0 116 bool contains(void* addr) {
aoqi@0 117 return (void*)_bottom <= addr && addr < (void*)_hard_end;
aoqi@0 118 }
aoqi@0 119
aoqi@0 120 // Sets the space of the buffer to be [buf, space+word_sz()).
tschatzl@6929 121 virtual void set_buf(HeapWord* buf) {
aoqi@0 122 _bottom = buf;
aoqi@0 123 _top = _bottom;
aoqi@0 124 _hard_end = _bottom + word_sz();
aoqi@0 125 _end = _hard_end - AlignmentReserve;
aoqi@0 126 assert(_end >= _top, "Negative buffer");
aoqi@0 127 // In support of ergonomic sizing
aoqi@0 128 _allocated += word_sz();
aoqi@0 129 }
aoqi@0 130
aoqi@0 131 // Flush the stats supporting ergonomic sizing of PLAB's
aoqi@0 132 // and retire the current buffer.
aoqi@0 133 void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
aoqi@0 134 // We flush the stats first in order to get a reading of
aoqi@0 135 // unused space in the last buffer.
aoqi@0 136 if (ResizePLAB) {
aoqi@0 137 flush_stats(stats);
aoqi@0 138
aoqi@0 139 // Since we have flushed the stats we need to clear
aoqi@0 140 // the _allocated and _wasted fields. Not doing so
aoqi@0 141 // will artifically inflate the values in the stats
aoqi@0 142 // to which we add them.
aoqi@0 143 // The next time we flush these values, we will add
aoqi@0 144 // what we have just flushed in addition to the size
aoqi@0 145 // of the buffers allocated between now and then.
aoqi@0 146 _allocated = 0;
aoqi@0 147 _wasted = 0;
aoqi@0 148 }
aoqi@0 149 // Retire the last allocation buffer.
aoqi@0 150 retire(end_of_gc, retain);
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 // Force future allocations to fail and queries for contains()
aoqi@0 154 // to return false
aoqi@0 155 void invalidate() {
aoqi@0 156 assert(!_retained, "Shouldn't retain an invalidated buffer.");
aoqi@0 157 _end = _hard_end;
aoqi@0 158 _wasted += pointer_delta(_end, _top); // unused space
aoqi@0 159 _top = _end; // force future allocations to fail
aoqi@0 160 _bottom = _end; // force future contains() queries to return false
aoqi@0 161 }
aoqi@0 162
aoqi@0 163 // Fills in the unallocated portion of the buffer with a garbage object.
aoqi@0 164 // If "end_of_gc" is TRUE, is after the last use in the GC. IF "retain"
aoqi@0 165 // is true, attempt to re-use the unused portion in the next GC.
tschatzl@6929 166 virtual void retire(bool end_of_gc, bool retain);
aoqi@0 167
aoqi@0 168 void print() PRODUCT_RETURN;
aoqi@0 169 };
aoqi@0 170
aoqi@0 171 // PLAB stats book-keeping
aoqi@0 172 class PLABStats VALUE_OBJ_CLASS_SPEC {
aoqi@0 173 size_t _allocated; // total allocated
aoqi@0 174 size_t _wasted; // of which wasted (internal fragmentation)
aoqi@0 175 size_t _unused; // Unused in last buffer
aoqi@0 176 size_t _used; // derived = allocated - wasted - unused
aoqi@0 177 size_t _desired_plab_sz;// output of filter (below), suitably trimmed and quantized
aoqi@0 178 AdaptiveWeightedAverage
aoqi@0 179 _filter; // integrator with decay
aoqi@0 180
aoqi@0 181 public:
aoqi@0 182 PLABStats(size_t desired_plab_sz_, unsigned wt) :
aoqi@0 183 _allocated(0),
aoqi@0 184 _wasted(0),
aoqi@0 185 _unused(0),
aoqi@0 186 _used(0),
aoqi@0 187 _desired_plab_sz(desired_plab_sz_),
aoqi@0 188 _filter(wt)
aoqi@0 189 { }
aoqi@0 190
aoqi@0 191 static const size_t min_size() {
aoqi@0 192 return ParGCAllocBuffer::min_size();
aoqi@0 193 }
aoqi@0 194
aoqi@0 195 static const size_t max_size() {
aoqi@0 196 return ParGCAllocBuffer::max_size();
aoqi@0 197 }
aoqi@0 198
aoqi@0 199 size_t desired_plab_sz() {
aoqi@0 200 return _desired_plab_sz;
aoqi@0 201 }
aoqi@0 202
aoqi@0 203 void adjust_desired_plab_sz(uint no_of_gc_workers);
aoqi@0 204 // filter computation, latches output to
aoqi@0 205 // _desired_plab_sz, clears sensor accumulators
aoqi@0 206
aoqi@0 207 void add_allocated(size_t v) {
aoqi@0 208 Atomic::add_ptr(v, &_allocated);
aoqi@0 209 }
aoqi@0 210
aoqi@0 211 void add_unused(size_t v) {
aoqi@0 212 Atomic::add_ptr(v, &_unused);
aoqi@0 213 }
aoqi@0 214
aoqi@0 215 void add_wasted(size_t v) {
aoqi@0 216 Atomic::add_ptr(v, &_wasted);
aoqi@0 217 }
aoqi@0 218 };
aoqi@0 219
aoqi@0 220 class ParGCAllocBufferWithBOT: public ParGCAllocBuffer {
aoqi@0 221 BlockOffsetArrayContigSpace _bt;
aoqi@0 222 BlockOffsetSharedArray* _bsa;
aoqi@0 223 HeapWord* _true_end; // end of the whole ParGCAllocBuffer
aoqi@0 224
aoqi@0 225 static const size_t ChunkSizeInWords;
aoqi@0 226 static const size_t ChunkSizeInBytes;
aoqi@0 227 HeapWord* allocate_slow(size_t word_sz);
aoqi@0 228
aoqi@0 229 void fill_region_with_block(MemRegion mr, bool contig);
aoqi@0 230
aoqi@0 231 public:
aoqi@0 232 ParGCAllocBufferWithBOT(size_t word_sz, BlockOffsetSharedArray* bsa);
aoqi@0 233
aoqi@0 234 HeapWord* allocate(size_t word_sz) {
aoqi@0 235 HeapWord* res = ParGCAllocBuffer::allocate(word_sz);
aoqi@0 236 if (res != NULL) {
aoqi@0 237 _bt.alloc_block(res, word_sz);
aoqi@0 238 } else {
aoqi@0 239 res = allocate_slow(word_sz);
aoqi@0 240 }
aoqi@0 241 return res;
aoqi@0 242 }
aoqi@0 243
aoqi@0 244 void undo_allocation(HeapWord* obj, size_t word_sz);
aoqi@0 245
tschatzl@6929 246 virtual void set_buf(HeapWord* buf_start) {
aoqi@0 247 ParGCAllocBuffer::set_buf(buf_start);
aoqi@0 248 _true_end = _hard_end;
aoqi@0 249 _bt.set_region(MemRegion(buf_start, word_sz()));
aoqi@0 250 _bt.initialize_threshold();
aoqi@0 251 }
aoqi@0 252
tschatzl@6929 253 virtual void retire(bool end_of_gc, bool retain);
aoqi@0 254
aoqi@0 255 MemRegion range() {
aoqi@0 256 return MemRegion(_top, _true_end);
aoqi@0 257 }
aoqi@0 258 };
aoqi@0 259
aoqi@0 260 #endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP

mercurial