8218743: SA: Add support for large bitmaps
authorstefank
Tue, 19 Feb 2019 10:02:54 +0100
changeset 53812 1199185efca1
parent 53811 935d31867930
child 53813 d90512958e44
8218743: SA: Add support for large bitmaps Reviewed-by: eosterlund, jgeorge
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/BitMapInterface.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/BitMapSegmented.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/MarkBits.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java	Tue Feb 19 10:02:42 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java	Tue Feb 19 10:02:54 2019 +0100
@@ -31,6 +31,8 @@
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.BitMapInterface;
+import sun.jvm.hotspot.utilities.BitMapSegmented;
 
 public abstract class CollectedHeap extends VMObject {
   private static long         reservedFieldOffset;
@@ -93,4 +95,8 @@
     tty.println("unknown subtype of CollectedHeap @ " + getAddress() + " (" +
                 mr.start() + "," + mr.end() + ")");
   }
+
+  public BitMapInterface createBitMap(long bits) {
+    return new BitMapSegmented(bits);
+  }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/BitMapInterface.java	Tue Feb 19 10:02:54 2019 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+/** Minimal bitmap interface to support bitmaps spanning more than Integer.MAX_VALUE bits. */
+public interface BitMapInterface {
+  public boolean at(long offset);
+  public void atPut(long offset, boolean value);
+  public void clear();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/BitMapSegmented.java	Tue Feb 19 10:02:54 2019 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+/** A BitMap implementing the BitMapInterface. */
+public class BitMapSegmented implements BitMapInterface {
+  private static final int SegmentSizeBits = 30;
+  private static final int SegmentSize = 1 << (SegmentSizeBits - 1);
+
+  public BitMapSegmented(long sizeInBits) {
+    this.size = sizeInBits;
+
+    if (sizeInBits == 0) {
+      segmentBitMaps = new BitMap[0];
+      return;
+    }
+
+    int lastSegmentSize = (int)(sizeInBits % SegmentSize);
+
+    int segments = segmentIndex(sizeInBits - 1) + 1;
+    int completeSegments = segments - ((lastSegmentSize != 0) ? 1 : 0);
+
+    segmentBitMaps = new BitMap[segments];
+
+    for (int i = 0; i < completeSegments; i++) {
+      segmentBitMaps[i] = new BitMap(SegmentSize);
+    }
+
+    if (lastSegmentSize != 0) {
+      segmentBitMaps[completeSegments] = new BitMap(lastSegmentSize);
+    }
+  }
+
+  public long size() {
+    return size;
+  }
+
+  // Accessors
+  public boolean at(long offset) {
+    assert offset < size;
+
+    int segmentIndex = segmentIndex(offset);
+    int segmentOffset = segmentOffset(offset);
+    return segmentBitMaps[segmentIndex].at(segmentOffset);
+  }
+
+  public void atPut(long offset, boolean value) {
+    assert offset < size;
+
+    int segmentIndex = segmentIndex(offset);
+    int segmentOffset = segmentOffset(offset);
+    segmentBitMaps[segmentIndex].atPut(segmentOffset, value);
+  }
+
+  public void clear() {
+    for (BitMap map : segmentBitMaps) {
+      map.clear();
+    }
+  }
+
+  //----------------------------------------------------------------------
+  // Internals only below this point
+  //
+  private final long     size; // in bits
+  private final BitMap[] segmentBitMaps;
+
+  private int segmentIndex(long offset) {
+    long longIndex = offset / SegmentSize;
+
+    assert longIndex < Integer.MAX_VALUE;
+    return (int)longIndex;
+  }
+
+  private int segmentOffset(long offset) {
+    return (int)(offset % SegmentSize);
+  }
+}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/MarkBits.java	Tue Feb 19 10:02:42 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/MarkBits.java	Tue Feb 19 10:02:54 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -41,8 +41,7 @@
     start = reserved.start();
     end   = reserved.end();
     long numOopHandles = end.minus(start) / VM.getVM().getOopSize();
-    // FIXME: will have trouble with larger heap sizes
-    bits = new BitMap((int) numOopHandles);
+    bits = heap.createBitMap(numOopHandles);
   }
 
   public void clear() {
@@ -60,34 +59,22 @@
     }
 
     OopHandle handle = obj.getHandle();
-    // FIXME: will have trouble with larger heap sizes
     long idx = handle.minus(start) / VM.getVM().getOopSize();
-    if ((idx < 0) || (idx >= bits.size())) {
-      System.err.println("MarkBits: WARNING: object " + handle + " outside of heap, ignoring");
-      return false;
-    }
-    int intIdx = (int) idx;
-    if (bits.at(intIdx)) {
+    if (bits.at(idx)) {
       return false; // already marked
     }
-    bits.atPut(intIdx, true);
+    bits.atPut(idx, true);
     return true;
   }
 
   /** Forces clearing of a given mark bit. */
   public void clear(Oop obj) {
     OopHandle handle = obj.getHandle();
-    // FIXME: will have trouble with larger heap sizes
     long idx = handle.minus(start) / VM.getVM().getOopSize();
-    if ((idx < 0) || (idx >= bits.size())) {
-      System.err.println("MarkBits: WARNING: object " + handle + " outside of heap, ignoring");
-      return;
-    }
-    int intIdx = (int) idx;
-    bits.atPut(intIdx, false);
+    bits.atPut(idx, false);
   }
 
-  private BitMap  bits;
+  private BitMapInterface bits;
   private Address start;
   private Address end;
 }