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; | |
iant
2013/05/28 21:23:36
I think we should have a comment somewhere explain
cshapiro1
2013/05/29 00:29:20
Done.
| |
274 walktype1(type, &xoffset, bv); | |
275 } | |
276 | |
277 // Compute a bit vector to describes the pointer containing locations | |
278 // in the argument list. | |
279 static void | |
280 pointermap(Node *fn) | |
281 { | |
282 Type *thistype, *inargtype, *outargtype; | |
283 Bvec *bv; | |
284 Prog *prog; | |
285 int32 i; | |
286 | |
287 thistype = getthisx(fn->type); | |
288 inargtype = getinargx(fn->type); | |
289 outargtype = getoutargx(fn->type); | |
290 bv = bvalloc(fn->type->argwid / widthptr); | |
291 if(thistype != nil) | |
292 walktype(thistype, bv); | |
293 if(inargtype != nil) | |
294 walktype(inargtype, bv); | |
295 if(outargtype != nil) | |
296 walktype(outargtype, bv); | |
297 if(bvisempty(bv)) { | |
298 prog = gins(ANPTRS, N, N); | |
299 prog->to.type = D_CONST; | |
300 prog->to.offset = 0; | |
301 } else { | |
302 prog = gins(ANPTRS, N, N); | |
303 prog->to.type = D_CONST; | |
304 prog->to.offset = bv->n; | |
305 for(i = 0; i < bv->n; i += 32) { | |
306 prog = gins(APTRS, N, N); | |
307 prog->from.type = D_CONST; | |
308 prog->from.offset = i / 32; | |
309 prog->to.type = D_CONST; | |
310 prog->to.offset = bv->b[i / 32]; | |
311 } | |
312 } | |
313 free(bv); | |
314 } | |
171 | 315 |
172 // Sort the list of stack variables. autos after anything else, | 316 // Sort the list of stack variables. autos after anything else, |
173 // within autos, unused after used, and within used on reverse alignment. | 317 // within autos, unused after used, and within used on reverse alignment. |
174 // non-autos sort on offset. | 318 // non-autos sort on offset. |
175 static int | 319 static int |
176 cmpstackvar(Node *a, Node *b) | 320 cmpstackvar(Node *a, Node *b) |
177 { | 321 { |
178 if (a->class != b->class) | 322 if (a->class != b->class) |
179 return (a->class == PAUTO) ? 1 : -1; | 323 return (a->class == PAUTO) ? 1 : -1; |
180 if (a->class != PAUTO) { | 324 if (a->class != PAUTO) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 fixautoused(ptxt); | 399 fixautoused(ptxt); |
256 | 400 |
257 // The debug information needs accurate offsets on the symbols. | 401 // The debug information needs accurate offsets on the symbols. |
258 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { | 402 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { |
259 if (ll->n->class != PAUTO || ll->n->op != ONAME) | 403 if (ll->n->class != PAUTO || ll->n->op != ONAME) |
260 continue; | 404 continue; |
261 ll->n->xoffset += ll->n->stkdelta; | 405 ll->n->xoffset += ll->n->stkdelta; |
262 ll->n->stkdelta = 0; | 406 ll->n->stkdelta = 0; |
263 } | 407 } |
264 } | 408 } |
OLD | NEW |