Left: | ||
Right: |
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); |
11 static void stackmap(Node *fn); | 11 static void pointermap(Node* fn); |
12 | 12 |
13 void | 13 void |
14 compile(Node *fn) | 14 compile(Node *fn) |
15 { | 15 { |
16 Plist *pl; | 16 Plist *pl; |
17 Node nod1, *n; | 17 Node nod1, *n; |
18 Prog *plocals, *ptxt, *p, *p1; | 18 Prog *plocals, *ptxt, *p, *p1; |
19 int32 lno; | 19 int32 lno; |
20 Type *t; | 20 Type *t; |
21 Iter save; | 21 Iter save; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 case PAUTO: | 102 case PAUTO: |
103 case PPARAM: | 103 case PPARAM: |
104 case PPARAMOUT: | 104 case PPARAMOUT: |
105 nodconst(&nod1, types[TUINTPTR], l->n->type->width); | 105 nodconst(&nod1, types[TUINTPTR], l->n->type->width); |
106 p = gins(ATYPE, l->n, &nod1); | 106 p = gins(ATYPE, l->n, &nod1); |
107 p->from.gotype = ngotype(l->n); | 107 p->from.gotype = ngotype(l->n); |
108 break; | 108 break; |
109 } | 109 } |
110 } | 110 } |
111 | 111 |
112 » stackmap(fn); | 112 » pointermap(fn); |
113 | 113 |
114 genlist(curfn->enter); | 114 genlist(curfn->enter); |
115 | 115 |
116 retpc = nil; | 116 retpc = nil; |
117 if(hasdefer || curfn->exit) { | 117 if(hasdefer || curfn->exit) { |
118 p1 = gjmp(nil); | 118 p1 = gjmp(nil); |
119 retpc = gjmp(nil); | 119 retpc = gjmp(nil); |
120 patch(p1, pc); | 120 patch(p1, pc); |
121 } | 121 } |
122 | 122 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 defframe(ptxt); | 165 defframe(ptxt); |
166 | 166 |
167 if(0) | 167 if(0) |
168 frame(0); | 168 frame(0); |
169 | 169 |
170 ret: | 170 ret: |
171 lineno = lno; | 171 lineno = lno; |
172 } | 172 } |
173 | 173 |
174 static void | 174 static void |
175 walktype1(Type *t, vlong *xoffset, Bvec *bv) | 175 walktype1(Type *t, vlong *xoffset, Bvec *bv) |
khr
2013/05/09 21:49:53
This code allocates slots for the arguments. We m
cshapiro1
2013/05/09 22:00:39
I am not sure I fully understand what you mean by
| |
176 { | 176 { |
177 vlong fieldoffset, i, o; | 177 vlong fieldoffset, i, o; |
178 Type *t1; | 178 Type *t1; |
179 | 179 |
180 if(t->align > 0 && (*xoffset % t->align) != 0) | 180 if(t->align > 0 && (*xoffset % t->align) != 0) |
181 fatal("walktype1: invalid initial alignment, %T", t); | 181 fatal("walktype1: invalid initial alignment, %T", t); |
182 | 182 |
183 switch(t->etype) { | 183 switch(t->etype) { |
184 case TINT8: | 184 case TINT8: |
185 case TUINT8: | 185 case TUINT8: |
(...skipping 20 matching lines...) Expand all 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 stackmap(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((thistype != nil) && (inargtype != nil) && (thiswidth < inargtype->al ign)) | |
298 » » thiswidth = inargtype->align; | |
299 » if((inargtype != nil) && (outargtype != nil) && (inargwidth < outargtype ->align)) | |
300 » » inargwidth = outargtype->align; | |
301 » bv = bvalloc((thiswidth + inargwidth + outargwidth) / widthptr); | |
302 if(thistype != nil) | 293 if(thistype != nil) |
303 walktype(thistype, bv); | 294 walktype(thistype, bv); |
304 if(inargtype != nil) | 295 if(inargtype != nil) |
305 walktype(inargtype, bv); | 296 walktype(inargtype, bv); |
306 if(outargtype != nil) | 297 if(outargtype != nil) |
307 walktype(outargtype, bv); | 298 walktype(outargtype, bv); |
308 » if(bv->n != 0) { | 299 » if(bvisempty(bv)) { |
309 prog = gins(ANPTRS, N, N); | 300 prog = gins(ANPTRS, N, N); |
310 prog->to.type = D_CONST; | 301 prog->to.type = D_CONST; |
311 » » prog->to.offset = roundup(bv->n, 32) / 32; | 302 » » prog->to.offset = 0; |
312 » } | 303 » } else { |
313 » for(i = 0; i < bv->n; i += 32) { | 304 » » prog = gins(ANPTRS, N, N); |
314 » » prog = gins(APTRS, N, N); | |
315 » » prog->from.type = D_CONST; | |
316 » » prog->from.offset = i; | |
317 prog->to.type = D_CONST; | 305 prog->to.type = D_CONST; |
318 » » prog->to.offset = bv->b[i / 32]; | 306 » » prog->to.offset = bv->n; |
307 » » for(i = 0; i < bv->n; i += 32) { | |
308 » » » prog = gins(APTRS, N, N); | |
309 » » » prog->from.type = D_CONST; | |
310 » » » prog->from.offset = i / 32; | |
311 » » » prog->to.type = D_CONST; | |
312 » » » prog->to.offset = bv->b[i / 32]; | |
313 » » } | |
319 } | 314 } |
320 free(bv); | 315 free(bv); |
321 } | 316 } |
322 | 317 |
323 // Sort the list of stack variables. autos after anything else, | 318 // Sort the list of stack variables. autos after anything else, |
324 // within autos, unused after used, and within used on reverse alignment. | 319 // within autos, unused after used, and within used on reverse alignment. |
325 // non-autos sort on offset. | 320 // non-autos sort on offset. |
326 static int | 321 static int |
327 cmpstackvar(Node *a, Node *b) | 322 cmpstackvar(Node *a, Node *b) |
328 { | 323 { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
406 fixautoused(ptxt); | 401 fixautoused(ptxt); |
407 | 402 |
408 // The debug information needs accurate offsets on the symbols. | 403 // The debug information needs accurate offsets on the symbols. |
409 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { | 404 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { |
410 if (ll->n->class != PAUTO || ll->n->op != ONAME) | 405 if (ll->n->class != PAUTO || ll->n->op != ONAME) |
411 continue; | 406 continue; |
412 ll->n->xoffset += ll->n->stkdelta; | 407 ll->n->xoffset += ll->n->stkdelta; |
413 ll->n->stkdelta = 0; | 408 ll->n->stkdelta = 0; |
414 } | 409 } |
415 } | 410 } |
LEFT | RIGHT |