--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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;
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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);
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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);
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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:
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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());
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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) {
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Wed Jan 08 13:53:24 2014 -0800
+++ b/hotspot/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; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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