annotate src/share/vm/opto/indexSet.cpp @ 6972:bd7a7ce2e264

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