duke@435: /* stefank@2314: * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" stefank@2314: #include "gc_implementation/parallelScavenge/psPromotionLAB.hpp" stefank@2314: #include "gc_implementation/shared/mutableSpace.hpp" stefank@2314: #include "oops/oop.inline.hpp" duke@435: coleenp@548: size_t PSPromotionLAB::filler_header_size; duke@435: duke@435: // This is the shared initialization code. It sets up the basic pointers, duke@435: // and allows enough extra space for a filler object. We call a virtual duke@435: // method, "lab_is_valid()" to handle the different asserts the old/young duke@435: // labs require. duke@435: void PSPromotionLAB::initialize(MemRegion lab) { duke@435: assert(lab_is_valid(lab), "Sanity"); duke@435: duke@435: HeapWord* bottom = lab.start(); duke@435: HeapWord* end = lab.end(); duke@435: duke@435: set_bottom(bottom); duke@435: set_end(end); duke@435: set_top(bottom); duke@435: coleenp@548: // Initialize after VM starts up because header_size depends on compressed coleenp@548: // oops. coleenp@548: filler_header_size = align_object_size(typeArrayOopDesc::header_size(T_INT)); coleenp@548: duke@435: // We can be initialized to a zero size! duke@435: if (free() > 0) { duke@435: if (ZapUnusedHeapArea) { duke@435: debug_only(Copy::fill_to_words(top(), free()/HeapWordSize, badHeapWord)); duke@435: } duke@435: duke@435: // NOTE! We need to allow space for a filler object. duke@435: assert(lab.word_size() >= filler_header_size, "lab is too small"); duke@435: end = end - filler_header_size; duke@435: set_end(end); duke@435: duke@435: _state = needs_flush; duke@435: } else { duke@435: _state = zero_size; duke@435: } duke@435: duke@435: assert(this->top() <= this->end(), "pointers out of order"); duke@435: } duke@435: duke@435: // Fill all remaining lab space with an unreachable object. duke@435: // The goal is to leave a contiguous parseable span of objects. duke@435: void PSPromotionLAB::flush() { duke@435: assert(_state != flushed, "Attempt to flush PLAB twice"); duke@435: assert(top() <= end(), "pointers out of order"); duke@435: duke@435: // If we were initialized to a zero sized lab, there is duke@435: // nothing to flush duke@435: if (_state == zero_size) duke@435: return; duke@435: duke@435: // PLAB's never allocate the last aligned_header_size duke@435: // so they can always fill with an array. duke@435: HeapWord* tlab_end = end() + filler_header_size; duke@435: typeArrayOop filler_oop = (typeArrayOop) top(); duke@435: filler_oop->set_mark(markOopDesc::prototype()); duke@435: filler_oop->set_klass(Universe::intArrayKlassObj()); duke@435: const size_t array_length = duke@435: pointer_delta(tlab_end, top()) - typeArrayOopDesc::header_size(T_INT); duke@435: assert( (array_length * (HeapWordSize/sizeof(jint))) < (size_t)max_jint, "array too big in PSPromotionLAB"); duke@435: filler_oop->set_length((int)(array_length * (HeapWordSize/sizeof(jint)))); duke@435: duke@435: #ifdef ASSERT duke@435: // Note that we actually DO NOT want to use the aligned header size! duke@435: HeapWord* elt_words = ((HeapWord*)filler_oop) + typeArrayOopDesc::header_size(T_INT); duke@435: Copy::fill_to_words(elt_words, array_length, 0xDEAABABE); duke@435: #endif duke@435: duke@435: set_bottom(NULL); duke@435: set_end(NULL); duke@435: set_top(NULL); duke@435: duke@435: _state = flushed; duke@435: } duke@435: stefank@3181: bool PSPromotionLAB::unallocate_object(HeapWord* obj, size_t obj_size) { duke@435: assert(Universe::heap()->is_in(obj), "Object outside heap"); duke@435: duke@435: if (contains(obj)) { stefank@3181: HeapWord* object_end = obj + obj_size; stefank@3181: assert(object_end == top(), "Not matching last allocation"); duke@435: stefank@3181: set_top(obj); stefank@3181: return true; duke@435: } duke@435: duke@435: return false; duke@435: } duke@435: duke@435: // Fill all remaining lab space with an unreachable object. duke@435: // The goal is to leave a contiguous parseable span of objects. duke@435: void PSOldPromotionLAB::flush() { duke@435: assert(_state != flushed, "Attempt to flush PLAB twice"); duke@435: assert(top() <= end(), "pointers out of order"); duke@435: duke@435: if (_state == zero_size) duke@435: return; duke@435: duke@435: HeapWord* obj = top(); duke@435: duke@435: PSPromotionLAB::flush(); duke@435: duke@435: assert(_start_array != NULL, "Sanity"); duke@435: duke@435: _start_array->allocate_block(obj); duke@435: } duke@435: duke@435: #ifdef ASSERT duke@435: duke@435: bool PSYoungPromotionLAB::lab_is_valid(MemRegion lab) { duke@435: ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); duke@435: assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); duke@435: duke@435: MutableSpace* to_space = heap->young_gen()->to_space(); duke@435: MemRegion used = to_space->used_region(); duke@435: if (used.contains(lab)) { duke@435: return true; duke@435: } duke@435: duke@435: return false; duke@435: } duke@435: duke@435: bool PSOldPromotionLAB::lab_is_valid(MemRegion lab) { duke@435: ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); duke@435: assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); duke@435: assert(_start_array->covered_region().contains(lab), "Sanity"); duke@435: duke@435: PSOldGen* old_gen = heap->old_gen(); duke@435: MemRegion used = old_gen->object_space()->used_region(); duke@435: duke@435: if (used.contains(lab)) { duke@435: return true; duke@435: } duke@435: duke@435: return false; duke@435: } duke@435: duke@435: #endif /* ASSERT */