annotate src/share/vm/opto/indexSet.hpp @ 12355:cefad50507d8

Merge with hs25-b53
author Gilles Duboscq <duboscq@ssw.jku.at>
date Fri, 11 Oct 2013 10:38:03 +0200
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 #ifndef SHARE_VM_OPTO_INDEXSET_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define SHARE_VM_OPTO_INDEXSET_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "memory/allocation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "opto/compile.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "opto/regmask.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32
0
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // This file defines the IndexSet class, a set of sparse integer indices.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // This data structure is used by the compiler in its liveness analysis and
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // during register allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 //-------------------------------- class IndexSet ----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // An IndexSet is a piece-wise bitvector. At the top level, we have an array
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // of pointers to bitvector chunks called BitBlocks. Each BitBlock has a fixed
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // size and is allocated from a shared free list. The bits which are set in
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // each BitBlock correspond to the elements of the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class IndexSet : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 friend class IndexSetIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // When we allocate an IndexSet, it starts off with an array of top level block
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // pointers of a set length. This size is intended to be large enough for the
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // majority of IndexSets. In the cases when this size is not large enough,
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // a separately allocated array is used.
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // The length of the preallocated top level block array
a61af66fc99e Initial load
duke
parents:
diff changeset
53 enum { preallocated_block_list_size = 16 };
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Elements of a IndexSet get decomposed into three fields. The highest order
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // bits are the block index, which tell which high level block holds the element.
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // Within that block, the word index indicates which word holds the element.
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Finally, the bit index determines which single bit within that word indicates
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // membership of the element in the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // The lengths of the index bitfields
a61af66fc99e Initial load
duke
parents:
diff changeset
62 enum { bit_index_length = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
63 word_index_length = 3,
a61af66fc99e Initial load
duke
parents:
diff changeset
64 block_index_length = 8 // not used
a61af66fc99e Initial load
duke
parents:
diff changeset
65 };
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // Derived constants used for manipulating the index bitfields
a61af66fc99e Initial load
duke
parents:
diff changeset
68 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 bit_index_offset = 0, // not used
a61af66fc99e Initial load
duke
parents:
diff changeset
70 word_index_offset = bit_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
71 block_index_offset = bit_index_length + word_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 bits_per_word = 1 << bit_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
74 words_per_block = 1 << word_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
75 bits_per_block = bits_per_word * words_per_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 bit_index_mask = right_n_bits(bit_index_length),
a61af66fc99e Initial load
duke
parents:
diff changeset
78 word_index_mask = right_n_bits(word_index_length)
a61af66fc99e Initial load
duke
parents:
diff changeset
79 };
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // These routines are used for extracting the block, word, and bit index
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // from an element.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static uint get_block_index(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return element >> block_index_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 static uint get_word_index(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return mask_bits(element >> word_index_offset,word_index_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 static uint get_bit_index(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 return mask_bits(element,bit_index_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 }
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 //------------------------------ class BitBlock ----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // The BitBlock class is a segment of a bitvector set.
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 class BitBlock : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 friend class IndexSetIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 friend class IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // All of BitBlocks fields and methods are declared private. We limit
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // access to IndexSet and IndexSetIterator.
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // A BitBlock is composed of some number of 32 bit words. When a BitBlock
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // is not in use by any IndexSet, it is stored on a free list. The next field
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // is used by IndexSet to mainting this free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 uint32 _words[words_per_block];
a61af66fc99e Initial load
duke
parents:
diff changeset
110 BitBlock *_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 } _data;
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
114 uint32 *words() { return _data._words; }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 void set_next(BitBlock *next) { _data._next = next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 BitBlock *next() { return _data._next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Operations. A BitBlock supports four simple operations,
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // clear(), member(), insert(), and remove(). These methods do
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // not assume that the block index has been masked out.
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 memset(words(), 0, sizeof(uint32) * words_per_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 bool member(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 uint word_index = IndexSet::get_word_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 uint bit_index = IndexSet::get_bit_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 bool insert(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 uint word_index = IndexSet::get_word_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 uint bit_index = IndexSet::get_bit_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 uint32 bit = (0x1 << bit_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
138 uint32 before = words()[word_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
139 words()[word_index] = before | bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 return ((before & bit) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 bool remove(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 uint word_index = IndexSet::get_word_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 uint bit_index = IndexSet::get_bit_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 uint32 bit = (0x1 << bit_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 uint32 before = words()[word_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
149 words()[word_index] = before & ~bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 return ((before & bit) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152 };
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 //-------------------------- BitBlock allocation ---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
155 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // All IndexSets share an arena from which they allocate BitBlocks. Unused
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // BitBlocks are placed on a free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // The number of BitBlocks to allocate at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
161 enum { bitblock_alloc_chunk_size = 50 };
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 static Arena *arena() { return Compile::current()->indexSet_arena(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 static void populate_free_list();
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // Invalidate the current free BitBlock list and begin allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // from a new arena. It is essential that this method is called whenever
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // the Arena being used for BitBlock allocation is reset.
a61af66fc99e Initial load
duke
parents:
diff changeset
172 static void reset_memory(Compile* compile, Arena *arena) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 compile->set_indexSet_free_block_list(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 compile->set_indexSet_arena(arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // This should probably be done in a static initializer
a61af66fc99e Initial load
duke
parents:
diff changeset
177 _empty_block.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
181 friend class BitBlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // A distinguished BitBlock which always remains empty. When a new IndexSet is
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // created, all of its top level BitBlock pointers are initialized to point to
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // this.
a61af66fc99e Initial load
duke
parents:
diff changeset
185 static BitBlock _empty_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 //-------------------------- Members ------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // The number of elements in the set
a61af66fc99e Initial load
duke
parents:
diff changeset
190 uint _count;
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // Our top level array of bitvector segments
a61af66fc99e Initial load
duke
parents:
diff changeset
193 BitBlock **_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 BitBlock *_preallocated_block_list[preallocated_block_list_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // The number of top level array entries in use
a61af66fc99e Initial load
duke
parents:
diff changeset
198 uint _max_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Our assertions need to know the maximum number allowed in the set
a61af66fc99e Initial load
duke
parents:
diff changeset
201 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
202 uint _max_elements;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // The next IndexSet on the free list (not used at same time as count)
a61af66fc99e Initial load
duke
parents:
diff changeset
206 IndexSet *_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
209 //-------------------------- Free list operations ------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // Individual IndexSets can be placed on a free list. This is done in PhaseLive.
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 IndexSet *next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if( VerifyOpto ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 check_watch("removed from free list?", ((_next == NULL) ? 0 : _next->_serial_number));
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return _next;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 void set_next(IndexSet *next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
223 if( VerifyOpto ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 check_watch("put on free list?", ((next == NULL) ? 0 : next->_serial_number));
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
227 _next = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
231 //-------------------------- Utility methods -----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // Get the block which holds element
a61af66fc99e Initial load
duke
parents:
diff changeset
234 BitBlock *get_block_containing(uint element) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 assert(element < _max_elements, "element out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
236 return _blocks[get_block_index(element)];
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // Set a block in the top level array
a61af66fc99e Initial load
duke
parents:
diff changeset
240 void set_block(uint index, BitBlock *block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
243 check_watch("set block", index);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _blocks[index] = block;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Get a BitBlock from the free list
a61af66fc99e Initial load
duke
parents:
diff changeset
249 BitBlock *alloc_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Get a BitBlock from the free list and place it in the top level array
a61af66fc99e Initial load
duke
parents:
diff changeset
252 BitBlock *alloc_block_containing(uint element);
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Free a block from the top level array, placing it on the free BitBlock list
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void free_block(uint i);
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
258 //-------------------------- Primitive set operations --------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
263 check_watch("clear");
a61af66fc99e Initial load
duke
parents:
diff changeset
264 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
265 _count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 for (uint i = 0; i < _max_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 BitBlock *block = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
268 if (block != &_empty_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 free_block(i);
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 uint count() const { return _count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 bool is_empty() const { return _count == 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 bool member(uint element) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 return get_block_containing(element)->member(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 bool insert(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
284 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
285 check_watch("insert", element);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (element == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 BitBlock *block = get_block_containing(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 if (block == &_empty_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 block = alloc_block_containing(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 bool present = block->insert(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 if (!present) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 _count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298 return !present;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 bool remove(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
304 check_watch("remove", element);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 BitBlock *block = get_block_containing(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 bool present = block->remove(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (present) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 _count--;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 return present;
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 //-------------------------- Compound set operations ------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // Compute the union of all elements of one and two which interfere
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // with the RegMask mask. If the degree of the union becomes
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // exceeds fail_degree, the union bails out. The underlying set is
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // cleared before the union is performed.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 uint lrg_union(uint lr1, uint lr2,
a61af66fc99e Initial load
duke
parents:
diff changeset
321 const uint fail_degree,
a61af66fc99e Initial load
duke
parents:
diff changeset
322 const class PhaseIFG *ifg,
a61af66fc99e Initial load
duke
parents:
diff changeset
323 const RegMask &mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326 //------------------------- Construction, initialization -----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 IndexSet() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // This constructor is used for making a deep copy of a IndexSet.
a61af66fc99e Initial load
duke
parents:
diff changeset
331 IndexSet(IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Perform initialization on a IndexSet
a61af66fc99e Initial load
duke
parents:
diff changeset
334 void initialize(uint max_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Initialize a IndexSet. If the top level BitBlock array needs to be
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // allocated, do it from the proffered arena. BitBlocks are still allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // from the static Arena member.
a61af66fc99e Initial load
duke
parents:
diff changeset
339 void initialize(uint max_element, Arena *arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Exchange two sets
a61af66fc99e Initial load
duke
parents:
diff changeset
342 void swap(IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 //-------------------------- Debugging and statistics --------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Output a IndexSet for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
348 void dump() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
349 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
352 void tally_iteration_statistics() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // BitBlock allocation statistics
2250
f7de3327c683 7017124: Fix some VM stats to avoid 32-bit overflow
kvn
parents: 1972
diff changeset
355 static julong _alloc_new;
f7de3327c683 7017124: Fix some VM stats to avoid 32-bit overflow
kvn
parents: 1972
diff changeset
356 static julong _alloc_total;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // Block density statistics
2250
f7de3327c683 7017124: Fix some VM stats to avoid 32-bit overflow
kvn
parents: 1972
diff changeset
359 static julong _total_bits;
f7de3327c683 7017124: Fix some VM stats to avoid 32-bit overflow
kvn
parents: 1972
diff changeset
360 static julong _total_used_blocks;
f7de3327c683 7017124: Fix some VM stats to avoid 32-bit overflow
kvn
parents: 1972
diff changeset
361 static julong _total_unused_blocks;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Sanity tests
a61af66fc99e Initial load
duke
parents:
diff changeset
364 void verify() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 static int _serial_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 int _serial_number;
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // Check to see if the serial number of the current set is the one we're tracing.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // If it is, print a message.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 void check_watch(const char *operation, uint operand) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (IndexSetWatch != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 tty->print_cr("IndexSet %d : %s ( %d )", _serial_number, operation, operand);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 void check_watch(const char *operation) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if (IndexSetWatch != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 tty->print_cr("IndexSet %d : %s", _serial_number, operation);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
387 static void print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
390 };
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 //-------------------------------- class IndexSetIterator --------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // An iterator for IndexSets.
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 friend class IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // We walk over the bits in a word in chunks of size window_size.
a61af66fc99e Initial load
duke
parents:
diff changeset
402 enum { window_size = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
403 window_mask = right_n_bits(window_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
404 table_size = (1 << window_size) };
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // For an integer of length window_size, what is the first set bit?
a61af66fc99e Initial load
duke
parents:
diff changeset
407 static const byte _first_bit[table_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // For an integer of length window_size, what is the second set bit?
a61af66fc99e Initial load
duke
parents:
diff changeset
410 static const byte _second_bit[table_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // The current word we are inspecting
a61af66fc99e Initial load
duke
parents:
diff changeset
414 uint32 _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // What element number are we currently on?
a61af66fc99e Initial load
duke
parents:
diff changeset
417 uint _value;
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // The index of the next word we will inspect
a61af66fc99e Initial load
duke
parents:
diff changeset
420 uint _next_word;
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // A pointer to the contents of the current block
a61af66fc99e Initial load
duke
parents:
diff changeset
423 uint32 *_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // The index of the next block we will inspect
a61af66fc99e Initial load
duke
parents:
diff changeset
426 uint _next_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
427
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // A pointer to the blocks in our set
a61af66fc99e Initial load
duke
parents:
diff changeset
429 IndexSet::BitBlock **_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // The number of blocks in the set
a61af66fc99e Initial load
duke
parents:
diff changeset
432 uint _max_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // If the iterator was created from a non-const set, we replace
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // non-canonical empty blocks with the _empty_block pointer. If
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // _set is NULL, we do no replacement.
a61af66fc99e Initial load
duke
parents:
diff changeset
437 IndexSet *_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Advance to the next non-empty word and return the next
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // element in the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
441 uint advance_and_next();
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // If an iterator is built from a constant set then empty blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // are not canonicalized.
a61af66fc99e Initial load
duke
parents:
diff changeset
448 IndexSetIterator(IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 IndexSetIterator(const IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Return the next element of the set. Return 0 when done.
a61af66fc99e Initial load
duke
parents:
diff changeset
452 uint next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 uint current = _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
454 if (current != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 uint value = _value;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 while (mask_bits(current,window_mask) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 current >>= window_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
458 value += window_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 uint advance = _second_bit[mask_bits(current,window_mask)];
a61af66fc99e Initial load
duke
parents:
diff changeset
462 _current = current >> advance;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 _value = value + advance;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 return value + _first_bit[mask_bits(current,window_mask)];
a61af66fc99e Initial load
duke
parents:
diff changeset
465 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 return advance_and_next();
a61af66fc99e Initial load
duke
parents:
diff changeset
467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
469 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
470
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
471 #endif // SHARE_VM_OPTO_INDEXSET_HPP