src/share/vm/opto/indexSet.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/opto/indexSet.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,577 @@
     1.4 +/*
     1.5 + * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "precompiled.hpp"
    1.29 +#include "memory/allocation.inline.hpp"
    1.30 +#include "opto/chaitin.hpp"
    1.31 +#include "opto/compile.hpp"
    1.32 +#include "opto/indexSet.hpp"
    1.33 +#include "opto/regmask.hpp"
    1.34 +
    1.35 +// This file defines the IndexSet class, a set of sparse integer indices.
    1.36 +// This data structure is used by the compiler in its liveness analysis and
    1.37 +// during register allocation.  It also defines an iterator for this class.
    1.38 +
    1.39 +//-------------------------------- Initializations ------------------------------
    1.40 +
    1.41 +IndexSet::BitBlock  IndexSet::_empty_block     = IndexSet::BitBlock();
    1.42 +
    1.43 +#ifdef ASSERT
    1.44 +// Initialize statistics counters
    1.45 +julong IndexSet::_alloc_new = 0;
    1.46 +julong IndexSet::_alloc_total = 0;
    1.47 +
    1.48 +julong IndexSet::_total_bits = 0;
    1.49 +julong IndexSet::_total_used_blocks = 0;
    1.50 +julong IndexSet::_total_unused_blocks = 0;
    1.51 +
    1.52 +// Per set, or all sets operation tracing
    1.53 +int IndexSet::_serial_count = 1;
    1.54 +#endif
    1.55 +
    1.56 +// What is the first set bit in a 5 bit integer?
    1.57 +const byte IndexSetIterator::_first_bit[32] = {
    1.58 +  0, 0, 1, 0,
    1.59 +  2, 0, 1, 0,
    1.60 +  3, 0, 1, 0,
    1.61 +  2, 0, 1, 0,
    1.62 +  4, 0, 1, 0,
    1.63 +  2, 0, 1, 0,
    1.64 +  3, 0, 1, 0,
    1.65 +  2, 0, 1, 0
    1.66 +};
    1.67 +
    1.68 +// What is the second set bit in a 5 bit integer?
    1.69 +const byte IndexSetIterator::_second_bit[32] = {
    1.70 +  5, 5, 5, 1,
    1.71 +  5, 2, 2, 1,
    1.72 +  5, 3, 3, 1,
    1.73 +  3, 2, 2, 1,
    1.74 +  5, 4, 4, 1,
    1.75 +  4, 2, 2, 1,
    1.76 +  4, 3, 3, 1,
    1.77 +  3, 2, 2, 1
    1.78 +};
    1.79 +
    1.80 +// I tried implementing the IndexSetIterator with a window_size of 8 and
    1.81 +// didn't seem to get a noticeable speedup.  I am leaving in the tables
    1.82 +// in case we want to switch back.
    1.83 +
    1.84 +/*const byte IndexSetIterator::_first_bit[256] = {
    1.85 +  8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.86 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.87 +  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.88 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.89 +  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.90 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.91 +  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.92 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.93 +  7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.94 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.95 +  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.96 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.97 +  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.98 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    1.99 +  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
   1.100 +  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
   1.101 +};
   1.102 +
   1.103 +const byte IndexSetIterator::_second_bit[256] = {
   1.104 +  8, 8, 8, 1, 8, 2, 2, 1, 8, 3, 3, 1, 3, 2, 2, 1,
   1.105 +  8, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.106 +  8, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
   1.107 +  5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.108 +  8, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1,
   1.109 +  6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.110 +  6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
   1.111 +  5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.112 +  8, 7, 7, 1, 7, 2, 2, 1, 7, 3, 3, 1, 3, 2, 2, 1,
   1.113 +  7, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.114 +  7, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
   1.115 +  5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.116 +  7, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1,
   1.117 +  6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
   1.118 +  6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
   1.119 +  5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1
   1.120 +};*/
   1.121 +
   1.122 +//---------------------------- IndexSet::populate_free_list() -----------------------------
   1.123 +// Populate the free BitBlock list with a batch of BitBlocks.  The BitBlocks
   1.124 +// are 32 bit aligned.
   1.125 +
   1.126 +void IndexSet::populate_free_list() {
   1.127 +  Compile *compile = Compile::current();
   1.128 +  BitBlock *free = (BitBlock*)compile->indexSet_free_block_list();
   1.129 +
   1.130 +  char *mem = (char*)arena()->Amalloc_4(sizeof(BitBlock) *
   1.131 +                                        bitblock_alloc_chunk_size + 32);
   1.132 +
   1.133 +  // Align the pointer to a 32 bit boundary.
   1.134 +  BitBlock *new_blocks = (BitBlock*)(((uintptr_t)mem + 32) & ~0x001F);
   1.135 +
   1.136 +  // Add the new blocks to the free list.
   1.137 +  for (int i = 0; i < bitblock_alloc_chunk_size; i++) {
   1.138 +    new_blocks->set_next(free);
   1.139 +    free = new_blocks;
   1.140 +    new_blocks++;
   1.141 +  }
   1.142 +
   1.143 +  compile->set_indexSet_free_block_list(free);
   1.144 +
   1.145 +#ifdef ASSERT
   1.146 +  if (CollectIndexSetStatistics) {
   1.147 +    inc_stat_counter(&_alloc_new, bitblock_alloc_chunk_size);
   1.148 +  }
   1.149 +#endif
   1.150 +}
   1.151 +
   1.152 +
   1.153 +//---------------------------- IndexSet::alloc_block() ------------------------
   1.154 +// Allocate a BitBlock from the free list.  If the free list is empty,
   1.155 +// prime it.
   1.156 +
   1.157 +IndexSet::BitBlock *IndexSet::alloc_block() {
   1.158 +#ifdef ASSERT
   1.159 +  if (CollectIndexSetStatistics) {
   1.160 +    inc_stat_counter(&_alloc_total, 1);
   1.161 +  }
   1.162 +#endif
   1.163 +  Compile *compile = Compile::current();
   1.164 +  BitBlock* free_list = (BitBlock*)compile->indexSet_free_block_list();
   1.165 +  if (free_list == NULL) {
   1.166 +    populate_free_list();
   1.167 +    free_list = (BitBlock*)compile->indexSet_free_block_list();
   1.168 +  }
   1.169 +  BitBlock *block = free_list;
   1.170 +  compile->set_indexSet_free_block_list(block->next());
   1.171 +
   1.172 +  block->clear();
   1.173 +  return block;
   1.174 +}
   1.175 +
   1.176 +//---------------------------- IndexSet::alloc_block_containing() -------------
   1.177 +// Allocate a new BitBlock and put it into the position in the _blocks array
   1.178 +// corresponding to element.
   1.179 +
   1.180 +IndexSet::BitBlock *IndexSet::alloc_block_containing(uint element) {
   1.181 +  BitBlock *block = alloc_block();
   1.182 +  uint bi = get_block_index(element);
   1.183 +  _blocks[bi] = block;
   1.184 +  return block;
   1.185 +}
   1.186 +
   1.187 +//---------------------------- IndexSet::free_block() -------------------------
   1.188 +// Add a BitBlock to the free list.
   1.189 +
   1.190 +void IndexSet::free_block(uint i) {
   1.191 +  debug_only(check_watch("free block", i));
   1.192 +  assert(i < _max_blocks, "block index too large");
   1.193 +  BitBlock *block = _blocks[i];
   1.194 +  assert(block != &_empty_block, "cannot free the empty block");
   1.195 +  block->set_next((IndexSet::BitBlock*)Compile::current()->indexSet_free_block_list());
   1.196 +  Compile::current()->set_indexSet_free_block_list(block);
   1.197 +  set_block(i,&_empty_block);
   1.198 +}
   1.199 +
   1.200 +//------------------------------lrg_union--------------------------------------
   1.201 +// Compute the union of all elements of one and two which interfere with
   1.202 +// the RegMask mask.  If the degree of the union becomes exceeds
   1.203 +// fail_degree, the union bails out.  The underlying set is cleared before
   1.204 +// the union is performed.
   1.205 +
   1.206 +uint IndexSet::lrg_union(uint lr1, uint lr2,
   1.207 +                         const uint fail_degree,
   1.208 +                         const PhaseIFG *ifg,
   1.209 +                         const RegMask &mask ) {
   1.210 +  IndexSet *one = ifg->neighbors(lr1);
   1.211 +  IndexSet *two = ifg->neighbors(lr2);
   1.212 +  LRG &lrg1 = ifg->lrgs(lr1);
   1.213 +  LRG &lrg2 = ifg->lrgs(lr2);
   1.214 +#ifdef ASSERT
   1.215 +  assert(_max_elements == one->_max_elements, "max element mismatch");
   1.216 +  check_watch("union destination");
   1.217 +  one->check_watch("union source");
   1.218 +  two->check_watch("union source");
   1.219 +#endif
   1.220 +
   1.221 +  // Compute the degree of the combined live-range.  The combined
   1.222 +  // live-range has the union of the original live-ranges' neighbors set as
   1.223 +  // well as the neighbors of all intermediate copies, minus those neighbors
   1.224 +  // that can not use the intersected allowed-register-set.
   1.225 +
   1.226 +  // Copy the larger set.  Insert the smaller set into the larger.
   1.227 +  if (two->count() > one->count()) {
   1.228 +    IndexSet *temp = one;
   1.229 +    one = two;
   1.230 +    two = temp;
   1.231 +  }
   1.232 +
   1.233 +  clear();
   1.234 +
   1.235 +  // Used to compute degree of register-only interferences.  Infinite-stack
   1.236 +  // neighbors do not alter colorability, as they can always color to some
   1.237 +  // other color.  (A variant of the Briggs assertion)
   1.238 +  uint reg_degree = 0;
   1.239 +
   1.240 +  uint element;
   1.241 +  // Load up the combined interference set with the neighbors of one
   1.242 +  IndexSetIterator elements(one);
   1.243 +  while ((element = elements.next()) != 0) {
   1.244 +    LRG &lrg = ifg->lrgs(element);
   1.245 +    if (mask.overlap(lrg.mask())) {
   1.246 +      insert(element);
   1.247 +      if( !lrg.mask().is_AllStack() ) {
   1.248 +        reg_degree += lrg1.compute_degree(lrg);
   1.249 +        if( reg_degree >= fail_degree ) return reg_degree;
   1.250 +      } else {
   1.251 +        // !!!!! Danger!  No update to reg_degree despite having a neighbor.
   1.252 +        // A variant of the Briggs assertion.
   1.253 +        // Not needed if I simplify during coalesce, ala George/Appel.
   1.254 +        assert( lrg.lo_degree(), "" );
   1.255 +      }
   1.256 +    }
   1.257 +  }
   1.258 +  // Add neighbors of two as well
   1.259 +  IndexSetIterator elements2(two);
   1.260 +  while ((element = elements2.next()) != 0) {
   1.261 +    LRG &lrg = ifg->lrgs(element);
   1.262 +    if (mask.overlap(lrg.mask())) {
   1.263 +      if (insert(element)) {
   1.264 +        if( !lrg.mask().is_AllStack() ) {
   1.265 +          reg_degree += lrg2.compute_degree(lrg);
   1.266 +          if( reg_degree >= fail_degree ) return reg_degree;
   1.267 +        } else {
   1.268 +          // !!!!! Danger!  No update to reg_degree despite having a neighbor.
   1.269 +          // A variant of the Briggs assertion.
   1.270 +          // Not needed if I simplify during coalesce, ala George/Appel.
   1.271 +          assert( lrg.lo_degree(), "" );
   1.272 +        }
   1.273 +      }
   1.274 +    }
   1.275 +  }
   1.276 +
   1.277 +  return reg_degree;
   1.278 +}
   1.279 +
   1.280 +//---------------------------- IndexSet() -----------------------------
   1.281 +// A deep copy constructor.  This is used when you need a scratch copy of this set.
   1.282 +
   1.283 +IndexSet::IndexSet (IndexSet *set) {
   1.284 +#ifdef ASSERT
   1.285 +  _serial_number = _serial_count++;
   1.286 +  set->check_watch("copied", _serial_number);
   1.287 +  check_watch("initialized by copy", set->_serial_number);
   1.288 +  _max_elements = set->_max_elements;
   1.289 +#endif
   1.290 +  _count = set->_count;
   1.291 +  _max_blocks = set->_max_blocks;
   1.292 +  if (_max_blocks <= preallocated_block_list_size) {
   1.293 +    _blocks = _preallocated_block_list;
   1.294 +  } else {
   1.295 +    _blocks =
   1.296 +      (IndexSet::BitBlock**) arena()->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
   1.297 +  }
   1.298 +  for (uint i = 0; i < _max_blocks; i++) {
   1.299 +    BitBlock *block = set->_blocks[i];
   1.300 +    if (block == &_empty_block) {
   1.301 +      set_block(i, &_empty_block);
   1.302 +    } else {
   1.303 +      BitBlock *new_block = alloc_block();
   1.304 +      memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block);
   1.305 +      set_block(i, new_block);
   1.306 +    }
   1.307 +  }
   1.308 +}
   1.309 +
   1.310 +//---------------------------- IndexSet::initialize() -----------------------------
   1.311 +// Prepare an IndexSet for use.
   1.312 +
   1.313 +void IndexSet::initialize(uint max_elements) {
   1.314 +#ifdef ASSERT
   1.315 +  _serial_number = _serial_count++;
   1.316 +  check_watch("initialized", max_elements);
   1.317 +  _max_elements = max_elements;
   1.318 +#endif
   1.319 +  _count = 0;
   1.320 +  _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
   1.321 +
   1.322 +  if (_max_blocks <= preallocated_block_list_size) {
   1.323 +    _blocks = _preallocated_block_list;
   1.324 +  } else {
   1.325 +    _blocks = (IndexSet::BitBlock**) arena()->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
   1.326 +  }
   1.327 +  for (uint i = 0; i < _max_blocks; i++) {
   1.328 +    set_block(i, &_empty_block);
   1.329 +  }
   1.330 +}
   1.331 +
   1.332 +//---------------------------- IndexSet::initialize()------------------------------
   1.333 +// Prepare an IndexSet for use.  If it needs to allocate its _blocks array, it does
   1.334 +// so from the Arena passed as a parameter.  BitBlock allocation is still done from
   1.335 +// the static Arena which was set with reset_memory().
   1.336 +
   1.337 +void IndexSet::initialize(uint max_elements, Arena *arena) {
   1.338 +#ifdef ASSERT
   1.339 +  _serial_number = _serial_count++;
   1.340 +  check_watch("initialized2", max_elements);
   1.341 +  _max_elements = max_elements;
   1.342 +#endif // ASSERT
   1.343 +  _count = 0;
   1.344 +  _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
   1.345 +
   1.346 +  if (_max_blocks <= preallocated_block_list_size) {
   1.347 +    _blocks = _preallocated_block_list;
   1.348 +  } else {
   1.349 +    _blocks = (IndexSet::BitBlock**) arena->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
   1.350 +  }
   1.351 +  for (uint i = 0; i < _max_blocks; i++) {
   1.352 +    set_block(i, &_empty_block);
   1.353 +  }
   1.354 +}
   1.355 +
   1.356 +//---------------------------- IndexSet::swap() -----------------------------
   1.357 +// Exchange two IndexSets.
   1.358 +
   1.359 +void IndexSet::swap(IndexSet *set) {
   1.360 +#ifdef ASSERT
   1.361 +  assert(_max_elements == set->_max_elements, "must have same universe size to swap");
   1.362 +  check_watch("swap", set->_serial_number);
   1.363 +  set->check_watch("swap", _serial_number);
   1.364 +#endif
   1.365 +
   1.366 +  for (uint i = 0; i < _max_blocks; i++) {
   1.367 +    BitBlock *temp = _blocks[i];
   1.368 +    set_block(i, set->_blocks[i]);
   1.369 +    set->set_block(i, temp);
   1.370 +  }
   1.371 +  uint temp = _count;
   1.372 +  _count = set->_count;
   1.373 +  set->_count = temp;
   1.374 +}
   1.375 +
   1.376 +//---------------------------- IndexSet::dump() -----------------------------
   1.377 +// Print this set.  Used for debugging.
   1.378 +
   1.379 +#ifndef PRODUCT
   1.380 +void IndexSet::dump() const {
   1.381 +  IndexSetIterator elements(this);
   1.382 +
   1.383 +  tty->print("{");
   1.384 +  uint i;
   1.385 +  while ((i = elements.next()) != 0) {
   1.386 +    tty->print("L%d ", i);
   1.387 +  }
   1.388 +  tty->print_cr("}");
   1.389 +}
   1.390 +#endif
   1.391 +
   1.392 +#ifdef ASSERT
   1.393 +//---------------------------- IndexSet::tally_iteration_statistics() -----------------------------
   1.394 +// Update block/bit counts to reflect that this set has been iterated over.
   1.395 +
   1.396 +void IndexSet::tally_iteration_statistics() const {
   1.397 +  inc_stat_counter(&_total_bits, count());
   1.398 +
   1.399 +  for (uint i = 0; i < _max_blocks; i++) {
   1.400 +    if (_blocks[i] != &_empty_block) {
   1.401 +      inc_stat_counter(&_total_used_blocks, 1);
   1.402 +    } else {
   1.403 +      inc_stat_counter(&_total_unused_blocks, 1);
   1.404 +    }
   1.405 +  }
   1.406 +}
   1.407 +
   1.408 +//---------------------------- IndexSet::print_statistics() -----------------------------
   1.409 +// Print statistics about IndexSet usage.
   1.410 +
   1.411 +void IndexSet::print_statistics() {
   1.412 +  julong total_blocks = _total_used_blocks + _total_unused_blocks;
   1.413 +  tty->print_cr ("Accumulated IndexSet usage statistics:");
   1.414 +  tty->print_cr ("--------------------------------------");
   1.415 +  tty->print_cr ("  Iteration:");
   1.416 +  tty->print_cr ("    blocks visited: " UINT64_FORMAT, total_blocks);
   1.417 +  tty->print_cr ("    blocks empty: %4.2f%%", 100.0*(double)_total_unused_blocks/total_blocks);
   1.418 +  tty->print_cr ("    bit density (bits/used blocks): %4.2f", (double)_total_bits/_total_used_blocks);
   1.419 +  tty->print_cr ("    bit density (bits/all blocks): %4.2f", (double)_total_bits/total_blocks);
   1.420 +  tty->print_cr ("  Allocation:");
   1.421 +  tty->print_cr ("    blocks allocated: " UINT64_FORMAT, _alloc_new);
   1.422 +  tty->print_cr ("    blocks used/reused: " UINT64_FORMAT, _alloc_total);
   1.423 +}
   1.424 +
   1.425 +//---------------------------- IndexSet::verify() -----------------------------
   1.426 +// Expensive test of IndexSet sanity.  Ensure that the count agrees with the
   1.427 +// number of bits in the blocks.  Make sure the iterator is seeing all elements
   1.428 +// of the set.  Meant for use during development.
   1.429 +
   1.430 +void IndexSet::verify() const {
   1.431 +  assert(!member(0), "zero cannot be a member");
   1.432 +  uint count = 0;
   1.433 +  uint i;
   1.434 +  for (i = 1; i < _max_elements; i++) {
   1.435 +    if (member(i)) {
   1.436 +      count++;
   1.437 +      assert(count <= _count, "_count is messed up");
   1.438 +    }
   1.439 +  }
   1.440 +
   1.441 +  IndexSetIterator elements(this);
   1.442 +  count = 0;
   1.443 +  while ((i = elements.next()) != 0) {
   1.444 +    count++;
   1.445 +    assert(member(i), "returned a non member");
   1.446 +    assert(count <= _count, "iterator returned wrong number of elements");
   1.447 +  }
   1.448 +}
   1.449 +#endif
   1.450 +
   1.451 +//---------------------------- IndexSetIterator() -----------------------------
   1.452 +// Create an iterator for a set.  If empty blocks are detected when iterating
   1.453 +// over the set, these blocks are replaced.
   1.454 +
   1.455 +IndexSetIterator::IndexSetIterator(IndexSet *set) {
   1.456 +#ifdef ASSERT
   1.457 +  if (CollectIndexSetStatistics) {
   1.458 +    set->tally_iteration_statistics();
   1.459 +  }
   1.460 +  set->check_watch("traversed", set->count());
   1.461 +#endif
   1.462 +  if (set->is_empty()) {
   1.463 +    _current = 0;
   1.464 +    _next_word = IndexSet::words_per_block;
   1.465 +    _next_block = 1;
   1.466 +    _max_blocks = 1;
   1.467 +
   1.468 +    // We don't need the following values when we iterate over an empty set.
   1.469 +    // The commented out code is left here to document that the omission
   1.470 +    // is intentional.
   1.471 +    //
   1.472 +    //_value = 0;
   1.473 +    //_words = NULL;
   1.474 +    //_blocks = NULL;
   1.475 +    //_set = NULL;
   1.476 +  } else {
   1.477 +    _current = 0;
   1.478 +    _value = 0;
   1.479 +    _next_block = 0;
   1.480 +    _next_word = IndexSet::words_per_block;
   1.481 +
   1.482 +    _max_blocks = set->_max_blocks;
   1.483 +    _words = NULL;
   1.484 +    _blocks = set->_blocks;
   1.485 +    _set = set;
   1.486 +  }
   1.487 +}
   1.488 +
   1.489 +//---------------------------- IndexSetIterator(const) -----------------------------
   1.490 +// Iterate over a constant IndexSet.
   1.491 +
   1.492 +IndexSetIterator::IndexSetIterator(const IndexSet *set) {
   1.493 +#ifdef ASSERT
   1.494 +  if (CollectIndexSetStatistics) {
   1.495 +    set->tally_iteration_statistics();
   1.496 +  }
   1.497 +  // We don't call check_watch from here to avoid bad recursion.
   1.498 +  //   set->check_watch("traversed const", set->count());
   1.499 +#endif
   1.500 +  if (set->is_empty()) {
   1.501 +    _current = 0;
   1.502 +    _next_word = IndexSet::words_per_block;
   1.503 +    _next_block = 1;
   1.504 +    _max_blocks = 1;
   1.505 +
   1.506 +    // We don't need the following values when we iterate over an empty set.
   1.507 +    // The commented out code is left here to document that the omission
   1.508 +    // is intentional.
   1.509 +    //
   1.510 +    //_value = 0;
   1.511 +    //_words = NULL;
   1.512 +    //_blocks = NULL;
   1.513 +    //_set = NULL;
   1.514 +  } else {
   1.515 +    _current = 0;
   1.516 +    _value = 0;
   1.517 +    _next_block = 0;
   1.518 +    _next_word = IndexSet::words_per_block;
   1.519 +
   1.520 +    _max_blocks = set->_max_blocks;
   1.521 +    _words = NULL;
   1.522 +    _blocks = set->_blocks;
   1.523 +    _set = NULL;
   1.524 +  }
   1.525 +}
   1.526 +
   1.527 +//---------------------------- List16Iterator::advance_and_next() -----------------------------
   1.528 +// Advance to the next non-empty word in the set being iterated over.  Return the next element
   1.529 +// if there is one.  If we are done, return 0.  This method is called from the next() method
   1.530 +// when it gets done with a word.
   1.531 +
   1.532 +uint IndexSetIterator::advance_and_next() {
   1.533 +  // See if there is another non-empty word in the current block.
   1.534 +  for (uint wi = _next_word; wi < (unsigned)IndexSet::words_per_block; wi++) {
   1.535 +    if (_words[wi] != 0) {
   1.536 +      // Found a non-empty word.
   1.537 +      _value = ((_next_block - 1) * IndexSet::bits_per_block) + (wi * IndexSet::bits_per_word);
   1.538 +      _current = _words[wi];
   1.539 +
   1.540 +      _next_word = wi+1;
   1.541 +
   1.542 +      return next();
   1.543 +    }
   1.544 +  }
   1.545 +
   1.546 +  // We ran out of words in the current block.  Advance to next non-empty block.
   1.547 +  for (uint bi = _next_block; bi < _max_blocks; bi++) {
   1.548 +    if (_blocks[bi] != &IndexSet::_empty_block) {
   1.549 +      // Found a non-empty block.
   1.550 +
   1.551 +      _words = _blocks[bi]->words();
   1.552 +      for (uint wi = 0; wi < (unsigned)IndexSet::words_per_block; wi++) {
   1.553 +        if (_words[wi] != 0) {
   1.554 +          // Found a non-empty word.
   1.555 +          _value = (bi * IndexSet::bits_per_block) + (wi * IndexSet::bits_per_word);
   1.556 +          _current = _words[wi];
   1.557 +
   1.558 +          _next_block = bi+1;
   1.559 +          _next_word = wi+1;
   1.560 +
   1.561 +          return next();
   1.562 +        }
   1.563 +      }
   1.564 +
   1.565 +      // All of the words in the block were empty.  Replace
   1.566 +      // the block with the empty block.
   1.567 +      if (_set) {
   1.568 +        _set->free_block(bi);
   1.569 +      }
   1.570 +    }
   1.571 +  }
   1.572 +
   1.573 +  // These assignments make redundant calls to next on a finished iterator
   1.574 +  // faster.  Probably not necessary.
   1.575 +  _next_block = _max_blocks;
   1.576 +  _next_word = IndexSet::words_per_block;
   1.577 +
   1.578 +  // No more words.
   1.579 +  return 0;
   1.580 +}

mercurial