src/share/vm/opto/indexSet.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "memory/allocation.inline.hpp"
aoqi@0 27 #include "opto/chaitin.hpp"
aoqi@0 28 #include "opto/compile.hpp"
aoqi@0 29 #include "opto/indexSet.hpp"
aoqi@0 30 #include "opto/regmask.hpp"
aoqi@0 31
aoqi@0 32 // This file defines the IndexSet class, a set of sparse integer indices.
aoqi@0 33 // This data structure is used by the compiler in its liveness analysis and
aoqi@0 34 // during register allocation. It also defines an iterator for this class.
aoqi@0 35
aoqi@0 36 //-------------------------------- Initializations ------------------------------
aoqi@0 37
aoqi@0 38 IndexSet::BitBlock IndexSet::_empty_block = IndexSet::BitBlock();
aoqi@0 39
aoqi@0 40 #ifdef ASSERT
aoqi@0 41 // Initialize statistics counters
aoqi@0 42 julong IndexSet::_alloc_new = 0;
aoqi@0 43 julong IndexSet::_alloc_total = 0;
aoqi@0 44
aoqi@0 45 julong IndexSet::_total_bits = 0;
aoqi@0 46 julong IndexSet::_total_used_blocks = 0;
aoqi@0 47 julong IndexSet::_total_unused_blocks = 0;
aoqi@0 48
aoqi@0 49 // Per set, or all sets operation tracing
aoqi@0 50 int IndexSet::_serial_count = 1;
aoqi@0 51 #endif
aoqi@0 52
aoqi@0 53 // What is the first set bit in a 5 bit integer?
aoqi@0 54 const byte IndexSetIterator::_first_bit[32] = {
aoqi@0 55 0, 0, 1, 0,
aoqi@0 56 2, 0, 1, 0,
aoqi@0 57 3, 0, 1, 0,
aoqi@0 58 2, 0, 1, 0,
aoqi@0 59 4, 0, 1, 0,
aoqi@0 60 2, 0, 1, 0,
aoqi@0 61 3, 0, 1, 0,
aoqi@0 62 2, 0, 1, 0
aoqi@0 63 };
aoqi@0 64
aoqi@0 65 // What is the second set bit in a 5 bit integer?
aoqi@0 66 const byte IndexSetIterator::_second_bit[32] = {
aoqi@0 67 5, 5, 5, 1,
aoqi@0 68 5, 2, 2, 1,
aoqi@0 69 5, 3, 3, 1,
aoqi@0 70 3, 2, 2, 1,
aoqi@0 71 5, 4, 4, 1,
aoqi@0 72 4, 2, 2, 1,
aoqi@0 73 4, 3, 3, 1,
aoqi@0 74 3, 2, 2, 1
aoqi@0 75 };
aoqi@0 76
aoqi@0 77 // I tried implementing the IndexSetIterator with a window_size of 8 and
aoqi@0 78 // didn't seem to get a noticeable speedup. I am leaving in the tables
aoqi@0 79 // in case we want to switch back.
aoqi@0 80
aoqi@0 81 /*const byte IndexSetIterator::_first_bit[256] = {
aoqi@0 82 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 83 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 84 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 85 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 86 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 87 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 88 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 89 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 90 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 91 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 92 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 93 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 94 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 95 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 96 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
aoqi@0 97 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
aoqi@0 98 };
aoqi@0 99
aoqi@0 100 const byte IndexSetIterator::_second_bit[256] = {
aoqi@0 101 8, 8, 8, 1, 8, 2, 2, 1, 8, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 102 8, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 103 8, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 104 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 105 8, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 106 6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 107 6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 108 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 109 8, 7, 7, 1, 7, 2, 2, 1, 7, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 110 7, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 111 7, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 112 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 113 7, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 114 6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 115 6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
aoqi@0 116 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1
aoqi@0 117 };*/
aoqi@0 118
aoqi@0 119 //---------------------------- IndexSet::populate_free_list() -----------------------------
aoqi@0 120 // Populate the free BitBlock list with a batch of BitBlocks. The BitBlocks
aoqi@0 121 // are 32 bit aligned.
aoqi@0 122
aoqi@0 123 void IndexSet::populate_free_list() {
aoqi@0 124 Compile *compile = Compile::current();
aoqi@0 125 BitBlock *free = (BitBlock*)compile->indexSet_free_block_list();
aoqi@0 126
aoqi@0 127 char *mem = (char*)arena()->Amalloc_4(sizeof(BitBlock) *
aoqi@0 128 bitblock_alloc_chunk_size + 32);
aoqi@0 129
aoqi@0 130 // Align the pointer to a 32 bit boundary.
aoqi@0 131 BitBlock *new_blocks = (BitBlock*)(((uintptr_t)mem + 32) & ~0x001F);
aoqi@0 132
aoqi@0 133 // Add the new blocks to the free list.
aoqi@0 134 for (int i = 0; i < bitblock_alloc_chunk_size; i++) {
aoqi@0 135 new_blocks->set_next(free);
aoqi@0 136 free = new_blocks;
aoqi@0 137 new_blocks++;
aoqi@0 138 }
aoqi@0 139
aoqi@0 140 compile->set_indexSet_free_block_list(free);
aoqi@0 141
aoqi@0 142 #ifdef ASSERT
aoqi@0 143 if (CollectIndexSetStatistics) {
aoqi@0 144 inc_stat_counter(&_alloc_new, bitblock_alloc_chunk_size);
aoqi@0 145 }
aoqi@0 146 #endif
aoqi@0 147 }
aoqi@0 148
aoqi@0 149
aoqi@0 150 //---------------------------- IndexSet::alloc_block() ------------------------
aoqi@0 151 // Allocate a BitBlock from the free list. If the free list is empty,
aoqi@0 152 // prime it.
aoqi@0 153
aoqi@0 154 IndexSet::BitBlock *IndexSet::alloc_block() {
aoqi@0 155 #ifdef ASSERT
aoqi@0 156 if (CollectIndexSetStatistics) {
aoqi@0 157 inc_stat_counter(&_alloc_total, 1);
aoqi@0 158 }
aoqi@0 159 #endif
aoqi@0 160 Compile *compile = Compile::current();
aoqi@0 161 BitBlock* free_list = (BitBlock*)compile->indexSet_free_block_list();
aoqi@0 162 if (free_list == NULL) {
aoqi@0 163 populate_free_list();
aoqi@0 164 free_list = (BitBlock*)compile->indexSet_free_block_list();
aoqi@0 165 }
aoqi@0 166 BitBlock *block = free_list;
aoqi@0 167 compile->set_indexSet_free_block_list(block->next());
aoqi@0 168
aoqi@0 169 block->clear();
aoqi@0 170 return block;
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 //---------------------------- IndexSet::alloc_block_containing() -------------
aoqi@0 174 // Allocate a new BitBlock and put it into the position in the _blocks array
aoqi@0 175 // corresponding to element.
aoqi@0 176
aoqi@0 177 IndexSet::BitBlock *IndexSet::alloc_block_containing(uint element) {
aoqi@0 178 BitBlock *block = alloc_block();
aoqi@0 179 uint bi = get_block_index(element);
aoqi@0 180 _blocks[bi] = block;
aoqi@0 181 return block;
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 //---------------------------- IndexSet::free_block() -------------------------
aoqi@0 185 // Add a BitBlock to the free list.
aoqi@0 186
aoqi@0 187 void IndexSet::free_block(uint i) {
aoqi@0 188 debug_only(check_watch("free block", i));
aoqi@0 189 assert(i < _max_blocks, "block index too large");
aoqi@0 190 BitBlock *block = _blocks[i];
aoqi@0 191 assert(block != &_empty_block, "cannot free the empty block");
aoqi@0 192 block->set_next((IndexSet::BitBlock*)Compile::current()->indexSet_free_block_list());
aoqi@0 193 Compile::current()->set_indexSet_free_block_list(block);
aoqi@0 194 set_block(i,&_empty_block);
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 //------------------------------lrg_union--------------------------------------
aoqi@0 198 // Compute the union of all elements of one and two which interfere with
aoqi@0 199 // the RegMask mask. If the degree of the union becomes exceeds
aoqi@0 200 // fail_degree, the union bails out. The underlying set is cleared before
aoqi@0 201 // the union is performed.
aoqi@0 202
aoqi@0 203 uint IndexSet::lrg_union(uint lr1, uint lr2,
aoqi@0 204 const uint fail_degree,
aoqi@0 205 const PhaseIFG *ifg,
aoqi@0 206 const RegMask &mask ) {
aoqi@0 207 IndexSet *one = ifg->neighbors(lr1);
aoqi@0 208 IndexSet *two = ifg->neighbors(lr2);
aoqi@0 209 LRG &lrg1 = ifg->lrgs(lr1);
aoqi@0 210 LRG &lrg2 = ifg->lrgs(lr2);
aoqi@0 211 #ifdef ASSERT
aoqi@0 212 assert(_max_elements == one->_max_elements, "max element mismatch");
aoqi@0 213 check_watch("union destination");
aoqi@0 214 one->check_watch("union source");
aoqi@0 215 two->check_watch("union source");
aoqi@0 216 #endif
aoqi@0 217
aoqi@0 218 // Compute the degree of the combined live-range. The combined
aoqi@0 219 // live-range has the union of the original live-ranges' neighbors set as
aoqi@0 220 // well as the neighbors of all intermediate copies, minus those neighbors
aoqi@0 221 // that can not use the intersected allowed-register-set.
aoqi@0 222
aoqi@0 223 // Copy the larger set. Insert the smaller set into the larger.
aoqi@0 224 if (two->count() > one->count()) {
aoqi@0 225 IndexSet *temp = one;
aoqi@0 226 one = two;
aoqi@0 227 two = temp;
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 clear();
aoqi@0 231
aoqi@0 232 // Used to compute degree of register-only interferences. Infinite-stack
aoqi@0 233 // neighbors do not alter colorability, as they can always color to some
aoqi@0 234 // other color. (A variant of the Briggs assertion)
aoqi@0 235 uint reg_degree = 0;
aoqi@0 236
aoqi@0 237 uint element;
aoqi@0 238 // Load up the combined interference set with the neighbors of one
aoqi@0 239 IndexSetIterator elements(one);
aoqi@0 240 while ((element = elements.next()) != 0) {
aoqi@0 241 LRG &lrg = ifg->lrgs(element);
aoqi@0 242 if (mask.overlap(lrg.mask())) {
aoqi@0 243 insert(element);
aoqi@0 244 if( !lrg.mask().is_AllStack() ) {
aoqi@0 245 reg_degree += lrg1.compute_degree(lrg);
aoqi@0 246 if( reg_degree >= fail_degree ) return reg_degree;
aoqi@0 247 } else {
aoqi@0 248 // !!!!! Danger! No update to reg_degree despite having a neighbor.
aoqi@0 249 // A variant of the Briggs assertion.
aoqi@0 250 // Not needed if I simplify during coalesce, ala George/Appel.
aoqi@0 251 assert( lrg.lo_degree(), "" );
aoqi@0 252 }
aoqi@0 253 }
aoqi@0 254 }
aoqi@0 255 // Add neighbors of two as well
aoqi@0 256 IndexSetIterator elements2(two);
aoqi@0 257 while ((element = elements2.next()) != 0) {
aoqi@0 258 LRG &lrg = ifg->lrgs(element);
aoqi@0 259 if (mask.overlap(lrg.mask())) {
aoqi@0 260 if (insert(element)) {
aoqi@0 261 if( !lrg.mask().is_AllStack() ) {
aoqi@0 262 reg_degree += lrg2.compute_degree(lrg);
aoqi@0 263 if( reg_degree >= fail_degree ) return reg_degree;
aoqi@0 264 } else {
aoqi@0 265 // !!!!! Danger! No update to reg_degree despite having a neighbor.
aoqi@0 266 // A variant of the Briggs assertion.
aoqi@0 267 // Not needed if I simplify during coalesce, ala George/Appel.
aoqi@0 268 assert( lrg.lo_degree(), "" );
aoqi@0 269 }
aoqi@0 270 }
aoqi@0 271 }
aoqi@0 272 }
aoqi@0 273
aoqi@0 274 return reg_degree;
aoqi@0 275 }
aoqi@0 276
aoqi@0 277 //---------------------------- IndexSet() -----------------------------
aoqi@0 278 // A deep copy constructor. This is used when you need a scratch copy of this set.
aoqi@0 279
aoqi@0 280 IndexSet::IndexSet (IndexSet *set) {
aoqi@0 281 #ifdef ASSERT
aoqi@0 282 _serial_number = _serial_count++;
aoqi@0 283 set->check_watch("copied", _serial_number);
aoqi@0 284 check_watch("initialized by copy", set->_serial_number);
aoqi@0 285 _max_elements = set->_max_elements;
aoqi@0 286 #endif
aoqi@0 287 _count = set->_count;
aoqi@0 288 _max_blocks = set->_max_blocks;
aoqi@0 289 if (_max_blocks <= preallocated_block_list_size) {
aoqi@0 290 _blocks = _preallocated_block_list;
aoqi@0 291 } else {
aoqi@0 292 _blocks =
aoqi@0 293 (IndexSet::BitBlock**) arena()->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
aoqi@0 294 }
aoqi@0 295 for (uint i = 0; i < _max_blocks; i++) {
aoqi@0 296 BitBlock *block = set->_blocks[i];
aoqi@0 297 if (block == &_empty_block) {
aoqi@0 298 set_block(i, &_empty_block);
aoqi@0 299 } else {
aoqi@0 300 BitBlock *new_block = alloc_block();
aoqi@0 301 memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block);
aoqi@0 302 set_block(i, new_block);
aoqi@0 303 }
aoqi@0 304 }
aoqi@0 305 }
aoqi@0 306
aoqi@0 307 //---------------------------- IndexSet::initialize() -----------------------------
aoqi@0 308 // Prepare an IndexSet for use.
aoqi@0 309
aoqi@0 310 void IndexSet::initialize(uint max_elements) {
aoqi@0 311 #ifdef ASSERT
aoqi@0 312 _serial_number = _serial_count++;
aoqi@0 313 check_watch("initialized", max_elements);
aoqi@0 314 _max_elements = max_elements;
aoqi@0 315 #endif
aoqi@0 316 _count = 0;
aoqi@0 317 _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
aoqi@0 318
aoqi@0 319 if (_max_blocks <= preallocated_block_list_size) {
aoqi@0 320 _blocks = _preallocated_block_list;
aoqi@0 321 } else {
aoqi@0 322 _blocks = (IndexSet::BitBlock**) arena()->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
aoqi@0 323 }
aoqi@0 324 for (uint i = 0; i < _max_blocks; i++) {
aoqi@0 325 set_block(i, &_empty_block);
aoqi@0 326 }
aoqi@0 327 }
aoqi@0 328
aoqi@0 329 //---------------------------- IndexSet::initialize()------------------------------
aoqi@0 330 // Prepare an IndexSet for use. If it needs to allocate its _blocks array, it does
aoqi@0 331 // so from the Arena passed as a parameter. BitBlock allocation is still done from
aoqi@0 332 // the static Arena which was set with reset_memory().
aoqi@0 333
aoqi@0 334 void IndexSet::initialize(uint max_elements, Arena *arena) {
aoqi@0 335 #ifdef ASSERT
aoqi@0 336 _serial_number = _serial_count++;
aoqi@0 337 check_watch("initialized2", max_elements);
aoqi@0 338 _max_elements = max_elements;
aoqi@0 339 #endif // ASSERT
aoqi@0 340 _count = 0;
aoqi@0 341 _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
aoqi@0 342
aoqi@0 343 if (_max_blocks <= preallocated_block_list_size) {
aoqi@0 344 _blocks = _preallocated_block_list;
aoqi@0 345 } else {
aoqi@0 346 _blocks = (IndexSet::BitBlock**) arena->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks);
aoqi@0 347 }
aoqi@0 348 for (uint i = 0; i < _max_blocks; i++) {
aoqi@0 349 set_block(i, &_empty_block);
aoqi@0 350 }
aoqi@0 351 }
aoqi@0 352
aoqi@0 353 //---------------------------- IndexSet::swap() -----------------------------
aoqi@0 354 // Exchange two IndexSets.
aoqi@0 355
aoqi@0 356 void IndexSet::swap(IndexSet *set) {
aoqi@0 357 #ifdef ASSERT
aoqi@0 358 assert(_max_elements == set->_max_elements, "must have same universe size to swap");
aoqi@0 359 check_watch("swap", set->_serial_number);
aoqi@0 360 set->check_watch("swap", _serial_number);
aoqi@0 361 #endif
aoqi@0 362
aoqi@0 363 for (uint i = 0; i < _max_blocks; i++) {
aoqi@0 364 BitBlock *temp = _blocks[i];
aoqi@0 365 set_block(i, set->_blocks[i]);
aoqi@0 366 set->set_block(i, temp);
aoqi@0 367 }
aoqi@0 368 uint temp = _count;
aoqi@0 369 _count = set->_count;
aoqi@0 370 set->_count = temp;
aoqi@0 371 }
aoqi@0 372
aoqi@0 373 //---------------------------- IndexSet::dump() -----------------------------
aoqi@0 374 // Print this set. Used for debugging.
aoqi@0 375
aoqi@0 376 #ifndef PRODUCT
aoqi@0 377 void IndexSet::dump() const {
aoqi@0 378 IndexSetIterator elements(this);
aoqi@0 379
aoqi@0 380 tty->print("{");
aoqi@0 381 uint i;
aoqi@0 382 while ((i = elements.next()) != 0) {
aoqi@0 383 tty->print("L%d ", i);
aoqi@0 384 }
aoqi@0 385 tty->print_cr("}");
aoqi@0 386 }
aoqi@0 387 #endif
aoqi@0 388
aoqi@0 389 #ifdef ASSERT
aoqi@0 390 //---------------------------- IndexSet::tally_iteration_statistics() -----------------------------
aoqi@0 391 // Update block/bit counts to reflect that this set has been iterated over.
aoqi@0 392
aoqi@0 393 void IndexSet::tally_iteration_statistics() const {
aoqi@0 394 inc_stat_counter(&_total_bits, count());
aoqi@0 395
aoqi@0 396 for (uint i = 0; i < _max_blocks; i++) {
aoqi@0 397 if (_blocks[i] != &_empty_block) {
aoqi@0 398 inc_stat_counter(&_total_used_blocks, 1);
aoqi@0 399 } else {
aoqi@0 400 inc_stat_counter(&_total_unused_blocks, 1);
aoqi@0 401 }
aoqi@0 402 }
aoqi@0 403 }
aoqi@0 404
aoqi@0 405 //---------------------------- IndexSet::print_statistics() -----------------------------
aoqi@0 406 // Print statistics about IndexSet usage.
aoqi@0 407
aoqi@0 408 void IndexSet::print_statistics() {
aoqi@0 409 julong total_blocks = _total_used_blocks + _total_unused_blocks;
aoqi@0 410 tty->print_cr ("Accumulated IndexSet usage statistics:");
aoqi@0 411 tty->print_cr ("--------------------------------------");
aoqi@0 412 tty->print_cr (" Iteration:");
aoqi@0 413 tty->print_cr (" blocks visited: " UINT64_FORMAT, total_blocks);
aoqi@0 414 tty->print_cr (" blocks empty: %4.2f%%", 100.0*(double)_total_unused_blocks/total_blocks);
aoqi@0 415 tty->print_cr (" bit density (bits/used blocks): %4.2f", (double)_total_bits/_total_used_blocks);
aoqi@0 416 tty->print_cr (" bit density (bits/all blocks): %4.2f", (double)_total_bits/total_blocks);
aoqi@0 417 tty->print_cr (" Allocation:");
aoqi@0 418 tty->print_cr (" blocks allocated: " UINT64_FORMAT, _alloc_new);
aoqi@0 419 tty->print_cr (" blocks used/reused: " UINT64_FORMAT, _alloc_total);
aoqi@0 420 }
aoqi@0 421
aoqi@0 422 //---------------------------- IndexSet::verify() -----------------------------
aoqi@0 423 // Expensive test of IndexSet sanity. Ensure that the count agrees with the
aoqi@0 424 // number of bits in the blocks. Make sure the iterator is seeing all elements
aoqi@0 425 // of the set. Meant for use during development.
aoqi@0 426
aoqi@0 427 void IndexSet::verify() const {
aoqi@0 428 assert(!member(0), "zero cannot be a member");
aoqi@0 429 uint count = 0;
aoqi@0 430 uint i;
aoqi@0 431 for (i = 1; i < _max_elements; i++) {
aoqi@0 432 if (member(i)) {
aoqi@0 433 count++;
aoqi@0 434 assert(count <= _count, "_count is messed up");
aoqi@0 435 }
aoqi@0 436 }
aoqi@0 437
aoqi@0 438 IndexSetIterator elements(this);
aoqi@0 439 count = 0;
aoqi@0 440 while ((i = elements.next()) != 0) {
aoqi@0 441 count++;
aoqi@0 442 assert(member(i), "returned a non member");
aoqi@0 443 assert(count <= _count, "iterator returned wrong number of elements");
aoqi@0 444 }
aoqi@0 445 }
aoqi@0 446 #endif
aoqi@0 447
aoqi@0 448 //---------------------------- IndexSetIterator() -----------------------------
aoqi@0 449 // Create an iterator for a set. If empty blocks are detected when iterating
aoqi@0 450 // over the set, these blocks are replaced.
aoqi@0 451
aoqi@0 452 IndexSetIterator::IndexSetIterator(IndexSet *set) {
aoqi@0 453 #ifdef ASSERT
aoqi@0 454 if (CollectIndexSetStatistics) {
aoqi@0 455 set->tally_iteration_statistics();
aoqi@0 456 }
aoqi@0 457 set->check_watch("traversed", set->count());
aoqi@0 458 #endif
aoqi@0 459 if (set->is_empty()) {
aoqi@0 460 _current = 0;
aoqi@0 461 _next_word = IndexSet::words_per_block;
aoqi@0 462 _next_block = 1;
aoqi@0 463 _max_blocks = 1;
aoqi@0 464
aoqi@0 465 // We don't need the following values when we iterate over an empty set.
aoqi@0 466 // The commented out code is left here to document that the omission
aoqi@0 467 // is intentional.
aoqi@0 468 //
aoqi@0 469 //_value = 0;
aoqi@0 470 //_words = NULL;
aoqi@0 471 //_blocks = NULL;
aoqi@0 472 //_set = NULL;
aoqi@0 473 } else {
aoqi@0 474 _current = 0;
aoqi@0 475 _value = 0;
aoqi@0 476 _next_block = 0;
aoqi@0 477 _next_word = IndexSet::words_per_block;
aoqi@0 478
aoqi@0 479 _max_blocks = set->_max_blocks;
aoqi@0 480 _words = NULL;
aoqi@0 481 _blocks = set->_blocks;
aoqi@0 482 _set = set;
aoqi@0 483 }
aoqi@0 484 }
aoqi@0 485
aoqi@0 486 //---------------------------- IndexSetIterator(const) -----------------------------
aoqi@0 487 // Iterate over a constant IndexSet.
aoqi@0 488
aoqi@0 489 IndexSetIterator::IndexSetIterator(const IndexSet *set) {
aoqi@0 490 #ifdef ASSERT
aoqi@0 491 if (CollectIndexSetStatistics) {
aoqi@0 492 set->tally_iteration_statistics();
aoqi@0 493 }
aoqi@0 494 // We don't call check_watch from here to avoid bad recursion.
aoqi@0 495 // set->check_watch("traversed const", set->count());
aoqi@0 496 #endif
aoqi@0 497 if (set->is_empty()) {
aoqi@0 498 _current = 0;
aoqi@0 499 _next_word = IndexSet::words_per_block;
aoqi@0 500 _next_block = 1;
aoqi@0 501 _max_blocks = 1;
aoqi@0 502
aoqi@0 503 // We don't need the following values when we iterate over an empty set.
aoqi@0 504 // The commented out code is left here to document that the omission
aoqi@0 505 // is intentional.
aoqi@0 506 //
aoqi@0 507 //_value = 0;
aoqi@0 508 //_words = NULL;
aoqi@0 509 //_blocks = NULL;
aoqi@0 510 //_set = NULL;
aoqi@0 511 } else {
aoqi@0 512 _current = 0;
aoqi@0 513 _value = 0;
aoqi@0 514 _next_block = 0;
aoqi@0 515 _next_word = IndexSet::words_per_block;
aoqi@0 516
aoqi@0 517 _max_blocks = set->_max_blocks;
aoqi@0 518 _words = NULL;
aoqi@0 519 _blocks = set->_blocks;
aoqi@0 520 _set = NULL;
aoqi@0 521 }
aoqi@0 522 }
aoqi@0 523
aoqi@0 524 //---------------------------- List16Iterator::advance_and_next() -----------------------------
aoqi@0 525 // Advance to the next non-empty word in the set being iterated over. Return the next element
aoqi@0 526 // if there is one. If we are done, return 0. This method is called from the next() method
aoqi@0 527 // when it gets done with a word.
aoqi@0 528
aoqi@0 529 uint IndexSetIterator::advance_and_next() {
aoqi@0 530 // See if there is another non-empty word in the current block.
aoqi@0 531 for (uint wi = _next_word; wi < (unsigned)IndexSet::words_per_block; wi++) {
aoqi@0 532 if (_words[wi] != 0) {
aoqi@0 533 // Found a non-empty word.
aoqi@0 534 _value = ((_next_block - 1) * IndexSet::bits_per_block) + (wi * IndexSet::bits_per_word);
aoqi@0 535 _current = _words[wi];
aoqi@0 536
aoqi@0 537 _next_word = wi+1;
aoqi@0 538
aoqi@0 539 return next();
aoqi@0 540 }
aoqi@0 541 }
aoqi@0 542
aoqi@0 543 // We ran out of words in the current block. Advance to next non-empty block.
aoqi@0 544 for (uint bi = _next_block; bi < _max_blocks; bi++) {
aoqi@0 545 if (_blocks[bi] != &IndexSet::_empty_block) {
aoqi@0 546 // Found a non-empty block.
aoqi@0 547
aoqi@0 548 _words = _blocks[bi]->words();
aoqi@0 549 for (uint wi = 0; wi < (unsigned)IndexSet::words_per_block; wi++) {
aoqi@0 550 if (_words[wi] != 0) {
aoqi@0 551 // Found a non-empty word.
aoqi@0 552 _value = (bi * IndexSet::bits_per_block) + (wi * IndexSet::bits_per_word);
aoqi@0 553 _current = _words[wi];
aoqi@0 554
aoqi@0 555 _next_block = bi+1;
aoqi@0 556 _next_word = wi+1;
aoqi@0 557
aoqi@0 558 return next();
aoqi@0 559 }
aoqi@0 560 }
aoqi@0 561
aoqi@0 562 // All of the words in the block were empty. Replace
aoqi@0 563 // the block with the empty block.
aoqi@0 564 if (_set) {
aoqi@0 565 _set->free_block(bi);
aoqi@0 566 }
aoqi@0 567 }
aoqi@0 568 }
aoqi@0 569
aoqi@0 570 // These assignments make redundant calls to next on a finished iterator
aoqi@0 571 // faster. Probably not necessary.
aoqi@0 572 _next_block = _max_blocks;
aoqi@0 573 _next_word = IndexSet::words_per_block;
aoqi@0 574
aoqi@0 575 // No more words.
aoqi@0 576 return 0;
aoqi@0 577 }

mercurial