1 /* 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. 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 #include "precompiled.hpp" 26 #include "gc_implementation/shared/collectorCounters.hpp" 27 #include "gc_implementation/shared/parGCAllocBuffer.hpp" 28 #include "memory/allocation.inline.hpp" 29 #include "memory/blockOffsetTable.inline.hpp" 30 #include "memory/generation.inline.hpp" 31 #include "memory/generationSpec.hpp" 32 #include "memory/space.hpp" 33 #include "memory/tenuredGeneration.hpp" 34 #include "oops/oop.inline.hpp" 35 #include "runtime/java.hpp" 36 #include "utilities/macros.hpp" 37 38 TenuredGeneration::TenuredGeneration(ReservedSpace rs, 39 size_t initial_byte_size, 40 GenRemSet* remset) : 41 OneContigSpaceCardGeneration(rs, initial_byte_size, remset, NULL) 42 { 43 HeapWord* bottom = (HeapWord*) _virtual_space.low(); 44 HeapWord* end = (HeapWord*) _virtual_space.high(); 45 _the_space = new TenuredSpace(_bts, MemRegion(bottom, end)); 46 _the_space->reset_saved_mark(); 47 _shrink_factor = 0; 48 _capacity_at_prologue = 0; 49 50 _gc_stats = new GCStats(); 51 52 // initialize performance counters 53 54 const char* gen_name = "old"; 55 GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy(); 56 57 // Generation Counters -- generation 1, 1 subspace 58 _gen_counters = new GenerationCounters(gen_name, 1, 1, 59 gcp->min_old_size(), gcp->max_old_size(), &_virtual_space); 60 61 _gc_counters = new CollectorCounters("MSC", 1); 62 63 _space_counters = new CSpaceCounters(gen_name, 0, 64 _virtual_space.reserved_size(), 65 _the_space, _gen_counters); 66 #if INCLUDE_ALL_GCS 67 if (UseParNewGC) { 68 typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr; 69 _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr, 70 ParallelGCThreads, mtGC); 71 if (_alloc_buffers == NULL) 72 vm_exit_during_initialization("Could not allocate alloc_buffers"); 73 for (uint i = 0; i < ParallelGCThreads; i++) { 74 _alloc_buffers[i] = 75 new ParGCAllocBufferWithBOT(OldPLABSize, _bts); 76 if (_alloc_buffers[i] == NULL) 77 vm_exit_during_initialization("Could not allocate alloc_buffers"); 78 } 79 } else { 80 _alloc_buffers = NULL; 81 } 82 #endif // INCLUDE_ALL_GCS 83 } 84 85 86 const char* TenuredGeneration::name() const { 87 return "tenured generation"; 88 } 89 90 void TenuredGeneration::gc_prologue(bool full) { 91 _capacity_at_prologue = capacity(); 92 _used_at_prologue = used(); 93 if (VerifyBeforeGC) { 94 verify_alloc_buffers_clean(); 95 } 96 } 97 98 void TenuredGeneration::gc_epilogue(bool full) { 99 if (VerifyAfterGC) { 100 verify_alloc_buffers_clean(); 101 } 102 OneContigSpaceCardGeneration::gc_epilogue(full); 103 } 104 105 106 bool TenuredGeneration::should_collect(bool full, 107 size_t size, 108 bool is_tlab) { 109 // This should be one big conditional or (||), but I want to be able to tell 110 // why it returns what it returns (without re-evaluating the conditionals 111 // in case they aren't idempotent), so I'm doing it this way. 112 // DeMorgan says it's okay. 113 bool result = false; 114 if (!result && full) { 115 result = true; 116 if (PrintGC && Verbose) { 117 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" 118 " full"); 119 } 120 } 121 if (!result && should_allocate(size, is_tlab)) { 122 result = true; 123 if (PrintGC && Verbose) { 124 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" 125 " should_allocate(" SIZE_FORMAT ")", 126 size); 127 } 128 } 129 // If we don't have very much free space. 130 // XXX: 10000 should be a percentage of the capacity!!! 131 if (!result && free() < 10000) { 132 result = true; 133 if (PrintGC && Verbose) { 134 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" 135 " free(): " SIZE_FORMAT, 136 free()); 137 } 138 } 139 // If we had to expand to accommodate promotions from younger generations 140 if (!result && _capacity_at_prologue < capacity()) { 141 result = true; 142 if (PrintGC && Verbose) { 143 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" 144 "_capacity_at_prologue: " SIZE_FORMAT " < capacity(): " SIZE_FORMAT, 145 _capacity_at_prologue, capacity()); 146 } 147 } 148 return result; 149 } 150 151 void TenuredGeneration::collect(bool full, 152 bool clear_all_soft_refs, 153 size_t size, 154 bool is_tlab) { 155 retire_alloc_buffers_before_full_gc(); 156 OneContigSpaceCardGeneration::collect(full, clear_all_soft_refs, 157 size, is_tlab); 158 } 159 160 void TenuredGeneration::compute_new_size() { 161 assert_locked_or_safepoint(Heap_lock); 162 163 // Compute some numbers about the state of the heap. 164 const size_t used_after_gc = used(); 165 const size_t capacity_after_gc = capacity(); 166 167 CardGeneration::compute_new_size(); 168 169 assert(used() == used_after_gc && used_after_gc <= capacity(), 170 err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT 171 " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity())); 172 } 173 174 void TenuredGeneration::update_gc_stats(Generation* current_generation, 175 bool full) { 176 // If the young generation has been collected, gather any statistics 177 // that are of interest at this point. 178 bool current_is_young = (current_generation == GenCollectedHeap::heap()->young_gen()); 179 if (!full && current_is_young) { 180 // Calculate size of data promoted from the younger generations 181 // before doing the collection. 182 size_t used_before_gc = used(); 183 184 // If the younger gen collections were skipped, then the 185 // number of promoted bytes will be 0 and adding it to the 186 // average will incorrectly lessen the average. It is, however, 187 // also possible that no promotion was needed. 188 if (used_before_gc >= _used_at_prologue) { 189 size_t promoted_in_bytes = used_before_gc - _used_at_prologue; 190 gc_stats()->avg_promoted()->sample(promoted_in_bytes); 191 } 192 } 193 } 194 195 void TenuredGeneration::update_counters() { 196 if (UsePerfData) { 197 _space_counters->update_all(); 198 _gen_counters->update_all(); 199 } 200 } 201 202 203 #if INCLUDE_ALL_GCS 204 oop TenuredGeneration::par_promote(int thread_num, 205 oop old, markOop m, size_t word_sz) { 206 207 ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num]; 208 HeapWord* obj_ptr = buf->allocate(word_sz); 209 bool is_lab = true; 210 if (obj_ptr == NULL) { 211 #ifndef PRODUCT 212 if (Universe::heap()->promotion_should_fail()) { 213 return NULL; 214 } 215 #endif // #ifndef PRODUCT 216 217 // Slow path: 218 if (word_sz * 100 < ParallelGCBufferWastePct * buf->word_sz()) { 219 // Is small enough; abandon this buffer and start a new one. 220 size_t buf_size = buf->word_sz(); 221 HeapWord* buf_space = 222 TenuredGeneration::par_allocate(buf_size, false); 223 if (buf_space == NULL) { 224 buf_space = expand_and_allocate(buf_size, false, true /* parallel*/); 225 } 226 if (buf_space != NULL) { 227 buf->retire(false, false); 228 buf->set_buf(buf_space); 229 obj_ptr = buf->allocate(word_sz); 230 assert(obj_ptr != NULL, "Buffer was definitely big enough..."); 231 } 232 }; 233 // Otherwise, buffer allocation failed; try allocating object 234 // individually. 235 if (obj_ptr == NULL) { 236 obj_ptr = TenuredGeneration::par_allocate(word_sz, false); 237 if (obj_ptr == NULL) { 238 obj_ptr = expand_and_allocate(word_sz, false, true /* parallel */); 239 } 240 } 241 if (obj_ptr == NULL) return NULL; 242 } 243 assert(obj_ptr != NULL, "program logic"); 244 Copy::aligned_disjoint_words((HeapWord*)old, obj_ptr, word_sz); 245 oop obj = oop(obj_ptr); 246 // Restore the mark word copied above. 247 obj->set_mark(m); 248 return obj; 249 } 250 251 void TenuredGeneration::par_promote_alloc_undo(int thread_num, 252 HeapWord* obj, 253 size_t word_sz) { 254 ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num]; 255 if (buf->contains(obj)) { 256 guarantee(buf->contains(obj + word_sz - 1), 257 "should contain whole object"); 258 buf->undo_allocation(obj, word_sz); 259 } else { 260 CollectedHeap::fill_with_object(obj, word_sz); 261 } 262 } 263 264 void TenuredGeneration::par_promote_alloc_done(int thread_num) { 265 ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num]; 266 buf->retire(true, ParallelGCRetainPLAB); 267 } 268 269 void TenuredGeneration::retire_alloc_buffers_before_full_gc() { 270 if (UseParNewGC) { 271 for (uint i = 0; i < ParallelGCThreads; i++) { 272 _alloc_buffers[i]->retire(true /*end_of_gc*/, false /*retain*/); 273 } 274 } 275 } 276 277 // Verify that any retained parallel allocation buffers do not 278 // intersect with dirty cards. 279 void TenuredGeneration::verify_alloc_buffers_clean() { 280 if (UseParNewGC) { 281 for (uint i = 0; i < ParallelGCThreads; i++) { 282 _rs->verify_aligned_region_empty(_alloc_buffers[i]->range()); 283 } 284 } 285 } 286 287 #else // INCLUDE_ALL_GCS 288 void TenuredGeneration::retire_alloc_buffers_before_full_gc() {} 289 void TenuredGeneration::verify_alloc_buffers_clean() {} 290 #endif // INCLUDE_ALL_GCS 291 292 bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const { 293 size_t available = max_contiguous_available(); 294 size_t av_promo = (size_t)gc_stats()->avg_promoted()->padded_average(); 295 bool res = (available >= av_promo) || (available >= max_promotion_in_bytes); 296 if (PrintGC && Verbose) { 297 gclog_or_tty->print_cr( 298 "Tenured: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT")," 299 "max_promo("SIZE_FORMAT")", 300 res? "":" not", available, res? ">=":"<", 301 av_promo, max_promotion_in_bytes); 302 } 303 return res; 304 }