From b02e905da38efdd670ec95affe49701d193ecea0 Mon Sep 17 00:00:00 2001 From: johnc Date: Fri, 29 Mar 2013 13:49:37 -0700 Subject: [PATCH] 8010463: G1: Crashes with -UseTLAB and heap verification Summary: Some parts of the G1 heap can only be walked during a safepoint. Skip verifying these parts of the heap when verifying during JVM startup. Reviewed-by: brutisso, tschatzl --- .../gc_implementation/g1/g1CollectedHeap.cpp | 7 +-- src/share/vm/memory/universe.cpp | 9 ---- src/share/vm/runtime/init.cpp | 9 ---- src/share/vm/runtime/thread.cpp | 11 +++-- test/gc/TestVerifyBeforeGCDuringStartup.java | 45 +++++++++++++++++++ 5 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 test/gc/TestVerifyBeforeGCDuringStartup.java diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 780e330b4..610942585 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -3288,12 +3288,12 @@ void G1CollectedHeap::verify(bool silent) { void G1CollectedHeap::verify(bool silent, VerifyOption vo) { - if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { + if (SafepointSynchronize::is_at_safepoint()) { if (!silent) { gclog_or_tty->print("Roots "); } VerifyRootsClosure rootsCl(vo); assert(Thread::current()->is_VM_thread(), - "Expected to be executed serially by the VM thread at this point"); + "Expected to be executed serially by the VM thread at this point"); CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); VerifyKlassClosure klassCl(this, &rootsCl); @@ -3378,7 +3378,8 @@ void G1CollectedHeap::verify(bool silent, } guarantee(!failures, "there should not have been any failures"); } else { - if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) "); + if (!silent) + gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) "); } } diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp index 79e092a3b..d2bbf0175 100644 --- a/src/share/vm/memory/universe.cpp +++ b/src/share/vm/memory/universe.cpp @@ -953,15 +953,6 @@ void Universe::update_heap_info_at_gc() { void universe2_init() { EXCEPTION_MARK; Universe::genesis(CATCH); - // Although we'd like to verify here that the state of the heap - // is good, we can't because the main thread has not yet added - // itself to the threads list (so, using current interfaces - // we can't "fill" its TLAB), unless TLABs are disabled. - if (VerifyBeforeGC && !UseTLAB && - Universe::heap()->total_collections() >= VerifyGCStartAt) { - Universe::heap()->prepare_for_verify(); - Universe::verify(); // make sure we're starting with a clean slate - } } diff --git a/src/share/vm/runtime/init.cpp b/src/share/vm/runtime/init.cpp index 7ef17204b..62f295c7e 100644 --- a/src/share/vm/runtime/init.cpp +++ b/src/share/vm/runtime/init.cpp @@ -132,15 +132,6 @@ jint init_globals() { javaClasses_init(); // must happen after vtable initialization stubRoutines_init2(); // note: StubRoutines need 2-phase init - // Although we'd like to, we can't easily do a heap verify - // here because the main thread isn't yet a JavaThread, so - // its TLAB may not be made parseable from the usual interfaces. - if (VerifyBeforeGC && !UseTLAB && - Universe::heap()->total_collections() >= VerifyGCStartAt) { - Universe::heap()->prepare_for_verify(); - Universe::verify(); // make sure we're starting with a clean slate - } - // All the flags that get adjusted by VM_Version_init and os::init_2 // have been set so dump the flags now. if (PrintFlagsFinal) { diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index 322597fe4..577901a28 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -3423,12 +3423,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // real raw monitor. VM is setup enough here for raw monitor enter. JvmtiExport::transition_pending_onload_raw_monitors(); - if (VerifyBeforeGC && - Universe::heap()->total_collections() >= VerifyGCStartAt) { - Universe::heap()->prepare_for_verify(); - Universe::verify(); // make sure we're starting with a clean slate - } - // Fully start NMT MemTracker::start(); @@ -3452,6 +3446,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { } assert (Universe::is_fully_initialized(), "not initialized"); + if (VerifyBeforeGC && VerifyGCStartAt == 0) { + Universe::heap()->prepare_for_verify(); + Universe::verify(); // make sure we're starting with a clean slate + } + EXCEPTION_MARK; // At this point, the Universe is initialized, but we have not executed diff --git a/test/gc/TestVerifyBeforeGCDuringStartup.java b/test/gc/TestVerifyBeforeGCDuringStartup.java new file mode 100644 index 000000000..109e45e4b --- /dev/null +++ b/test/gc/TestVerifyBeforeGCDuringStartup.java @@ -0,0 +1,45 @@ +/* + * 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 TestVerifyBeforeGCDuringStartup.java + * @key gc + * @bug 8010463 + * @summary Simple test run with -XX:+VerifyBeforeGC -XX:-UseTLAB to verify 8010463 + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestVerifyBeforeGCDuringStartup { + public static void main(String args[]) throws Exception { + ProcessBuilder pb = + ProcessTools.createJavaProcessBuilder(System.getProperty("test.vm.opts"), + "-XX:-UseTLAB", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+VerifyBeforeGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("[Verifying"); + output.shouldHaveExitValue(0); + } +} -- GitLab