# HG changeset patch # User ehelin # Date 1389282831 -3600 # Node ID c8907928a976c892a120a8d8828591c2e999202b # Parent e9d5e8a38ae366d3b0d806cbcbf05db64bbc8d5f# Parent 9982f3b7527bd53706c308f67684f3be0811c1eb Merge diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jan 09 16:53:51 2014 +0100 @@ -2376,25 +2376,6 @@ return blk.result(); } -size_t G1CollectedHeap::unsafe_max_alloc() { - if (free_regions() > 0) return HeapRegion::GrainBytes; - // otherwise, is there space in the current allocation region? - - // We need to store the current allocation region in a local variable - // here. The problem is that this method doesn't take any locks and - // there may be other threads which overwrite the current allocation - // region field. attempt_allocation(), for example, sets it to NULL - // and this can happen *after* the NULL check here but before the call - // to free(), resulting in a SIGSEGV. Note that this doesn't appear - // to be a problem in the optimized build, since the two loads of the - // current allocation region field are optimized away. - HeapRegion* hr = _mutator_alloc_region.get(); - if (hr == NULL) { - return 0; - } - return hr->free(); -} - bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { switch (cause) { case GCCause::_gc_locker: return GCLockerInvokesConcurrent; diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jan 09 16:53:51 2014 +0100 @@ -1183,15 +1183,6 @@ // end fields defining the extent of the contiguous allocation region.) // But G1CollectedHeap doesn't yet support this. - // Return an estimate of the maximum allocation that could be performed - // without triggering any collection or expansion activity. In a - // generational collector, for example, this is probably the largest - // allocation that could be supported (without expansion) in the youngest - // generation. It is "unsafe" because no locks are taken; the result - // should be treated as an approximation, not a guarantee, for use in - // heuristic resizing decisions. - virtual size_t unsafe_max_alloc(); - virtual bool is_maximal_no_gc() const { return _g1_storage.uncommitted_size() == 0; } diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu Jan 09 16:53:51 2014 +0100 @@ -484,10 +484,6 @@ young_gen()->eden_space()->ensure_parsability(); } -size_t ParallelScavengeHeap::unsafe_max_alloc() { - return young_gen()->eden_space()->free_in_bytes(); -} - size_t ParallelScavengeHeap::tlab_capacity(Thread* thr) const { return young_gen()->eden_space()->tlab_capacity(thr); } diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Jan 09 16:53:51 2014 +0100 @@ -184,8 +184,6 @@ void accumulate_statistics_all_tlabs(); void resize_all_tlabs(); - size_t unsafe_max_alloc(); - bool supports_tlab_allocation() const { return true; } size_t tlab_capacity(Thread* thr) const; diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Jan 09 16:53:51 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, 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 @@ -466,10 +466,12 @@ } } - GCTraceTime tm("StringTable", false, false, &_gc_timer); - // Unlink any dead interned Strings and process the remaining live ones. - PSScavengeRootsClosure root_closure(promotion_manager); - StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure); + { + GCTraceTime tm("StringTable", false, false, &_gc_timer); + // Unlink any dead interned Strings and process the remaining live ones. + PSScavengeRootsClosure root_closure(promotion_manager); + StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure); + } // Finally, flush the promotion_manager's labs, and deallocate its stacks. promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer); diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/gc_interface/collectedHeap.hpp --- a/src/share/vm/gc_interface/collectedHeap.hpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Thu Jan 09 16:53:51 2014 +0100 @@ -389,15 +389,6 @@ // allocation from them and necessitating allocation of new TLABs. virtual void ensure_parsability(bool retire_tlabs); - // Return an estimate of the maximum allocation that could be performed - // without triggering any collection or expansion activity. In a - // generational collector, for example, this is probably the largest - // allocation that could be supported (without expansion) in the youngest - // generation. It is "unsafe" because no locks are taken; the result - // should be treated as an approximation, not a guarantee, for use in - // heuristic resizing decisions. - virtual size_t unsafe_max_alloc() = 0; - // Section on thread-local allocation buffers (TLABs) // If the heap supports thread-local allocation buffers, it should override // the following methods: diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/memory/defNewGeneration.cpp --- a/src/share/vm/memory/defNewGeneration.cpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/memory/defNewGeneration.cpp Thu Jan 09 16:53:51 2014 +0100 @@ -667,9 +667,6 @@ // for full GC's. AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy(); size_policy->reset_gc_overhead_limit_count(); - if (PrintGC && !PrintGCDetails) { - gch->print_heap_change(gch_prev_used); - } assert(!gch->incremental_collection_failed(), "Should be clear"); } else { assert(_promo_failure_scan_stack.is_empty(), "post condition"); @@ -695,6 +692,9 @@ // Reset the PromotionFailureALot counters. NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) } + if (PrintGC && !PrintGCDetails) { + gch->print_heap_change(gch_prev_used); + } // set new iteration safe limit for the survivor spaces from()->set_concurrent_iteration_safe_limit(from()->top()); to()->set_concurrent_iteration_safe_limit(to()->top()); diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/memory/genCollectedHeap.cpp Thu Jan 09 16:53:51 2014 +0100 @@ -673,10 +673,6 @@ return _gens[0]->end_addr(); } -size_t GenCollectedHeap::unsafe_max_alloc() { - return _gens[0]->unsafe_max_alloc_nogc(); -} - // public collection interfaces void GenCollectedHeap::collect(GCCause::Cause cause) { diff -r e9d5e8a38ae3 -r c8907928a976 src/share/vm/memory/genCollectedHeap.hpp --- a/src/share/vm/memory/genCollectedHeap.hpp Wed Jan 08 13:53:24 2014 -0800 +++ b/src/share/vm/memory/genCollectedHeap.hpp Thu Jan 09 16:53:51 2014 +0100 @@ -166,14 +166,6 @@ HeapWord** top_addr() const; HeapWord** end_addr() const; - // Return an estimate of the maximum allocation that could be performed - // without triggering any collection activity. In a generational - // collector, for example, this is probably the largest allocation that - // could be supported in the youngest generation. It is "unsafe" because - // no locks are taken; the result should be treated as an approximation, - // not a guarantee. - size_t unsafe_max_alloc(); - // Does this heap support heap inspection? (+PrintClassHistogram) virtual bool supports_heap_inspection() const { return true; } diff -r e9d5e8a38ae3 -r c8907928a976 test/gc/defnew/HeapChangeLogging.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/defnew/HeapChangeLogging.java Thu Jan 09 16:53:51 2014 +0100 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, 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 + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test HeapChangeLogging.java + * @bug 8027440 + * @library /testlibrary + * @build HeapChangeLogging + * @summary Allocate to get a promotion failure and verify that that heap change logging is present. + * @run main HeapChangeLogging + * + * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod. + */ + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.oracle.java.testlibrary.*; + +public class HeapChangeLogging { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xmx128m", "-Xmn100m", "-XX:+UseSerialGC", "-XX:+PrintGC", "HeapFiller"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + String stdout = output.getStdout(); + System.out.println(stdout); + Matcher stdoutMatcher = Pattern.compile("\\[GC .Allocation Failure.*K->.*K\\(.*K\\), .* secs\\]", Pattern.MULTILINE).matcher(stdout); + if (!stdoutMatcher.find()) { + throw new RuntimeException("No proper GC log line found"); + } + output.shouldHaveExitValue(0); + } +} + +class HeapFiller { + public static Entry root; + private static final int PAYLOAD_SIZE = 1000; + + public static void main(String[] args) { + root = new Entry(PAYLOAD_SIZE, null); + Entry current = root; + try { + while (true) { + Entry newEntry = new Entry(PAYLOAD_SIZE, current); + current = newEntry; + } + } catch (OutOfMemoryError e) { + root = null; + } + + } +} + +class Entry { + public Entry previous; + public byte[] payload; + + Entry(int payloadSize, Entry previous) { + payload = new byte[payloadSize]; + this.previous = previous; + } +} \ No newline at end of file