# HG changeset patch # User johnc # Date 1285994920 25200 # Node ID 32a1f7bf0c21ac33c6d748f432e0d2bb8a5e601a # Parent 4e0094bc41fa2f4294a4923332ca66e21c92b7b3# Parent e41cd7fd68a6adbdb6ef34a3171ab30e58af2251 Merge diff -r 4e0094bc41fa -r 32a1f7bf0c21 src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp Fri Oct 01 18:23:16 2010 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp Fri Oct 01 21:48:40 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. 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 @@ -50,6 +50,18 @@ } } +HeapWord* CMSPermGen::request_expand_and_allocate(Generation* gen, + size_t size, + GCCause::Cause prev_cause /* ignored */) { + HeapWord* obj = gen->expand_and_allocate(size, false); + if (gen->capacity() >= _capacity_expansion_limit) { + set_capacity_expansion_limit(gen->capacity() + MaxPermHeapExpansion); + assert(((ConcurrentMarkSweepGeneration*)gen)->should_concurrent_collect(), + "Should kick off a collection if one not in progress"); + } + return obj; +} + void CMSPermGen::compute_new_size() { _gen->compute_new_size(); } diff -r 4e0094bc41fa -r 32a1f7bf0c21 src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp Fri Oct 01 18:23:16 2010 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp Fri Oct 01 21:48:40 2010 -0700 @@ -33,6 +33,10 @@ // The "generation" view. ConcurrentMarkSweepGeneration* _gen; + // Override default implementation from PermGen + virtual HeapWord* request_expand_and_allocate(Generation* gen, size_t size, + GCCause::Cause prev_cause); + public: CMSPermGen(ReservedSpace rs, size_t initial_byte_size, CardTableRS* ct, FreeBlockDictionary::DictionaryChoice); diff -r 4e0094bc41fa -r 32a1f7bf0c21 src/share/vm/includeDB_core --- a/src/share/vm/includeDB_core Fri Oct 01 18:23:16 2010 -0700 +++ b/src/share/vm/includeDB_core Fri Oct 01 21:48:40 2010 -0700 @@ -3456,6 +3456,7 @@ permGen.hpp generation.hpp permGen.hpp handles.hpp permGen.hpp iterator.hpp +permGen.hpp mutexLocker.hpp permGen.hpp virtualspace.hpp placeholders.cpp fieldType.hpp diff -r 4e0094bc41fa -r 32a1f7bf0c21 src/share/vm/memory/permGen.cpp --- a/src/share/vm/memory/permGen.cpp Fri Oct 01 18:23:16 2010 -0700 +++ b/src/share/vm/memory/permGen.cpp Fri Oct 01 21:48:40 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. 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 @@ -25,6 +25,17 @@ #include "incls/_precompiled.incl" #include "incls/_permGen.cpp.incl" +HeapWord* PermGen::request_expand_and_allocate(Generation* gen, size_t size, + GCCause::Cause prev_cause) { + if (gen->capacity() < _capacity_expansion_limit || + prev_cause != GCCause::_no_gc || UseG1GC) { // last disjunct is a temporary hack for G1 + return gen->expand_and_allocate(size, false); + } + // We have reached the limit of capacity expansion where + // we will not expand further until a GC is done; request denied. + return NULL; +} + HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) { GCCause::Cause next_cause = GCCause::_permanent_generation_full; GCCause::Cause prev_cause = GCCause::_no_gc; @@ -37,10 +48,14 @@ if ((obj = gen->allocate(size, false)) != NULL) { return obj; } - if (gen->capacity() < _capacity_expansion_limit || - prev_cause != GCCause::_no_gc) { - obj = gen->expand_and_allocate(size, false); - } + // Attempt to expand and allocate the requested space: + // specific subtypes may use specific policy to either expand + // or not. The default policy (see above) is to expand until + // _capacity_expansion_limit, and no further unless a GC is done. + // Concurrent collectors may decide to kick off a concurrent + // collection under appropriate conditions. + obj = request_expand_and_allocate(gen, size, prev_cause); + if (obj != NULL || prev_cause == GCCause::_last_ditch_collection) { return obj; } @@ -119,5 +134,5 @@ if (_gen->capacity() > desired_capacity) { _gen->shrink(_gen->capacity() - desired_capacity); } - _capacity_expansion_limit = _gen->capacity() + MaxPermHeapExpansion; + set_capacity_expansion_limit(_gen->capacity() + MaxPermHeapExpansion); } diff -r 4e0094bc41fa -r 32a1f7bf0c21 src/share/vm/memory/permGen.hpp --- a/src/share/vm/memory/permGen.hpp Fri Oct 01 18:23:16 2010 -0700 +++ b/src/share/vm/memory/permGen.hpp Fri Oct 01 21:48:40 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. 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 @@ -30,15 +30,26 @@ class GenRemSet; class CSpaceCounters; -// PermGen models the part of the heap +// PermGen models the part of the heap used to allocate class meta-data. class PermGen : public CHeapObj { friend class VMStructs; protected: size_t _capacity_expansion_limit; // maximum expansion allowed without a // full gc occurring + void set_capacity_expansion_limit(size_t limit) { + assert_locked_or_safepoint(Heap_lock); + _capacity_expansion_limit = limit; + } HeapWord* mem_allocate_in_gen(size_t size, Generation* gen); + // Along with mem_allocate_in_gen() above, implements policy for + // "scheduling" allocation/expansion/collection of the perm gen. + // The virtual method request_...() below can be overridden by + // subtypes that want to implement a different expansion/collection + // policy from the default provided. + virtual HeapWord* request_expand_and_allocate(Generation* gen, size_t size, + GCCause::Cause prev_cause); public: enum Name {