annotate src/share/vm/opto/regmask.cpp @ 1145:e018e6884bd8

6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
author ysr
date Wed, 23 Dec 2009 09:23:54 -0800
parents a61af66fc99e
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
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 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_regmask.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 #define RM_SIZE _RM_SIZE /* a constant private to the class RegMask */
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //-------------Non-zero bit search methods used by RegMask---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // Find lowest 1, or return 32 if empty
a61af66fc99e Initial load
duke
parents:
diff changeset
32 int find_lowest_bit( uint32 mask ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
33 int n = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 if( (mask & 0xffff) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 mask >>= 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 n += 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 }
a61af66fc99e Initial load
duke
parents:
diff changeset
38 if( (mask & 0xff) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 mask >>= 8;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 n += 8;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 }
a61af66fc99e Initial load
duke
parents:
diff changeset
42 if( (mask & 0xf) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 mask >>= 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 n += 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46 if( (mask & 0x3) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 mask >>= 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 n += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 if( (mask & 0x1) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 mask >>= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 n += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54 if( mask == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 n = 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // Find highest 1, or return 32 if empty
a61af66fc99e Initial load
duke
parents:
diff changeset
61 int find_hihghest_bit( uint32 mask ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 int n = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 if( mask > 0xffff ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 mask >>= 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 n += 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if( mask > 0xff ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 mask >>= 8;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 n += 8;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71 if( mask > 0xf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 mask >>= 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 n += 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if( mask > 0x3 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 mask >>= 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 n += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 if( mask > 0x1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 mask >>= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 n += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if( mask == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 n = 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
92 void OptoReg::dump( int r ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 switch( r ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 case Special: tty->print("r---"); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 case Bad: tty->print("rBAD"); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if( r < _last_Mach_Reg ) tty->print(Matcher::regName[r]);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 else tty->print("rS%d",r);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
106 const RegMask RegMask::Empty(
a61af66fc99e Initial load
duke
parents:
diff changeset
107 # define BODY(I) 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
108 FORALL_BODY
a61af66fc99e Initial load
duke
parents:
diff changeset
109 # undef BODY
a61af66fc99e Initial load
duke
parents:
diff changeset
110 0
a61af66fc99e Initial load
duke
parents:
diff changeset
111 );
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //------------------------------find_first_pair--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // Find the lowest-numbered register pair in the mask. Return the
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // HIGHEST register number in the pair, or BAD if no pairs.
a61af66fc99e Initial load
duke
parents:
diff changeset
116 OptoReg::Name RegMask::find_first_pair() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 VerifyPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
118 for( int i = 0; i < RM_SIZE; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if( _A[i] ) { // Found some bits
a61af66fc99e Initial load
duke
parents:
diff changeset
120 int bit = _A[i] & -_A[i]; // Extract low bit
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Convert to bit number, return hi bit in pair
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return OptoReg::Name((i<<_LogWordBits)+find_lowest_bit(bit)+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 return OptoReg::Bad;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 //------------------------------ClearToPairs-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // Clear out partial bits; leave only bit pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
130 void RegMask::ClearToPairs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 for( int i = 0; i < RM_SIZE; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 int bits = _A[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
133 bits &= ((bits & 0x55555555)<<1); // 1 hi-bit set for each pair
a61af66fc99e Initial load
duke
parents:
diff changeset
134 bits |= (bits>>1); // Smear 1 hi-bit into a pair
a61af66fc99e Initial load
duke
parents:
diff changeset
135 _A[i] = bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137 VerifyPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 //------------------------------SmearToPairs-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Smear out partial bits; leave only bit pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
142 void RegMask::SmearToPairs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 for( int i = 0; i < RM_SIZE; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 int bits = _A[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
145 bits |= ((bits & 0x55555555)<<1); // Smear lo bit hi per pair
a61af66fc99e Initial load
duke
parents:
diff changeset
146 bits |= ((bits & 0xAAAAAAAA)>>1); // Smear hi bit lo per pair
a61af66fc99e Initial load
duke
parents:
diff changeset
147 _A[i] = bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 VerifyPairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 //------------------------------is_aligned_pairs-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
153 bool RegMask::is_aligned_Pairs() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // Assert that the register mask contains only bit pairs.
a61af66fc99e Initial load
duke
parents:
diff changeset
155 for( int i = 0; i < RM_SIZE; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 int bits = _A[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
157 while( bits ) { // Check bits for pairing
a61af66fc99e Initial load
duke
parents:
diff changeset
158 int bit = bits & -bits; // Extract low bit
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Low bit is not odd means its mis-aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if( (bit & 0x55555555) == 0 ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 bits -= bit; // Remove bit from mask
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // Check for aligned adjacent bit
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if( (bits & (bit<<1)) == 0 ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 bits -= (bit<<1); // Remove other halve of pair
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 //------------------------------is_bound1--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Return TRUE if the mask contains a single bit
a61af66fc99e Initial load
duke
parents:
diff changeset
172 int RegMask::is_bound1() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 if( is_AllStack() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 int bit = -1; // Set to hold the one bit allowed
a61af66fc99e Initial load
duke
parents:
diff changeset
175 for( int i = 0; i < RM_SIZE; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if( _A[i] ) { // Found some bits
a61af66fc99e Initial load
duke
parents:
diff changeset
177 if( bit != -1 ) return false; // Already had bits, so fail
a61af66fc99e Initial load
duke
parents:
diff changeset
178 bit = _A[i] & -_A[i]; // Extract 1 bit from mask
a61af66fc99e Initial load
duke
parents:
diff changeset
179 if( bit != _A[i] ) return false; // Found many bits, so fail
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // True for both the empty mask and for a single bit
a61af66fc99e Initial load
duke
parents:
diff changeset
183 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 //------------------------------is_bound2--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // Return TRUE if the mask contains an adjacent pair of bits and no other bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
188 int RegMask::is_bound2() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 if( is_AllStack() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 int bit = -1; // Set to hold the one bit allowed
a61af66fc99e Initial load
duke
parents:
diff changeset
192 for( int i = 0; i < RM_SIZE; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if( _A[i] ) { // Found some bits
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if( bit != -1 ) return false; // Already had bits, so fail
a61af66fc99e Initial load
duke
parents:
diff changeset
195 bit = _A[i] & -(_A[i]); // Extract 1 bit from mask
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if( (bit << 1) != 0 ) { // Bit pair stays in same word?
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if( (bit | (bit<<1)) != _A[i] )
a61af66fc99e Initial load
duke
parents:
diff changeset
198 return false; // Require adjacent bit pair and no more bits
a61af66fc99e Initial load
duke
parents:
diff changeset
199 } else { // Else its a split-pair case
a61af66fc99e Initial load
duke
parents:
diff changeset
200 if( bit != _A[i] ) return false; // Found many bits, so fail
a61af66fc99e Initial load
duke
parents:
diff changeset
201 i++; // Skip iteration forward
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if( _A[i] != 1 ) return false; // Require 1 lo bit in next word
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // True for both the empty mask and for a bit pair
a61af66fc99e Initial load
duke
parents:
diff changeset
207 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 //------------------------------is_UP------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // UP means register only, Register plus stack, or stack only is DOWN
a61af66fc99e Initial load
duke
parents:
diff changeset
212 bool RegMask::is_UP() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Quick common case check for DOWN (any stack slot is legal)
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if( is_AllStack() )
a61af66fc99e Initial load
duke
parents:
diff changeset
215 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // Slower check for any stack bits set (also DOWN)
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if( overlap(Matcher::STACK_ONLY_mask) )
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Not DOWN, so must be UP
a61af66fc99e Initial load
duke
parents:
diff changeset
220 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 //------------------------------Size-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // Compute size of register mask in bits
a61af66fc99e Initial load
duke
parents:
diff changeset
225 uint RegMask::Size() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 extern uint8 bitsInByte[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
227 uint sum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 for( int i = 0; i < RM_SIZE; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
229 sum +=
a61af66fc99e Initial load
duke
parents:
diff changeset
230 bitsInByte[(_A[i]>>24) & 0xff] +
a61af66fc99e Initial load
duke
parents:
diff changeset
231 bitsInByte[(_A[i]>>16) & 0xff] +
a61af66fc99e Initial load
duke
parents:
diff changeset
232 bitsInByte[(_A[i]>> 8) & 0xff] +
a61af66fc99e Initial load
duke
parents:
diff changeset
233 bitsInByte[ _A[i] & 0xff];
a61af66fc99e Initial load
duke
parents:
diff changeset
234 return sum;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
238 //------------------------------print------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
239 void RegMask::dump( ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 tty->print("[");
a61af66fc99e Initial load
duke
parents:
diff changeset
241 RegMask rm = *this; // Structure copy into local temp
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 OptoReg::Name start = rm.find_first_elem(); // Get a register
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if( OptoReg::is_valid(start) ) { // Check for empty mask
a61af66fc99e Initial load
duke
parents:
diff changeset
245 rm.Remove(start); // Yank from mask
a61af66fc99e Initial load
duke
parents:
diff changeset
246 OptoReg::dump(start); // Print register
a61af66fc99e Initial load
duke
parents:
diff changeset
247 OptoReg::Name last = start;
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Now I have printed an initial register.
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Print adjacent registers as "rX-rZ" instead of "rX,rY,rZ".
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Begin looping over the remaining registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
252 while( 1 ) { //
a61af66fc99e Initial load
duke
parents:
diff changeset
253 OptoReg::Name reg = rm.find_first_elem(); // Get a register
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if( !OptoReg::is_valid(reg) )
a61af66fc99e Initial load
duke
parents:
diff changeset
255 break; // Empty mask, end loop
a61af66fc99e Initial load
duke
parents:
diff changeset
256 rm.Remove(reg); // Yank from mask
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 if( last+1 == reg ) { // See if they are adjacent
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // Adjacent registers just collect into long runs, no printing.
a61af66fc99e Initial load
duke
parents:
diff changeset
260 last = reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 } else { // Ending some kind of run
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if( start == last ) { // 1-register run; no special printing
a61af66fc99e Initial load
duke
parents:
diff changeset
263 } else if( start+1 == last ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 tty->print(","); // 2-register run; print as "rX,rY"
a61af66fc99e Initial load
duke
parents:
diff changeset
265 OptoReg::dump(last);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 } else { // Multi-register run; print as "rX-rZ"
a61af66fc99e Initial load
duke
parents:
diff changeset
267 tty->print("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
268 OptoReg::dump(last);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270 tty->print(","); // Seperate start of new run
a61af66fc99e Initial load
duke
parents:
diff changeset
271 start = last = reg; // Start a new register run
a61af66fc99e Initial load
duke
parents:
diff changeset
272 OptoReg::dump(start); // Print register
a61af66fc99e Initial load
duke
parents:
diff changeset
273 } // End of if ending a register run or not
a61af66fc99e Initial load
duke
parents:
diff changeset
274 } // End of while regmask not empty
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if( start == last ) { // 1-register run; no special printing
a61af66fc99e Initial load
duke
parents:
diff changeset
277 } else if( start+1 == last ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 tty->print(","); // 2-register run; print as "rX,rY"
a61af66fc99e Initial load
duke
parents:
diff changeset
279 OptoReg::dump(last);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 } else { // Multi-register run; print as "rX-rZ"
a61af66fc99e Initial load
duke
parents:
diff changeset
281 tty->print("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
282 OptoReg::dump(last);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284 if( rm.is_AllStack() ) tty->print("...");
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 tty->print("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288 #endif