Mercurial > hg > graal-compiler
annotate src/cpu/sparc/vm/args.cc @ 6812:988bf00cc564
7200261: G1: Liveness counting inconsistencies during marking verification
Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures.
Reviewed-by: brutisso, jwilhelm, jmasa
author | johnc |
---|---|
date | Thu, 27 Sep 2012 15:44:01 -0700 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
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 | 22 * |
23 */ | |
24 | |
25 #include <stdio.h> | |
26 #include <string.h> | |
27 | |
28 static const int R_O0_num = 1000; | |
29 static const int R_I0_num = 2000; | |
30 static const int R_F0_num = 3000; | |
31 static const int R_F1_num = R_F0_num + 1; | |
32 static const int R_F2_num = R_F0_num + 2; | |
33 static const int STACK_num= 4000; | |
34 | |
35 static bool LP64 = false; | |
36 static bool LONGS_IN_ONE_ENTRY = false; | |
37 | |
38 static const int Op_RegI = 'I'; | |
39 static const int Op_RegP = 'P'; | |
40 static const int Op_RegF = 'F'; | |
41 static const int Op_RegD = 'D'; | |
42 static const int Op_RegL = 'L'; | |
43 static const int SPARC_ARGS_IN_REGS_NUM=6; | |
44 | |
45 static void print_reg( int reg ) { | |
46 if( reg == 0 ) | |
47 printf("__"); // halve's | |
48 else if( reg >= STACK_num && reg < STACK_num+100 ) | |
49 printf("S%d_",reg - STACK_num); | |
50 else if( reg >= R_F0_num && reg < R_F0_num+100 ) | |
51 printf("F%d_",reg - R_F0_num); | |
52 else if( reg >= R_O0_num && reg < R_O0_num+100 ) { | |
53 if( LONGS_IN_ONE_ENTRY ) { | |
54 reg -= R_O0_num; | |
55 printf("O%d",reg>>1); | |
56 printf(reg&1 ? "H" : "L"); | |
57 } else | |
58 printf("O%d_",reg - R_O0_num); | |
59 } else | |
60 printf("Wretched: %d\n", reg); | |
61 } | |
62 | |
63 static void print_convention( int *sig, const char *s, int length ) { | |
64 // Print it out | |
65 for( int i = 0; i < length; i++) { | |
66 if( sig[i] == 0 ) continue; // do not print 'halves' | |
67 print_reg( sig[i] & 0xFFFF ); | |
68 int reg = sig[i] >> 16; | |
69 if( reg ) { | |
70 printf(":"); | |
71 print_reg( reg ); | |
72 } else { | |
73 printf(" "); | |
74 } | |
75 printf(" "); | |
76 } | |
77 printf("\n"); | |
78 } | |
79 | |
80 static int INT_SCALE( int x ) { | |
81 return LONGS_IN_ONE_ENTRY ? (x<<1) : x; | |
82 } | |
83 | |
84 static void java_convention( int *sig, const char *s, int length ) { | |
85 if( LP64 && !LONGS_IN_ONE_ENTRY ) { | |
86 printf("LP64 and 2-reg longs not supported\n"); | |
87 return; | |
88 } | |
89 for( int i = 0; i < length; i++ ) | |
90 sig[i] = s[i]; // Reset sig array | |
91 bool is_outgoing = true; | |
92 | |
93 int int_base = (is_outgoing ? R_O0_num : R_I0_num); | |
94 | |
95 // Convention is to pack the first 6 int/oop args into the first 6 | |
96 // registers (I0-I5), extras spill to the stack. Then pack the first | |
97 // 32 float args into F0-F31, extras spill to the stack. Then pad | |
98 // all register sets to align. Then put longs and doubles into the | |
99 // same registers as they fit, else spill to the stack. | |
100 int int_reg_max = SPARC_ARGS_IN_REGS_NUM; | |
101 int flt_reg_max = 32; | |
102 | |
103 // Count int/oop and float args. See how many stack slots we'll need | |
104 // and where the longs & doubles will go. | |
105 int int_reg_cnt = 0; | |
106 int flt_reg_cnt = 0; | |
107 int stk_reg_pairs = 0; | |
108 for( int i = 0; i < length; i++) { | |
109 switch( sig[i] ) { | |
110 case Op_RegL: // Longs-in-1-reg compete with int args | |
111 if( LONGS_IN_ONE_ENTRY ) { | |
112 if( int_reg_cnt < int_reg_max ) int_reg_cnt++; | |
113 } | |
114 break; | |
115 case Op_RegP: | |
116 if( int_reg_cnt < int_reg_max ) int_reg_cnt++; | |
117 else if( !LP64 ) stk_reg_pairs++; | |
118 break; | |
119 case Op_RegI: | |
120 if( int_reg_cnt < int_reg_max ) int_reg_cnt++; | |
121 else stk_reg_pairs++; | |
122 break; | |
123 case Op_RegF: | |
124 if( flt_reg_cnt < flt_reg_max ) flt_reg_cnt++; | |
125 else stk_reg_pairs++; | |
126 break; | |
127 } | |
128 } | |
129 | |
130 // This is where the longs/doubles start on the stack. | |
131 stk_reg_pairs = (stk_reg_pairs+1) & ~1; // Round | |
132 | |
133 int int_reg_pairs = (int_reg_cnt+1) & ~1; // 32-bit 2-reg longs only | |
134 int flt_reg_pairs = (flt_reg_cnt+1) & ~1; | |
135 | |
136 int stk_reg = 0; | |
137 int int_reg = 0; | |
138 int flt_reg = 0; | |
139 | |
140 // Now do the signature layout | |
141 for( int i = 0; i < length; i++) { | |
142 int tmp = sig[i]; | |
143 if( tmp == Op_RegP ) | |
144 tmp = LP64 ? Op_RegL : Op_RegI; // Treat ptrs and ints or long accordingly | |
145 switch( tmp ) { | |
146 case Op_RegI: | |
147 // case Op_RegP: | |
148 if( int_reg < int_reg_max) tmp = INT_SCALE(int_reg++) + int_base; | |
149 else tmp = STACK_num + stk_reg++; | |
150 sig[i] = tmp; | |
151 break; | |
152 | |
153 case Op_RegL: | |
154 if( sig[i] != Op_RegP && sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; } | |
155 // case Op_RegP: | |
156 if( LONGS_IN_ONE_ENTRY ) { | |
157 if( int_reg < int_reg_max ) { | |
158 tmp = INT_SCALE(int_reg++) + int_base; | |
159 } else { | |
160 tmp = STACK_num + stk_reg_pairs; | |
161 stk_reg_pairs += 2; | |
162 } | |
163 } else { | |
164 if( int_reg_pairs < int_reg_max ) { | |
165 tmp = int_reg_pairs + int_base; | |
166 int_reg_pairs += 2; | |
167 } else { | |
168 tmp = STACK_num + stk_reg_pairs; | |
169 stk_reg_pairs += 2; | |
170 } | |
171 } | |
172 sig[i] = tmp | (tmp+1)<<16; // Smear to pair | |
173 break; | |
174 | |
175 case Op_RegF: | |
176 sig[i] = (flt_reg < flt_reg_max) ? (R_F0_num + flt_reg++) : STACK_num + stk_reg++; | |
177 break; | |
178 case Op_RegD: | |
179 if( sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; } | |
180 if( flt_reg_pairs < flt_reg_max ) { | |
181 tmp = R_F0_num + flt_reg_pairs; | |
182 flt_reg_pairs += 2; | |
183 } else { | |
184 tmp = STACK_num + stk_reg_pairs; | |
185 stk_reg_pairs += 2; | |
186 } | |
187 sig[i] = tmp | (tmp+1)<<16; // Smear to pair | |
188 break; | |
189 case 'h': sig[i] = 0; break; | |
190 default: | |
191 printf("Bad character: %c\n", sig[i] ); | |
192 return; | |
193 } | |
194 } | |
195 | |
196 printf("java "); | |
197 printf(LP64 ? "LP64 " : "LP32 "); | |
198 printf(LONGS_IN_ONE_ENTRY ? "long1: " : "long2: "); | |
199 print_convention(sig,s,length); | |
200 } | |
201 | |
202 static int int_stk_helper( int i ) { | |
203 if( i < 6 ) return R_O0_num + (LONGS_IN_ONE_ENTRY ? i<<1 : i); | |
204 else return STACK_num + (LP64 ? i<<1 : i); | |
205 } | |
206 | |
207 static void native_convention( int *sig, const char *s, int length ) { | |
208 if( LP64 && !LONGS_IN_ONE_ENTRY ) { | |
209 printf("LP64 and 2-reg longs not supported\n"); | |
210 return; | |
211 } | |
212 for( int i = 0; i < length; i++ ) | |
213 sig[i] = s[i]; // Reset sig array | |
214 | |
215 // The native convention is V8 if !LP64, which means the V8 convention is | |
216 // used both with and without LONGS_IN_ONE_ENTRY, an unfortunate split. The | |
217 // same actual machine registers are used, but they are named differently in | |
218 // the LONGS_IN_ONE_ENTRY mode. The LP64 convention is the V9 convention | |
219 // which is slightly more sane. | |
220 | |
221 if( LP64 ) { | |
222 // V9 convention: All things "as-if" on double-wide stack slots. | |
223 // Hoist any int/ptr/long's in the first 6 to int regs. | |
224 // Hoist any flt/dbl's in the first 16 dbl regs. | |
225 int j = 0; // Count of actual args, not HALVES | |
226 for( int i=0; i<length; i++, j++ ) { | |
227 int tmp; | |
228 switch( sig[i] ) { | |
229 case Op_RegI: | |
230 sig[i] = int_stk_helper( j ); | |
231 break; | |
232 case Op_RegL: | |
233 if( sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; } | |
234 case Op_RegP: | |
235 tmp = int_stk_helper( j ); | |
236 sig[i] = tmp | ((tmp+1) << 16); // Smear to pair | |
237 break; | |
238 case Op_RegF: // V9ism: floats go in ODD registers | |
239 sig[i] = ((j < 16) ? R_F1_num : (STACK_num + 1)) + (j<<1); | |
240 break; | |
241 case Op_RegD: // V9ism: doubles go in EVEN/ODD regs | |
242 tmp = ((j < 16) ? R_F0_num : STACK_num) + (j<<1); | |
243 sig[i] = tmp | ((tmp+1) << 16); // Smear to pair | |
244 break; | |
245 case 'h': sig[i] = 0; j--; break; // Do not count HALVES | |
246 default: | |
247 printf("Bad character: %c\n", sig[i] ); | |
248 return; | |
249 } | |
250 } | |
251 | |
252 } else { | |
253 // V8 convention: first 6 things in O-regs, rest on stack. | |
254 // Alignment is willy-nilly. | |
255 for( int i=0; i<length; i++ ) { | |
256 int tmp; | |
257 switch( sig[i] ) { | |
258 case Op_RegI: | |
259 case Op_RegP: | |
260 case Op_RegF: | |
261 sig[i] = int_stk_helper( i ); | |
262 break; | |
263 case Op_RegL: | |
264 case Op_RegD: | |
265 if( sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; } | |
266 tmp = int_stk_helper( i ); | |
267 sig[i] = tmp | (int_stk_helper( i+1 ) << 16); | |
268 break; | |
269 case 'h': sig[i] = 0; break; | |
270 default: | |
271 printf("Bad character: %c\n", sig[i] ); | |
272 return; | |
273 } | |
274 } | |
275 } | |
276 | |
277 printf("natv "); | |
278 printf(LP64 ? "LP64 " : "LP32 "); | |
279 printf(LONGS_IN_ONE_ENTRY ? "long1: " : "long2: "); | |
280 print_convention(sig,s,length); | |
281 } | |
282 | |
283 int main( int argc, char **argv ) { | |
284 | |
285 if( argc != 2 ) { | |
286 printf("Usage: args IPFLhDh... (Java argument string)\n"); | |
287 printf("Returns argument layout\n"); | |
288 return -1; | |
289 } | |
290 | |
291 const char *s = argv[1]; | |
292 int length = strlen(s); | |
293 int sig[1000]; | |
294 | |
295 LP64 = false; LONGS_IN_ONE_ENTRY = false; | |
296 java_convention( sig, s, length ); | |
297 LP64 = false; LONGS_IN_ONE_ENTRY = true; | |
298 java_convention( sig, s, length ); | |
299 LP64 = true ; LONGS_IN_ONE_ENTRY = true; | |
300 java_convention( sig, s, length ); | |
301 | |
302 LP64 = false; LONGS_IN_ONE_ENTRY = false; | |
303 native_convention( sig, s, length ); | |
304 LP64 = false; LONGS_IN_ONE_ENTRY = true; | |
305 native_convention( sig, s, length ); | |
306 LP64 = true ; LONGS_IN_ONE_ENTRY = true; | |
307 native_convention( sig, s, length ); | |
308 } | |
309 |