src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/BitMap.java
author erikj
Tue, 12 Sep 2017 19:03:39 +0200
changeset 47216 71c04702a3d5
parent 35217 hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/BitMap.java@ce4b5303a813
permissions -rw-r--r--
8187443: Forest Consolidation: Move files to unified layout Reviewed-by: darcy, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
     2
 * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
package sun.jvm.hotspot.utilities;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import sun.jvm.hotspot.debugger.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
/** Manages a bitmap of the specified bit size */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
public class BitMap {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
  public BitMap(int sizeInBits) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
    this.size = sizeInBits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
    int nofWords = sizeInWords();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
    data = new int[nofWords];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  public int size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
    return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  // Accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  public boolean at(int offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
      Assert.that(offset>=0 && offset < size(), "BitMap index out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    return Bits.isSetNthBit(wordFor(offset), offset % bitsPerWord);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  public void atPut(int offset, boolean value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    int index = indexFor(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
    int pos   = offset % bitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    if (value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
      data[index] = Bits.setNthBit(data[index], pos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
      data[index] = Bits.clearNthBit(data[index], pos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  public void set_size(int value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    size = value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  public void set_map(Address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    for (int i=0; i<sizeInWords(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      data[i] =  (int) addr.getCIntegerAt(0, bytesPerWord, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      addr = addr.addOffsetTo(bytesPerWord);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  public void clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    for (int i = 0; i < sizeInWords(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
      data[i] = Bits.NoBits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  public void iterate(BitMapClosure blk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    for (int index = 0; index < sizeInWords(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
      int rest = data[index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
      for (int offset = index * bitsPerWord; rest != Bits.NoBits; offset++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
        if (rest % 2 == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
          if (offset < size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
            blk.doBit(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
            return; // Passed end of map
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
        rest = rest >>> 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  /** Sets this bitmap to the logical union of it and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
      argument. Both bitmaps must be the same size. Returns true if a
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
      change was caused in this bitmap. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  public boolean setUnion(BitMap other) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
      Assert.that(size() == other.size(), "must have same size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    boolean changed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    for (int index = 0; index < sizeInWords(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      int temp = data[index] | other.data[index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      changed = changed || (temp != data[index]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
      data[index] = temp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    return changed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  /** Sets this bitmap to the logical intersection of it and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
      argument. Both bitmaps must be the same size. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  public void setIntersection(BitMap other) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
      Assert.that(size() == other.size(), "must have same size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    for (int index = 0; index < sizeInWords(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
      data[index] = data[index] & (other.data[index]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  /** Sets this bitmap to the contents of the argument. Both bitmaps
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
      must be the same size. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  public void setFrom(BitMap other) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
      Assert.that(size() == other.size(), "must have same size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    for (int index = 0; index < sizeInWords(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
      data[index] = other.data[index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  /** Sets this bitmap to the logical difference between it and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
      argument; that is, any bits that are set in the argument are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
      cleared in this bitmap. Both bitmaps must be the same size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
      Returns true if a change was caused in this bitmap. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  public boolean setDifference(BitMap other) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      Assert.that(size() == other.size(), "must have same size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    boolean changed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    for (int index = 0; index < sizeInWords(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      int temp = data[index] & ~(other.data[index]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
      changed = changed || (temp != data[index]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
      data[index] = temp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    return changed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  /** Both bitmaps must be the same size. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  public boolean isSame(BitMap other) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      Assert.that(size() == other.size(), "must have same size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    for (int index = 0; index < sizeInWords(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      if (data[index] != (other.data[index])) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  public int getNextOneOffset(int l_offset, int r_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    if (l_offset == r_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
      return l_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    int index = indexFor(l_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    int r_index = indexFor(r_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    int res_offset = l_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    int pos = bitInWord(res_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    int res = data[index] >> pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    if (res != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
      // find the position of the 1-bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
      for (; (res & 1) == 0; res_offset++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
        res = res >> 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      return res_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    // skip over all word length 0-bit runs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    for (index++; index < r_index; index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
      res = data[index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
      if (res != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
        // found a 1, return the offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
        for (res_offset = index * bitsPerWord; (res & 1) == 0; res_offset++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
          res = res >> 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
        return res_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    return r_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  //----------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  // Internals only below this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  private int   size; // in bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  private int[] data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  private static final int bitsPerWord = 32;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  private static final int bytesPerWord = 4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  private int sizeInWords() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    return (size() + bitsPerWord - 1) / bitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  private int indexFor(int offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    return offset / bitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  private int wordFor(int offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    return data[offset / bitsPerWord];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  private int bitInWord(int offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    return offset & (bitsPerWord - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
}