diff -r fd16c54261b3 -r 489c9b5090e2 hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +# include "incls/_precompiled.incl" +# include "incls/_psPermGen.cpp.incl" + +PSPermGen::PSPermGen(ReservedSpace rs, size_t alignment, + size_t initial_size, size_t min_size, size_t max_size, + const char* gen_name, int level) : + PSOldGen(rs, alignment, initial_size, min_size, max_size, gen_name, level), + _last_used(0) +{ + assert(object_mark_sweep() != NULL, "Sanity"); + + object_mark_sweep()->set_allowed_dead_ratio(PermMarkSweepDeadRatio); + _avg_size = new AdaptivePaddedAverage(AdaptivePermSizeWeight, + PermGenPadding); +} + +HeapWord* PSPermGen::allocate_permanent(size_t size) { + assert_locked_or_safepoint(Heap_lock); + HeapWord* obj = allocate_noexpand(size, false); + + if (obj == NULL) { + obj = expand_and_allocate(size, false); + } + + return obj; +} + +void PSPermGen::compute_new_size(size_t used_before_collection) { + // Update our padded average of objects allocated in perm + // gen between collections. + assert(used_before_collection >= _last_used, + "negative allocation amount since last GC?"); + + const size_t alloc_since_last_gc = used_before_collection - _last_used; + _avg_size->sample(alloc_since_last_gc); + + const size_t current_live = used_in_bytes(); + // Stash away the current amount live for the next call to this method. + _last_used = current_live; + + // We have different alignment constraints than the rest of the heap. + const size_t alignment = MAX2(MinPermHeapExpansion, + virtual_space()->alignment()); + + // Compute the desired size: + // The free space is the newly computed padded average, + // so the desired size is what's live + the free space. + size_t desired_size = current_live + (size_t)_avg_size->padded_average(); + desired_size = align_size_up(desired_size, alignment); + + // ...and no larger or smaller than our max and min allowed. + desired_size = MAX2(MIN2(desired_size, _max_gen_size), _min_gen_size); + assert(desired_size <= _max_gen_size, "just checking"); + + const size_t size_before = _virtual_space->committed_size(); + + if (desired_size == size_before) { + // no change, we're done + return; + } + + { + // We'll be growing or shrinking the heap: in either case, + // we need to hold a lock. + MutexLocker x(ExpandHeap_lock); + if (desired_size > size_before) { + const size_t change_bytes = desired_size - size_before; + const size_t aligned_change_bytes = + align_size_up(change_bytes, alignment); + expand_by(aligned_change_bytes); + } else { + // Shrinking + const size_t change_bytes = + size_before - desired_size; + const size_t aligned_change_bytes = align_size_down(change_bytes, alignment); + shrink(aligned_change_bytes); + } + } + + // While this code isn't controlled by AdaptiveSizePolicy, it's + // convenient to see all resizing decsions under the same flag. + if (PrintAdaptiveSizePolicy) { + ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); + assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); + + gclog_or_tty->print_cr("AdaptiveSizePolicy::perm generation size: " + "collection: %d " + "(" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ", + heap->total_collections(), + size_before, _virtual_space->committed_size()); + } +} + + + +void PSPermGen::move_and_update(ParCompactionManager* cm) { + PSParallelCompact::move_and_update(cm, PSParallelCompact::perm_space_id); +} + +void PSPermGen::precompact() { + // Reset start array first. + debug_only(if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {) + _start_array.reset(); + debug_only(}) + object_mark_sweep()->precompact(); +}