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

Fri, 29 Apr 2016 00:06:10 +0800

author
aoqi
date
Fri, 29 Apr 2016 00:06:10 +0800
changeset 1
2d8a650513c2
parent 0
f90c822e73f8
child 25
873fd82b133d
permissions
-rw-r--r--

Added MIPS 64-bit port.

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2002, 2010, 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@1 25 /*
aoqi@1 26 * This file has been modified by Loongson Technology in 2015. These
aoqi@1 27 * modifications are Copyright (c) 2015 Loongson Technology, and are made
aoqi@1 28 * available on the same license terms set forth above.
aoqi@1 29 */
aoqi@1 30
aoqi@0 31 #include "precompiled.hpp"
aoqi@0 32 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
aoqi@0 33 #include "gc_implementation/parallelScavenge/psPromotionLAB.hpp"
aoqi@0 34 #include "gc_implementation/shared/mutableSpace.hpp"
aoqi@1 35 #include "gc_implementation/shared/mutableNUMASpace.hpp"
aoqi@0 36 #include "oops/oop.inline.hpp"
aoqi@0 37
aoqi@0 38 size_t PSPromotionLAB::filler_header_size;
aoqi@0 39
aoqi@0 40 // This is the shared initialization code. It sets up the basic pointers,
aoqi@0 41 // and allows enough extra space for a filler object. We call a virtual
aoqi@0 42 // method, "lab_is_valid()" to handle the different asserts the old/young
aoqi@0 43 // labs require.
aoqi@0 44 void PSPromotionLAB::initialize(MemRegion lab) {
aoqi@0 45 assert(lab_is_valid(lab), "Sanity");
aoqi@0 46
aoqi@0 47 HeapWord* bottom = lab.start();
aoqi@0 48 HeapWord* end = lab.end();
aoqi@0 49
aoqi@0 50 set_bottom(bottom);
aoqi@0 51 set_end(end);
aoqi@0 52 set_top(bottom);
aoqi@0 53
aoqi@0 54 // Initialize after VM starts up because header_size depends on compressed
aoqi@0 55 // oops.
aoqi@0 56 filler_header_size = align_object_size(typeArrayOopDesc::header_size(T_INT));
aoqi@0 57
aoqi@0 58 // We can be initialized to a zero size!
aoqi@0 59 if (free() > 0) {
aoqi@0 60 if (ZapUnusedHeapArea) {
aoqi@0 61 debug_only(Copy::fill_to_words(top(), free()/HeapWordSize, badHeapWord));
aoqi@0 62 }
aoqi@0 63
aoqi@0 64 // NOTE! We need to allow space for a filler object.
aoqi@0 65 assert(lab.word_size() >= filler_header_size, "lab is too small");
aoqi@0 66 end = end - filler_header_size;
aoqi@0 67 set_end(end);
aoqi@0 68
aoqi@0 69 _state = needs_flush;
aoqi@0 70 } else {
aoqi@0 71 _state = zero_size;
aoqi@0 72 }
aoqi@0 73
aoqi@0 74 assert(this->top() <= this->end(), "pointers out of order");
aoqi@0 75 }
aoqi@0 76
aoqi@0 77 // Fill all remaining lab space with an unreachable object.
aoqi@0 78 // The goal is to leave a contiguous parseable span of objects.
aoqi@0 79 void PSPromotionLAB::flush() {
aoqi@0 80 assert(_state != flushed, "Attempt to flush PLAB twice");
aoqi@0 81 assert(top() <= end(), "pointers out of order");
aoqi@0 82
aoqi@0 83 // If we were initialized to a zero sized lab, there is
aoqi@0 84 // nothing to flush
aoqi@0 85 if (_state == zero_size)
aoqi@0 86 return;
aoqi@0 87
aoqi@0 88 // PLAB's never allocate the last aligned_header_size
aoqi@0 89 // so they can always fill with an array.
aoqi@0 90 HeapWord* tlab_end = end() + filler_header_size;
aoqi@0 91 typeArrayOop filler_oop = (typeArrayOop) top();
aoqi@0 92 filler_oop->set_mark(markOopDesc::prototype());
aoqi@0 93 filler_oop->set_klass(Universe::intArrayKlassObj());
aoqi@0 94 const size_t array_length =
aoqi@0 95 pointer_delta(tlab_end, top()) - typeArrayOopDesc::header_size(T_INT);
aoqi@0 96 assert( (array_length * (HeapWordSize/sizeof(jint))) < (size_t)max_jint, "array too big in PSPromotionLAB");
aoqi@0 97 filler_oop->set_length((int)(array_length * (HeapWordSize/sizeof(jint))));
aoqi@0 98
aoqi@0 99 #ifdef ASSERT
aoqi@0 100 // Note that we actually DO NOT want to use the aligned header size!
aoqi@0 101 HeapWord* elt_words = ((HeapWord*)filler_oop) + typeArrayOopDesc::header_size(T_INT);
aoqi@0 102 Copy::fill_to_words(elt_words, array_length, 0xDEAABABE);
aoqi@0 103 #endif
aoqi@0 104
aoqi@0 105 set_bottom(NULL);
aoqi@0 106 set_end(NULL);
aoqi@0 107 set_top(NULL);
aoqi@0 108
aoqi@0 109 _state = flushed;
aoqi@0 110 }
aoqi@0 111
aoqi@0 112 bool PSPromotionLAB::unallocate_object(HeapWord* obj, size_t obj_size) {
aoqi@0 113 assert(Universe::heap()->is_in(obj), "Object outside heap");
aoqi@0 114
aoqi@0 115 if (contains(obj)) {
aoqi@0 116 HeapWord* object_end = obj + obj_size;
aoqi@0 117 assert(object_end == top(), "Not matching last allocation");
aoqi@0 118
aoqi@0 119 set_top(obj);
aoqi@0 120 return true;
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 return false;
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 // Fill all remaining lab space with an unreachable object.
aoqi@0 127 // The goal is to leave a contiguous parseable span of objects.
aoqi@0 128 void PSOldPromotionLAB::flush() {
aoqi@0 129 assert(_state != flushed, "Attempt to flush PLAB twice");
aoqi@0 130 assert(top() <= end(), "pointers out of order");
aoqi@0 131
aoqi@0 132 if (_state == zero_size)
aoqi@0 133 return;
aoqi@0 134
aoqi@0 135 HeapWord* obj = top();
aoqi@0 136
aoqi@0 137 PSPromotionLAB::flush();
aoqi@0 138
aoqi@0 139 assert(_start_array != NULL, "Sanity");
aoqi@0 140
aoqi@0 141 _start_array->allocate_block(obj);
aoqi@0 142 }
aoqi@0 143
aoqi@0 144 #ifdef ASSERT
aoqi@0 145
aoqi@0 146 bool PSYoungPromotionLAB::lab_is_valid(MemRegion lab) {
aoqi@0 147 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
aoqi@0 148 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
aoqi@0 149
aoqi@0 150 MutableSpace* to_space = heap->young_gen()->to_space();
aoqi@0 151 MemRegion used = to_space->used_region();
aoqi@0 152 if (used.contains(lab)) {
aoqi@0 153 return true;
aoqi@0 154 }
aoqi@0 155
aoqi@0 156 return false;
aoqi@0 157 }
aoqi@0 158
aoqi@0 159 bool PSOldPromotionLAB::lab_is_valid(MemRegion lab) {
aoqi@0 160 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
aoqi@0 161 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
aoqi@0 162 assert(_start_array->covered_region().contains(lab), "Sanity");
aoqi@0 163
aoqi@0 164 PSOldGen* old_gen = heap->old_gen();
aoqi@0 165 MemRegion used = old_gen->object_space()->used_region();
aoqi@0 166
aoqi@1 167 /* 2014/2/12/ Liao: In UseOldNUMA, the new lab may be allocated out of the current used_region.
aoqi@1 168 * For example, a new plab should be allocated in lgrp2, while the top of current used_region
aoqi@1 169 * is in lgrp1. The original checking will return invalid, while this situation is reasonable.
aoqi@1 170 * So we should check whether the lab is in one of the lgrps. */
aoqi@1 171 if(UseOldNUMA) {
aoqi@1 172 MutableSpace* sp;
aoqi@1 173 MutableNUMASpace::LGRPSpace *ls;
aoqi@1 174 MutableNUMASpace* s = (MutableNUMASpace*) old_gen->object_space();
aoqi@1 175 int i, j;
aoqi@1 176 i = s->lgrp_spaces()->length();
aoqi@1 177 for(j = 0; j < i; j++) {
aoqi@1 178 ls = s->lgrp_spaces()->at(j);
aoqi@1 179 sp = ls->space();
aoqi@1 180 used = sp ->used_region();
aoqi@1 181 if (used.contains(lab))
aoqi@1 182 return true;
aoqi@1 183 }
aoqi@1 184 }
aoqi@1 185 else {
aoqi@1 186 if (used.contains(lab)) {
aoqi@1 187 return true;
aoqi@1 188 }
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 return false;
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 #endif /* ASSERT */

mercurial