8059066: CardTableModRefBS might commit the same page twice
authorehelin
Tue, 02 Dec 2014 09:53:30 +0100
changeset 28026 3694b71eef6c
parent 28025 3126963e1b1e
child 28028 2bea2086693d
8059066: CardTableModRefBS might commit the same page twice Reviewed-by: tschatzl, kbarrett, jmasa
hotspot/src/share/vm/memory/cardTableModRefBS.cpp
hotspot/test/gc/TestCardTablePageCommits.java
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Thu Dec 04 09:43:12 2014 +0000
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Tue Dec 02 09:53:30 2014 +0100
@@ -275,29 +275,26 @@
     // the new_end_aligned does not intrude onto the committed
     // space of another region.
     int ri = 0;
-    for (ri = 0; ri < _cur_covered_regions; ri++) {
-      if (ri != ind) {
-        if (_committed[ri].contains(new_end_aligned)) {
-          // The prior check included in the assert
-          // (new_end_aligned >= _committed[ri].start())
-          // is redundant with the "contains" test.
-          // Any region containing the new end
-          // should start at or beyond the region found (ind)
-          // for the new end (committed regions are not expected to
-          // be proper subsets of other committed regions).
-          assert(_committed[ri].start() >= _committed[ind].start(),
-                 "New end of committed region is inconsistent");
-          new_end_aligned = _committed[ri].start();
-          // new_end_aligned can be equal to the start of its
-          // committed region (i.e., of "ind") if a second
-          // region following "ind" also start at the same location
-          // as "ind".
-          assert(new_end_aligned >= _committed[ind].start(),
-            "New end of committed region is before start");
-          debug_only(collided = true;)
-          // Should only collide with 1 region
-          break;
-        }
+    for (ri = ind + 1; ri < _cur_covered_regions; ri++) {
+      if (new_end_aligned > _committed[ri].start()) {
+        assert(new_end_aligned <= _committed[ri].end(),
+               "An earlier committed region can't cover a later committed region");
+        // Any region containing the new end
+        // should start at or beyond the region found (ind)
+        // for the new end (committed regions are not expected to
+        // be proper subsets of other committed regions).
+        assert(_committed[ri].start() >= _committed[ind].start(),
+               "New end of committed region is inconsistent");
+        new_end_aligned = _committed[ri].start();
+        // new_end_aligned can be equal to the start of its
+        // committed region (i.e., of "ind") if a second
+        // region following "ind" also start at the same location
+        // as "ind".
+        assert(new_end_aligned >= _committed[ind].start(),
+          "New end of committed region is before start");
+        debug_only(collided = true;)
+        // Should only collide with 1 region
+        break;
       }
     }
 #ifdef ASSERT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/TestCardTablePageCommits.java	Tue Dec 02 09:53:30 2014 +0100
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 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
+* 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.
+*/
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.Platform;
+
+/*
+ * @test TestCardTablePageCommits
+ * @key gc
+ * @bug 8059066
+ * @summary Tests that the card table does not commit the same page twice
+ * @library /testlibrary
+ * @run driver TestCardTablePageCommits
+ */
+public class TestCardTablePageCommits {
+    public static void main(String args[]) throws Exception {
+        // The test is run with a small heap to make sure all pages in the card
+        // table gets committed. Need 8 MB heap to trigger the bug on SPARC
+        // because of 8kB pages, assume 4 KB pages for all other CPUs.
+        String Xmx = Platform.isSparc() ? "-Xmx8m" : "-Xmx4m";
+
+        String[] opts = {Xmx, "-XX:NativeMemoryTracking=detail", "-XX:+UseParallelGC", "-version"};
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(opts);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+}