LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "gg.h" | 7 #include "gg.h" |
8 #include "opt.h" | 8 #include "opt.h" |
9 | 9 |
10 static void allocauto(Prog* p); | 10 static void allocauto(Prog* p); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 case TFUNC: | 206 case TFUNC: |
207 case TCHAN: | 207 case TCHAN: |
208 case TMAP: | 208 case TMAP: |
209 if(*xoffset % widthptr != 0) | 209 if(*xoffset % widthptr != 0) |
210 fatal("walktype1: invalid alignment, %T", t); | 210 fatal("walktype1: invalid alignment, %T", t); |
211 bvset(bv, *xoffset / widthptr); | 211 bvset(bv, *xoffset / widthptr); |
212 *xoffset += t->width; | 212 *xoffset += t->width; |
213 break; | 213 break; |
214 | 214 |
215 case TSTRING: | 215 case TSTRING: |
216 » » // struct { byte *str; int32 len; } | 216 » » // struct { byte *str; intgo len; } |
217 if(*xoffset % widthptr != 0) | 217 if(*xoffset % widthptr != 0) |
218 fatal("walktype1: invalid alignment, %T", t); | 218 fatal("walktype1: invalid alignment, %T", t); |
219 bvset(bv, *xoffset / widthptr); | 219 bvset(bv, *xoffset / widthptr); |
220 *xoffset += t->width; | 220 *xoffset += t->width; |
221 break; | 221 break; |
222 | 222 |
223 case TINTER: | 223 case TINTER: |
224 » » // struct { Itab* tab; void* data; } | 224 » » // struct { Itab* tab; union { void* ptr, uintptr val } data; } |
225 » » // struct { Type* type; void* data; }» // When isnilinter(t)==t
rue | 225 » » // or, when isnilinter(t)==true: |
| 226 » » // struct { Type* type; union { void* ptr, uintptr val } data; } |
226 if(*xoffset % widthptr != 0) | 227 if(*xoffset % widthptr != 0) |
227 fatal("walktype1: invalid alignment, %T", t); | 228 fatal("walktype1: invalid alignment, %T", t); |
228 bvset(bv, *xoffset / widthptr); | 229 bvset(bv, *xoffset / widthptr); |
229 bvset(bv, (*xoffset + widthptr) / widthptr); | 230 bvset(bv, (*xoffset + widthptr) / widthptr); |
230 *xoffset += t->width; | 231 *xoffset += t->width; |
231 break; | 232 break; |
232 | 233 |
233 case TARRAY: | 234 case TARRAY: |
| 235 // The value of t->bound is -1 for slices types and >0 for |
| 236 // for fixed array types. All other values are invalid. |
234 if(t->bound < -1) | 237 if(t->bound < -1) |
235 fatal("walktype1: invalid bound, %T", t); | 238 fatal("walktype1: invalid bound, %T", t); |
236 if(isslice(t)) { | 239 if(isslice(t)) { |
237 » » » // struct { byte* array; uint32 len; uint32 cap; } | 240 » » » // struct { byte* array; uintgo len; uintgo cap; } |
238 if(*xoffset % widthptr != 0) | 241 if(*xoffset % widthptr != 0) |
239 fatal("walktype1: invalid TARRAY alignment, %T",
t); | 242 fatal("walktype1: invalid TARRAY alignment, %T",
t); |
240 bvset(bv, *xoffset / widthptr); | 243 bvset(bv, *xoffset / widthptr); |
241 *xoffset += t->width; | 244 *xoffset += t->width; |
242 } else if(!haspointers(t->type)) | 245 } else if(!haspointers(t->type)) |
243 *xoffset += t->width; | 246 *xoffset += t->width; |
244 else | 247 else |
245 for(i = 0; i < t->bound; ++i) | 248 for(i = 0; i < t->bound; ++i) |
246 walktype1(t->type, xoffset, bv); | 249 walktype1(t->type, xoffset, bv); |
247 break; | 250 break; |
(...skipping 12 matching lines...) Expand all Loading... |
260 default: | 263 default: |
261 fatal("walktype1: unexpected type, %T", t); | 264 fatal("walktype1: unexpected type, %T", t); |
262 } | 265 } |
263 } | 266 } |
264 | 267 |
265 static void | 268 static void |
266 walktype(Type *type, Bvec *bv) | 269 walktype(Type *type, Bvec *bv) |
267 { | 270 { |
268 vlong xoffset; | 271 vlong xoffset; |
269 | 272 |
| 273 // Start the walk at offset 0. The correct offset will be |
| 274 // filled in by the first type encountered during the walk. |
270 xoffset = 0; | 275 xoffset = 0; |
271 walktype1(type, &xoffset, bv); | 276 walktype1(type, &xoffset, bv); |
272 } | |
273 | |
274 static int32 | |
275 roundup(int32 x, int32 n) | |
276 { | |
277 return x + (-x & (n - 1)); | |
278 } | 277 } |
279 | 278 |
280 // Compute a bit vector to describes the pointer containing locations | 279 // Compute a bit vector to describes the pointer containing locations |
281 // in the argument list. | 280 // in the argument list. |
282 static void | 281 static void |
283 pointermap(Node *fn) | 282 pointermap(Node *fn) |
284 { | 283 { |
285 vlong thiswidth, inargwidth, outargwidth; | |
286 Type *thistype, *inargtype, *outargtype; | 284 Type *thistype, *inargtype, *outargtype; |
287 Bvec *bv; | 285 Bvec *bv; |
288 Prog *prog; | 286 Prog *prog; |
289 int32 i; | 287 int32 i; |
290 | 288 |
291 thistype = getthisx(fn->type); | 289 thistype = getthisx(fn->type); |
292 thiswidth = (thistype == nil) ? 0 : thistype->width; | |
293 inargtype = getinargx(fn->type); | 290 inargtype = getinargx(fn->type); |
294 inargwidth = (inargtype == nil) ? 0 : inargtype->width; | |
295 outargtype = getoutargx(fn->type); | 291 outargtype = getoutargx(fn->type); |
296 » outargwidth = (outargtype == nil) ? 0 : outargtype->width; | 292 » bv = bvalloc(fn->type->argwid / widthptr); |
297 » if(thiswidth > 0) | |
298 » » if((inargwidth > 0) && (thiswidth < inargtype->align)) | |
299 » » » thiswidth = inargtype->align; | |
300 » » else if((outargwidth > 0) && (thiswidth < outargtype->align)) | |
301 » » » thiswidth = outargtype->align; | |
302 » if(inargwidth > 0) | |
303 » » if((outargwidth > 0) && (inargwidth < outargtype->align)) | |
304 » » » inargwidth = outargtype->align; | |
305 » bv = bvalloc((thiswidth + inargwidth + outargwidth) / widthptr); | |
306 if(thistype != nil) | 293 if(thistype != nil) |
307 walktype(thistype, bv); | 294 walktype(thistype, bv); |
308 if(inargtype != nil) | 295 if(inargtype != nil) |
309 walktype(inargtype, bv); | 296 walktype(inargtype, bv); |
310 if(outargtype != nil) | 297 if(outargtype != nil) |
311 walktype(outargtype, bv); | 298 walktype(outargtype, bv); |
312 » if(bvpopcnt(bv) == 0) { | 299 » if(bvisempty(bv)) { |
313 prog = gins(ANPTRS, N, N); | 300 prog = gins(ANPTRS, N, N); |
314 prog->to.type = D_CONST; | 301 prog->to.type = D_CONST; |
315 prog->to.offset = 0; | 302 prog->to.offset = 0; |
316 } else { | 303 } else { |
317 prog = gins(ANPTRS, N, N); | 304 prog = gins(ANPTRS, N, N); |
318 prog->to.type = D_CONST; | 305 prog->to.type = D_CONST; |
319 » » prog->to.offset = roundup(bv->n, 32) / 32; | 306 » » prog->to.offset = bv->n; |
320 for(i = 0; i < bv->n; i += 32) { | 307 for(i = 0; i < bv->n; i += 32) { |
321 prog = gins(APTRS, N, N); | 308 prog = gins(APTRS, N, N); |
322 prog->from.type = D_CONST; | 309 prog->from.type = D_CONST; |
323 » » » prog->from.offset = i; | 310 » » » prog->from.offset = i / 32; |
324 prog->to.type = D_CONST; | 311 prog->to.type = D_CONST; |
325 prog->to.offset = bv->b[i / 32]; | 312 prog->to.offset = bv->b[i / 32]; |
326 } | 313 } |
327 } | 314 } |
328 free(bv); | 315 free(bv); |
329 } | 316 } |
330 | 317 |
331 // Sort the list of stack variables. autos after anything else, | 318 // Sort the list of stack variables. autos after anything else, |
332 // within autos, unused after used, and within used on reverse alignment. | 319 // within autos, unused after used, and within used on reverse alignment. |
333 // non-autos sort on offset. | 320 // non-autos sort on offset. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 fixautoused(ptxt); | 401 fixautoused(ptxt); |
415 | 402 |
416 // The debug information needs accurate offsets on the symbols. | 403 // The debug information needs accurate offsets on the symbols. |
417 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { | 404 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { |
418 if (ll->n->class != PAUTO || ll->n->op != ONAME) | 405 if (ll->n->class != PAUTO || ll->n->op != ONAME) |
419 continue; | 406 continue; |
420 ll->n->xoffset += ll->n->stkdelta; | 407 ll->n->xoffset += ll->n->stkdelta; |
421 ll->n->stkdelta = 0; | 408 ll->n->stkdelta = 0; |
422 } | 409 } |
423 } | 410 } |
LEFT | RIGHT |