Left: | ||
Right: |
OLD | NEW |
---|---|
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 pointermap(Node* fn); | |
11 | 12 |
12 void | 13 void |
13 compile(Node *fn) | 14 compile(Node *fn) |
14 { | 15 { |
15 Plist *pl; | 16 Plist *pl; |
16 Node nod1, *n; | 17 Node nod1, *n; |
17 Prog *plocals, *ptxt, *p, *p1; | 18 Prog *plocals, *ptxt, *p, *p1; |
18 int32 lno; | 19 int32 lno; |
19 Type *t; | 20 Type *t; |
20 Iter save; | 21 Iter save; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 case PAUTO: | 102 case PAUTO: |
102 case PPARAM: | 103 case PPARAM: |
103 case PPARAMOUT: | 104 case PPARAMOUT: |
104 nodconst(&nod1, types[TUINTPTR], l->n->type->width); | 105 nodconst(&nod1, types[TUINTPTR], l->n->type->width); |
105 p = gins(ATYPE, l->n, &nod1); | 106 p = gins(ATYPE, l->n, &nod1); |
106 p->from.gotype = ngotype(l->n); | 107 p->from.gotype = ngotype(l->n); |
107 break; | 108 break; |
108 } | 109 } |
109 } | 110 } |
110 | 111 |
112 pointermap(fn); | |
113 | |
111 genlist(curfn->enter); | 114 genlist(curfn->enter); |
112 | 115 |
113 retpc = nil; | 116 retpc = nil; |
114 if(hasdefer || curfn->exit) { | 117 if(hasdefer || curfn->exit) { |
115 p1 = gjmp(nil); | 118 p1 = gjmp(nil); |
116 retpc = gjmp(nil); | 119 retpc = gjmp(nil); |
117 patch(p1, pc); | 120 patch(p1, pc); |
118 } | 121 } |
119 | 122 |
120 genlist(curfn->nbody); | 123 genlist(curfn->nbody); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 | 164 |
162 defframe(ptxt); | 165 defframe(ptxt); |
163 | 166 |
164 if(0) | 167 if(0) |
165 frame(0); | 168 frame(0); |
166 | 169 |
167 ret: | 170 ret: |
168 lineno = lno; | 171 lineno = lno; |
169 } | 172 } |
170 | 173 |
174 static void | |
175 walktype1(Type *t, vlong *xoffset, Bvec *bv) | |
176 { | |
177 vlong fieldoffset, i, o; | |
178 Type *t1; | |
179 | |
180 if(t->align > 0 && (*xoffset % t->align) != 0) | |
181 fatal("walktype1: invalid initial alignment, %T", t); | |
182 | |
183 switch(t->etype) { | |
184 case TINT8: | |
185 case TUINT8: | |
186 case TINT16: | |
187 case TUINT16: | |
188 case TINT32: | |
189 case TUINT32: | |
190 case TINT64: | |
191 case TUINT64: | |
192 case TINT: | |
193 case TUINT: | |
194 case TUINTPTR: | |
195 case TBOOL: | |
196 case TFLOAT32: | |
197 case TFLOAT64: | |
198 case TCOMPLEX64: | |
199 case TCOMPLEX128: | |
200 *xoffset += t->width; | |
201 break; | |
202 | |
203 case TPTR32: | |
204 case TPTR64: | |
205 case TUNSAFEPTR: | |
206 case TFUNC: | |
207 case TCHAN: | |
208 case TMAP: | |
209 if(*xoffset % widthptr != 0) | |
210 fatal("walktype1: invalid alignment, %T", t); | |
211 bvset(bv, *xoffset / widthptr); | |
212 *xoffset += t->width; | |
213 break; | |
214 | |
215 case TSTRING: | |
216 // struct { byte *str; intgo len; } | |
217 if(*xoffset % widthptr != 0) | |
218 fatal("walktype1: invalid alignment, %T", t); | |
219 bvset(bv, *xoffset / widthptr); | |
220 *xoffset += t->width; | |
221 break; | |
222 | |
223 case TINTER: | |
224 // struct { Itab* tab; union { void* ptr, uintptr val } data; } | |
225 // or, when isnilinter(t)==true: | |
226 // struct { Type* type; union { void* ptr, uintptr val } data; } | |
227 if(*xoffset % widthptr != 0) | |
228 fatal("walktype1: invalid alignment, %T", t); | |
229 bvset(bv, *xoffset / widthptr); | |
230 bvset(bv, (*xoffset + widthptr) / widthptr); | |
231 *xoffset += t->width; | |
232 break; | |
233 | |
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. | |
237 if(t->bound < -1) | |
238 fatal("walktype1: invalid bound, %T", t); | |
239 if(isslice(t)) { | |
240 // struct { byte* array; uintgo len; uintgo cap; } | |
241 if(*xoffset % widthptr != 0) | |
242 fatal("walktype1: invalid TARRAY alignment, %T", t); | |
243 bvset(bv, *xoffset / widthptr); | |
244 *xoffset += t->width; | |
245 } else if(!haspointers(t->type)) | |
246 *xoffset += t->width; | |
247 else | |
248 for(i = 0; i < t->bound; ++i) | |
249 walktype1(t->type, xoffset, bv); | |
250 break; | |
251 | |
252 case TSTRUCT: | |
253 o = 0; | |
254 for(t1 = t->type; t1 != T; t1 = t1->down) { | |
255 fieldoffset = t1->width; | |
256 *xoffset += fieldoffset - o; | |
257 walktype1(t1->type, xoffset, bv); | |
258 o = fieldoffset + t1->type->width; | |
259 } | |
260 *xoffset += t->width - o; | |
261 break; | |
262 | |
263 default: | |
264 fatal("walktype1: unexpected type, %T", t); | |
265 } | |
266 } | |
267 | |
268 static void | |
269 walktype(Type *type, Bvec *bv) | |
270 { | |
271 vlong xoffset; | |
272 | |
273 xoffset = 0; | |
274 walktype1(type, &xoffset, bv); | |
275 } | |
276 | |
277 static int32 | |
278 roundup(int32 x, int32 n) | |
279 { | |
280 return x + (-x & (n - 1)); | |
281 } | |
282 | |
283 // Compute a bit vector to describes the pointer containing locations | |
284 // in the argument list. | |
285 static void | |
286 pointermap(Node *fn) | |
287 { | |
288 vlong thiswidth, inargwidth, outargwidth; | |
289 Type *thistype, *inargtype, *outargtype; | |
290 Bvec *bv; | |
291 Prog *prog; | |
292 int32 i; | |
293 | |
294 thistype = getthisx(fn->type); | |
295 thiswidth = (thistype == nil) ? 0 : thistype->width; | |
296 inargtype = getinargx(fn->type); | |
297 inargwidth = (inargtype == nil) ? 0 : inargtype->width; | |
298 outargtype = getoutargx(fn->type); | |
299 outargwidth = (outargtype == nil) ? 0 : outargtype->width; | |
300 if(thiswidth > 0) | |
301 if((inargwidth > 0) && (thiswidth < inargtype->align)) | |
302 thiswidth = inargtype->align; | |
303 else if((outargwidth > 0) && (thiswidth < outargtype->align)) | |
304 thiswidth = outargtype->align; | |
305 if(inargwidth > 0) | |
306 if((outargwidth > 0) && (inargwidth < outargtype->align)) | |
307 inargwidth = outargtype->align; | |
308 bv = bvalloc((thiswidth + inargwidth + outargwidth) / widthptr); | |
309 if(thistype != nil) | |
DMorsing
2013/05/22 09:29:48
This could be done more cleanly by using the fn->d
cshapiro1
2013/05/22 23:19:11
I started by using the fn->dcl list but I had diff
DMorsing
2013/05/23 06:25:09
The this parameter shows up in dcl as a node with
| |
310 walktype(thistype, bv); | |
311 if(inargtype != nil) | |
312 walktype(inargtype, bv); | |
313 if(outargtype != nil) | |
314 walktype(outargtype, bv); | |
315 if(bvisempty(bv)) { | |
316 prog = gins(ANPTRS, N, N); | |
317 prog->to.type = D_CONST; | |
318 prog->to.offset = 0; | |
319 } else { | |
320 prog = gins(ANPTRS, N, N); | |
321 prog->to.type = D_CONST; | |
322 prog->to.offset = roundup(bv->n, 32) / 32; | |
323 for(i = 0; i < bv->n; i += 32) { | |
324 prog = gins(APTRS, N, N); | |
325 prog->from.type = D_CONST; | |
326 prog->from.offset = i / 32; | |
327 prog->to.type = D_CONST; | |
328 prog->to.offset = bv->b[i / 32]; | |
329 } | |
330 } | |
331 free(bv); | |
332 } | |
171 | 333 |
172 // Sort the list of stack variables. autos after anything else, | 334 // Sort the list of stack variables. autos after anything else, |
173 // within autos, unused after used, and within used on reverse alignment. | 335 // within autos, unused after used, and within used on reverse alignment. |
174 // non-autos sort on offset. | 336 // non-autos sort on offset. |
175 static int | 337 static int |
176 cmpstackvar(Node *a, Node *b) | 338 cmpstackvar(Node *a, Node *b) |
177 { | 339 { |
178 if (a->class != b->class) | 340 if (a->class != b->class) |
179 return (a->class == PAUTO) ? 1 : -1; | 341 return (a->class == PAUTO) ? 1 : -1; |
180 if (a->class != PAUTO) { | 342 if (a->class != PAUTO) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 fixautoused(ptxt); | 417 fixautoused(ptxt); |
256 | 418 |
257 // The debug information needs accurate offsets on the symbols. | 419 // The debug information needs accurate offsets on the symbols. |
258 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { | 420 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { |
259 if (ll->n->class != PAUTO || ll->n->op != ONAME) | 421 if (ll->n->class != PAUTO || ll->n->op != ONAME) |
260 continue; | 422 continue; |
261 ll->n->xoffset += ll->n->stkdelta; | 423 ll->n->xoffset += ll->n->stkdelta; |
262 ll->n->stkdelta = 0; | 424 ll->n->stkdelta = 0; |
263 } | 425 } |
264 } | 426 } |
OLD | NEW |