src/share/vm/gc_implementation/g1/g1Allocator.hpp

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7131
d35872270666
child 7651
c132be0fb74d
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

sjohanss@7118 1 /*
sjohanss@7118 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
sjohanss@7118 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
sjohanss@7118 4 *
sjohanss@7118 5 * This code is free software; you can redistribute it and/or modify it
sjohanss@7118 6 * under the terms of the GNU General Public License version 2 only, as
sjohanss@7118 7 * published by the Free Software Foundation.
sjohanss@7118 8 *
sjohanss@7118 9 * This code is distributed in the hope that it will be useful, but WITHOUT
sjohanss@7118 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
sjohanss@7118 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
sjohanss@7118 12 * version 2 for more details (a copy is included in the LICENSE file that
sjohanss@7118 13 * accompanied this code).
sjohanss@7118 14 *
sjohanss@7118 15 * You should have received a copy of the GNU General Public License version
sjohanss@7118 16 * 2 along with this work; if not, write to the Free Software Foundation,
sjohanss@7118 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
sjohanss@7118 18 *
sjohanss@7118 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
sjohanss@7118 20 * or visit www.oracle.com if you need additional information or have any
sjohanss@7118 21 * questions.
sjohanss@7118 22 *
sjohanss@7118 23 */
sjohanss@7118 24
sjohanss@7118 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
sjohanss@7118 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
sjohanss@7118 27
sjohanss@7118 28 #include "gc_implementation/g1/g1AllocationContext.hpp"
sjohanss@7118 29 #include "gc_implementation/g1/g1AllocRegion.hpp"
sjohanss@7118 30 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
sjohanss@7118 31
sjohanss@7118 32 enum GCAllocPurpose {
sjohanss@7118 33 GCAllocForTenured,
sjohanss@7118 34 GCAllocForSurvived,
sjohanss@7118 35 GCAllocPurposeCount
sjohanss@7118 36 };
sjohanss@7118 37
sjohanss@7118 38 // Base class for G1 allocators.
sjohanss@7118 39 class G1Allocator : public CHeapObj<mtGC> {
sjohanss@7118 40 friend class VMStructs;
sjohanss@7118 41 protected:
sjohanss@7118 42 G1CollectedHeap* _g1h;
sjohanss@7118 43
sjohanss@7118 44 // Outside of GC pauses, the number of bytes used in all regions other
sjohanss@7118 45 // than the current allocation region.
sjohanss@7118 46 size_t _summary_bytes_used;
sjohanss@7118 47
sjohanss@7118 48 public:
sjohanss@7118 49 G1Allocator(G1CollectedHeap* heap) :
sjohanss@7118 50 _g1h(heap), _summary_bytes_used(0) { }
sjohanss@7118 51
sjohanss@7118 52 static G1Allocator* create_allocator(G1CollectedHeap* g1h);
sjohanss@7118 53
sjohanss@7118 54 virtual void init_mutator_alloc_region() = 0;
sjohanss@7118 55 virtual void release_mutator_alloc_region() = 0;
sjohanss@7118 56
sjohanss@7118 57 virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
sjohanss@7118 58 virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) = 0;
sjohanss@7118 59 virtual void abandon_gc_alloc_regions() = 0;
sjohanss@7118 60
sjohanss@7118 61 virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
sjohanss@7118 62 virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
sjohanss@7118 63 virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0;
sjohanss@7118 64 virtual size_t used() = 0;
sjohanss@7118 65 virtual bool is_retained_old_region(HeapRegion* hr) = 0;
sjohanss@7118 66
sjohanss@7118 67 void reuse_retained_old_region(EvacuationInfo& evacuation_info,
sjohanss@7118 68 OldGCAllocRegion* old,
sjohanss@7118 69 HeapRegion** retained);
sjohanss@7118 70
sjohanss@7118 71 size_t used_unlocked() const {
sjohanss@7118 72 return _summary_bytes_used;
sjohanss@7118 73 }
sjohanss@7118 74
sjohanss@7118 75 void increase_used(size_t bytes) {
sjohanss@7118 76 _summary_bytes_used += bytes;
sjohanss@7118 77 }
sjohanss@7118 78
sjohanss@7118 79 void decrease_used(size_t bytes) {
sjohanss@7118 80 assert(_summary_bytes_used >= bytes,
sjohanss@7118 81 err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" should be >= bytes: "SIZE_FORMAT,
sjohanss@7118 82 _summary_bytes_used, bytes));
sjohanss@7118 83 _summary_bytes_used -= bytes;
sjohanss@7118 84 }
sjohanss@7118 85
sjohanss@7118 86 void set_used(size_t bytes) {
sjohanss@7118 87 _summary_bytes_used = bytes;
sjohanss@7118 88 }
sjohanss@7131 89
sjohanss@7131 90 virtual HeapRegion* new_heap_region(uint hrs_index,
sjohanss@7131 91 G1BlockOffsetSharedArray* sharedOffsetArray,
sjohanss@7131 92 MemRegion mr) {
sjohanss@7131 93 return new HeapRegion(hrs_index, sharedOffsetArray, mr);
sjohanss@7131 94 }
sjohanss@7118 95 };
sjohanss@7118 96
sjohanss@7118 97 // The default allocator for G1.
sjohanss@7118 98 class G1DefaultAllocator : public G1Allocator {
sjohanss@7118 99 protected:
sjohanss@7118 100 // Alloc region used to satisfy mutator allocation requests.
sjohanss@7118 101 MutatorAllocRegion _mutator_alloc_region;
sjohanss@7118 102
sjohanss@7118 103 // Alloc region used to satisfy allocation requests by the GC for
sjohanss@7118 104 // survivor objects.
sjohanss@7118 105 SurvivorGCAllocRegion _survivor_gc_alloc_region;
sjohanss@7118 106
sjohanss@7118 107 // Alloc region used to satisfy allocation requests by the GC for
sjohanss@7118 108 // old objects.
sjohanss@7118 109 OldGCAllocRegion _old_gc_alloc_region;
sjohanss@7118 110
sjohanss@7118 111 HeapRegion* _retained_old_gc_alloc_region;
sjohanss@7118 112 public:
sjohanss@7118 113 G1DefaultAllocator(G1CollectedHeap* heap) : G1Allocator(heap), _retained_old_gc_alloc_region(NULL) { }
sjohanss@7118 114
sjohanss@7118 115 virtual void init_mutator_alloc_region();
sjohanss@7118 116 virtual void release_mutator_alloc_region();
sjohanss@7118 117
sjohanss@7118 118 virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
sjohanss@7118 119 virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
sjohanss@7118 120 virtual void abandon_gc_alloc_regions();
sjohanss@7118 121
sjohanss@7118 122 virtual bool is_retained_old_region(HeapRegion* hr) {
sjohanss@7118 123 return _retained_old_gc_alloc_region == hr;
sjohanss@7118 124 }
sjohanss@7118 125
sjohanss@7118 126 virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) {
sjohanss@7118 127 return &_mutator_alloc_region;
sjohanss@7118 128 }
sjohanss@7118 129
sjohanss@7118 130 virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) {
sjohanss@7118 131 return &_survivor_gc_alloc_region;
sjohanss@7118 132 }
sjohanss@7118 133
sjohanss@7118 134 virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) {
sjohanss@7118 135 return &_old_gc_alloc_region;
sjohanss@7118 136 }
sjohanss@7118 137
sjohanss@7118 138 virtual size_t used() {
sjohanss@7118 139 assert(Heap_lock->owner() != NULL,
sjohanss@7118 140 "Should be owned on this thread's behalf.");
sjohanss@7118 141 size_t result = _summary_bytes_used;
sjohanss@7118 142
sjohanss@7118 143 // Read only once in case it is set to NULL concurrently
sjohanss@7118 144 HeapRegion* hr = mutator_alloc_region(AllocationContext::current())->get();
sjohanss@7118 145 if (hr != NULL) {
sjohanss@7118 146 result += hr->used();
sjohanss@7118 147 }
sjohanss@7118 148 return result;
sjohanss@7118 149 }
sjohanss@7118 150 };
sjohanss@7118 151
sjohanss@7118 152 class G1ParGCAllocBuffer: public ParGCAllocBuffer {
sjohanss@7118 153 private:
sjohanss@7118 154 bool _retired;
sjohanss@7118 155
sjohanss@7118 156 public:
sjohanss@7118 157 G1ParGCAllocBuffer(size_t gclab_word_size);
sjohanss@7118 158 virtual ~G1ParGCAllocBuffer() {
sjohanss@7118 159 guarantee(_retired, "Allocation buffer has not been retired");
sjohanss@7118 160 }
sjohanss@7118 161
sjohanss@7118 162 virtual void set_buf(HeapWord* buf) {
sjohanss@7118 163 ParGCAllocBuffer::set_buf(buf);
sjohanss@7118 164 _retired = false;
sjohanss@7118 165 }
sjohanss@7118 166
sjohanss@7118 167 virtual void retire(bool end_of_gc, bool retain) {
sjohanss@7118 168 if (_retired) {
sjohanss@7118 169 return;
sjohanss@7118 170 }
sjohanss@7118 171 ParGCAllocBuffer::retire(end_of_gc, retain);
sjohanss@7118 172 _retired = true;
sjohanss@7118 173 }
sjohanss@7118 174 };
sjohanss@7118 175
sjohanss@7118 176 class G1ParGCAllocator : public CHeapObj<mtGC> {
sjohanss@7118 177 friend class G1ParScanThreadState;
sjohanss@7118 178 protected:
sjohanss@7118 179 G1CollectedHeap* _g1h;
sjohanss@7118 180
sjohanss@7118 181 size_t _alloc_buffer_waste;
sjohanss@7118 182 size_t _undo_waste;
sjohanss@7118 183
sjohanss@7118 184 void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
sjohanss@7118 185 void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
sjohanss@7118 186
sjohanss@7118 187 HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context);
sjohanss@7118 188
sjohanss@7118 189 virtual void retire_alloc_buffers() = 0;
sjohanss@7118 190 virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) = 0;
sjohanss@7118 191
sjohanss@7118 192 public:
sjohanss@7118 193 G1ParGCAllocator(G1CollectedHeap* g1h) :
sjohanss@7118 194 _g1h(g1h), _alloc_buffer_waste(0), _undo_waste(0) {
sjohanss@7118 195 }
sjohanss@7118 196
sjohanss@7118 197 static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
sjohanss@7118 198
sjohanss@7118 199 size_t alloc_buffer_waste() { return _alloc_buffer_waste; }
sjohanss@7118 200 size_t undo_waste() {return _undo_waste; }
sjohanss@7118 201
sjohanss@7118 202 HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
sjohanss@7118 203 HeapWord* obj = NULL;
sjohanss@7118 204 if (purpose == GCAllocForSurvived) {
sjohanss@7118 205 obj = alloc_buffer(purpose, context)->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
sjohanss@7118 206 } else {
sjohanss@7118 207 obj = alloc_buffer(purpose, context)->allocate(word_sz);
sjohanss@7118 208 }
sjohanss@7118 209 if (obj != NULL) {
sjohanss@7118 210 return obj;
sjohanss@7118 211 }
sjohanss@7118 212 return allocate_slow(purpose, word_sz, context);
sjohanss@7118 213 }
sjohanss@7118 214
sjohanss@7118 215 void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
sjohanss@7118 216 if (alloc_buffer(purpose, context)->contains(obj)) {
sjohanss@7118 217 assert(alloc_buffer(purpose, context)->contains(obj + word_sz - 1),
sjohanss@7118 218 "should contain whole object");
sjohanss@7118 219 alloc_buffer(purpose, context)->undo_allocation(obj, word_sz);
sjohanss@7118 220 } else {
sjohanss@7118 221 CollectedHeap::fill_with_object(obj, word_sz);
sjohanss@7118 222 add_to_undo_waste(word_sz);
sjohanss@7118 223 }
sjohanss@7118 224 }
sjohanss@7118 225 };
sjohanss@7118 226
sjohanss@7118 227 class G1DefaultParGCAllocator : public G1ParGCAllocator {
sjohanss@7118 228 G1ParGCAllocBuffer _surviving_alloc_buffer;
sjohanss@7118 229 G1ParGCAllocBuffer _tenured_alloc_buffer;
sjohanss@7118 230 G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
sjohanss@7118 231
sjohanss@7118 232 public:
sjohanss@7118 233 G1DefaultParGCAllocator(G1CollectedHeap* g1h);
sjohanss@7118 234
sjohanss@7118 235 virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) {
sjohanss@7118 236 return _alloc_buffers[purpose];
sjohanss@7118 237 }
sjohanss@7118 238
sjohanss@7118 239 virtual void retire_alloc_buffers() ;
sjohanss@7118 240 };
sjohanss@7118 241
sjohanss@7118 242 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP

mercurial