src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 2314
f95d63e2154a
child 3181
c63b928b212b
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

duke@435 1 /*
stefank@2314 2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
stefank@2314 27 #include "gc_implementation/parallelScavenge/psPromotionLAB.hpp"
stefank@2314 28 #include "gc_implementation/shared/mutableSpace.hpp"
stefank@2314 29 #include "oops/oop.inline.hpp"
duke@435 30
coleenp@548 31 size_t PSPromotionLAB::filler_header_size;
duke@435 32
duke@435 33 // This is the shared initialization code. It sets up the basic pointers,
duke@435 34 // and allows enough extra space for a filler object. We call a virtual
duke@435 35 // method, "lab_is_valid()" to handle the different asserts the old/young
duke@435 36 // labs require.
duke@435 37 void PSPromotionLAB::initialize(MemRegion lab) {
duke@435 38 assert(lab_is_valid(lab), "Sanity");
duke@435 39
duke@435 40 HeapWord* bottom = lab.start();
duke@435 41 HeapWord* end = lab.end();
duke@435 42
duke@435 43 set_bottom(bottom);
duke@435 44 set_end(end);
duke@435 45 set_top(bottom);
duke@435 46
coleenp@548 47 // Initialize after VM starts up because header_size depends on compressed
coleenp@548 48 // oops.
coleenp@548 49 filler_header_size = align_object_size(typeArrayOopDesc::header_size(T_INT));
coleenp@548 50
duke@435 51 // We can be initialized to a zero size!
duke@435 52 if (free() > 0) {
duke@435 53 if (ZapUnusedHeapArea) {
duke@435 54 debug_only(Copy::fill_to_words(top(), free()/HeapWordSize, badHeapWord));
duke@435 55 }
duke@435 56
duke@435 57 // NOTE! We need to allow space for a filler object.
duke@435 58 assert(lab.word_size() >= filler_header_size, "lab is too small");
duke@435 59 end = end - filler_header_size;
duke@435 60 set_end(end);
duke@435 61
duke@435 62 _state = needs_flush;
duke@435 63 } else {
duke@435 64 _state = zero_size;
duke@435 65 }
duke@435 66
duke@435 67 assert(this->top() <= this->end(), "pointers out of order");
duke@435 68 }
duke@435 69
duke@435 70 // Fill all remaining lab space with an unreachable object.
duke@435 71 // The goal is to leave a contiguous parseable span of objects.
duke@435 72 void PSPromotionLAB::flush() {
duke@435 73 assert(_state != flushed, "Attempt to flush PLAB twice");
duke@435 74 assert(top() <= end(), "pointers out of order");
duke@435 75
duke@435 76 // If we were initialized to a zero sized lab, there is
duke@435 77 // nothing to flush
duke@435 78 if (_state == zero_size)
duke@435 79 return;
duke@435 80
duke@435 81 // PLAB's never allocate the last aligned_header_size
duke@435 82 // so they can always fill with an array.
duke@435 83 HeapWord* tlab_end = end() + filler_header_size;
duke@435 84 typeArrayOop filler_oop = (typeArrayOop) top();
duke@435 85 filler_oop->set_mark(markOopDesc::prototype());
duke@435 86 filler_oop->set_klass(Universe::intArrayKlassObj());
duke@435 87 const size_t array_length =
duke@435 88 pointer_delta(tlab_end, top()) - typeArrayOopDesc::header_size(T_INT);
duke@435 89 assert( (array_length * (HeapWordSize/sizeof(jint))) < (size_t)max_jint, "array too big in PSPromotionLAB");
duke@435 90 filler_oop->set_length((int)(array_length * (HeapWordSize/sizeof(jint))));
duke@435 91
duke@435 92 #ifdef ASSERT
duke@435 93 // Note that we actually DO NOT want to use the aligned header size!
duke@435 94 HeapWord* elt_words = ((HeapWord*)filler_oop) + typeArrayOopDesc::header_size(T_INT);
duke@435 95 Copy::fill_to_words(elt_words, array_length, 0xDEAABABE);
duke@435 96 #endif
duke@435 97
duke@435 98 set_bottom(NULL);
duke@435 99 set_end(NULL);
duke@435 100 set_top(NULL);
duke@435 101
duke@435 102 _state = flushed;
duke@435 103 }
duke@435 104
duke@435 105 bool PSPromotionLAB::unallocate_object(oop obj) {
duke@435 106 assert(Universe::heap()->is_in(obj), "Object outside heap");
duke@435 107
duke@435 108 if (contains(obj)) {
duke@435 109 HeapWord* object_end = (HeapWord*)obj + obj->size();
duke@435 110 assert(object_end <= top(), "Object crosses promotion LAB boundary");
duke@435 111
duke@435 112 if (object_end == top()) {
duke@435 113 set_top((HeapWord*)obj);
duke@435 114 return true;
duke@435 115 }
duke@435 116 }
duke@435 117
duke@435 118 return false;
duke@435 119 }
duke@435 120
duke@435 121 // Fill all remaining lab space with an unreachable object.
duke@435 122 // The goal is to leave a contiguous parseable span of objects.
duke@435 123 void PSOldPromotionLAB::flush() {
duke@435 124 assert(_state != flushed, "Attempt to flush PLAB twice");
duke@435 125 assert(top() <= end(), "pointers out of order");
duke@435 126
duke@435 127 if (_state == zero_size)
duke@435 128 return;
duke@435 129
duke@435 130 HeapWord* obj = top();
duke@435 131
duke@435 132 PSPromotionLAB::flush();
duke@435 133
duke@435 134 assert(_start_array != NULL, "Sanity");
duke@435 135
duke@435 136 _start_array->allocate_block(obj);
duke@435 137 }
duke@435 138
duke@435 139 #ifdef ASSERT
duke@435 140
duke@435 141 bool PSYoungPromotionLAB::lab_is_valid(MemRegion lab) {
duke@435 142 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
duke@435 143 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@435 144
duke@435 145 MutableSpace* to_space = heap->young_gen()->to_space();
duke@435 146 MemRegion used = to_space->used_region();
duke@435 147 if (used.contains(lab)) {
duke@435 148 return true;
duke@435 149 }
duke@435 150
duke@435 151 return false;
duke@435 152 }
duke@435 153
duke@435 154 bool PSOldPromotionLAB::lab_is_valid(MemRegion lab) {
duke@435 155 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
duke@435 156 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@435 157 assert(_start_array->covered_region().contains(lab), "Sanity");
duke@435 158
duke@435 159 PSOldGen* old_gen = heap->old_gen();
duke@435 160 MemRegion used = old_gen->object_space()->used_region();
duke@435 161
duke@435 162 if (used.contains(lab)) {
duke@435 163 return true;
duke@435 164 }
duke@435 165
duke@435 166 return false;
duke@435 167 }
duke@435 168
duke@435 169 #endif /* ASSERT */

mercurial