Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(3)

Delta Between Two Patch Sets: src/cmd/gc/pgen.c

Issue 12328044: code review 12328044: cmd/cc, cmd/gc, runtime: emit bitmaps for scanning locals. (Closed)
Left Patch Set: Created 11 years, 7 months ago
Right Patch Set: diff -r 6058f523a441 https://code.google.com/p/go/ Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/cc/pgen.c ('k') | src/pkg/runtime/funcdata.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
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 #include "../../pkg/runtime/funcdata.h" 9 #include "../../pkg/runtime/funcdata.h"
10 10
11 static void allocauto(Prog* p); 11 static void allocauto(Prog* p);
12 static int pointermap(Sym*, int, Node*); 12 static void dumpgcargs(Node*, Sym*);
13 static void gcsymbol(Sym*, Node*); 13 static void dumpgclocals(Node*, Sym*);
14 14
15 void 15 void
16 compile(Node *fn) 16 compile(Node *fn)
17 { 17 {
18 Plist *pl; 18 Plist *pl;
19 » Node nod1, *n, *gcnod; 19 » Node nod1, *n, *gcargsnod, *gclocalsnod;
20 Prog *ptxt, *p, *p1; 20 Prog *ptxt, *p, *p1;
21 int32 lno; 21 int32 lno;
22 Type *t; 22 Type *t;
23 Iter save; 23 Iter save;
24 vlong oldstksize; 24 vlong oldstksize;
25 NodeList *l; 25 NodeList *l;
26 » Sym *gcsym; 26 » Sym *gcargssym, *gclocalssym;
27 » static int ngcsym; 27 » static int ngcargs, ngclocals;
28 28
29 if(newproc == N) { 29 if(newproc == N) {
30 newproc = sysfunc("newproc"); 30 newproc = sysfunc("newproc");
31 deferproc = sysfunc("deferproc"); 31 deferproc = sysfunc("deferproc");
32 deferreturn = sysfunc("deferreturn"); 32 deferreturn = sysfunc("deferreturn");
33 panicindex = sysfunc("panicindex"); 33 panicindex = sysfunc("panicindex");
34 panicslice = sysfunc("panicslice"); 34 panicslice = sysfunc("panicslice");
35 throwreturn = sysfunc("throwreturn"); 35 throwreturn = sysfunc("throwreturn");
36 } 36 }
37 37
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 setlineno(curfn); 86 setlineno(curfn);
87 87
88 nodconst(&nod1, types[TINT32], 0); 88 nodconst(&nod1, types[TINT32], 0);
89 ptxt = gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1); 89 ptxt = gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
90 if(fn->dupok) 90 if(fn->dupok)
91 ptxt->TEXTFLAG = DUPOK; 91 ptxt->TEXTFLAG = DUPOK;
92 afunclit(&ptxt->from, curfn->nname); 92 afunclit(&ptxt->from, curfn->nname);
93 93
94 ginit(); 94 ginit();
95 95
96 » snprint(namebuf, sizeof namebuf, "gc·%d", ngcsym++); 96 » snprint(namebuf, sizeof namebuf, "gcargs·%d", ngcargs++);
97 » gcsym = lookup(namebuf); 97 » gcargssym = lookup(namebuf);
98 » gcnod = newname(gcsym); 98 » gcargsnod = newname(gcargssym);
99 » gcnod->class = PEXTERN; 99 » gcargsnod->class = PEXTERN;
100 100
101 » nodconst(&nod1, types[TINT32], FUNCDATA_GC); 101 » nodconst(&nod1, types[TINT32], FUNCDATA_GCArgs);
102 » gins(AFUNCDATA, &nod1, gcnod); 102 » gins(AFUNCDATA, &nod1, gcargsnod);
103
104 » snprint(namebuf, sizeof(namebuf), "gclocals·%d", ngclocals++);
105 » gclocalssym = lookup(namebuf);
106 » gclocalsnod = newname(gclocalssym);
107 » gclocalsnod->class = PEXTERN;
108
109 » nodconst(&nod1, types[TINT32], FUNCDATA_GCLocals);
110 » gins(AFUNCDATA, &nod1, gclocalsnod);
103 111
104 for(t=curfn->paramfld; t; t=t->down) 112 for(t=curfn->paramfld; t; t=t->down)
105 gtrack(tracksym(t->type)); 113 gtrack(tracksym(t->type));
106 114
107 for(l=fn->dcl; l; l=l->next) { 115 for(l=fn->dcl; l; l=l->next) {
108 n = l->n; 116 n = l->n;
109 if(n->op != ONAME) // might be OTYPE or OLITERAL 117 if(n->op != ONAME) // might be OTYPE or OLITERAL
110 continue; 118 continue;
111 switch(n->class) { 119 switch(n->class) {
112 case PAUTO: 120 case PAUTO:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 160
153 pc->as = ARET; // overwrite AEND 161 pc->as = ARET; // overwrite AEND
154 pc->lineno = lineno; 162 pc->lineno = lineno;
155 163
156 if(!debug['N'] || debug['R'] || debug['P']) { 164 if(!debug['N'] || debug['R'] || debug['P']) {
157 regopt(ptxt); 165 regopt(ptxt);
158 } 166 }
159 167
160 oldstksize = stksize; 168 oldstksize = stksize;
161 allocauto(ptxt); 169 allocauto(ptxt);
162 ········
163 // Emit garbage collection symbol.
164 gcsymbol(gcsym, fn);
165 170
166 if(0) 171 if(0)
167 print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize); 172 print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize);
168 173
169 setlineno(curfn); 174 setlineno(curfn);
170 » if((int64)stksize+maxarg > (1ULL<<31)) 175 » if((int64)stksize+maxarg > (1ULL<<31)) {
171 yyerror("stack frame too large (>2GB)"); 176 yyerror("stack frame too large (>2GB)");
177 goto ret;
178 }
172 179
173 defframe(ptxt); 180 defframe(ptxt);
174 181
175 if(0) 182 if(0)
176 frame(0); 183 frame(0);
177 184
185 // Emit garbage collection symbols.
186 dumpgcargs(fn, gcargssym);
187 dumpgclocals(curfn, gclocalssym);
188
178 ret: 189 ret:
179 lineno = lno; 190 lineno = lno;
180 }
181
182 static void
183 gcsymbol(Sym *gcsym, Node *fn)
184 {
185 int off;
186
187 off = 0;
188 off = duint32(gcsym, off, stksize); // size of local block
189 off = pointermap(gcsym, off, fn); // pointer bitmap for args (must be la st)
190 ggloblsym(gcsym, off, 0, 1);
191 } 191 }
192 192
193 static void 193 static void
194 walktype1(Type *t, vlong *xoffset, Bvec *bv) 194 walktype1(Type *t, vlong *xoffset, Bvec *bv)
195 { 195 {
196 vlong fieldoffset, i, o; 196 vlong fieldoffset, i, o;
197 Type *t1; 197 Type *t1;
198 198
199 if(t->align > 0 && (*xoffset % t->align) != 0) 199 if(t->align > 0 && (*xoffset % t->align) != 0)
200 fatal("walktype1: invalid initial alignment, %T", t); 200 fatal("walktype1: invalid initial alignment, %T", t);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 { 289 {
290 vlong xoffset; 290 vlong xoffset;
291 291
292 // Start the walk at offset 0. The correct offset will be 292 // Start the walk at offset 0. The correct offset will be
293 // filled in by the first type encountered during the walk. 293 // filled in by the first type encountered during the walk.
294 xoffset = 0; 294 xoffset = 0;
295 walktype1(type, &xoffset, bv); 295 walktype1(type, &xoffset, bv);
296 } 296 }
297 297
298 // Compute a bit vector to describes the pointer containing locations 298 // Compute a bit vector to describes the pointer containing locations
299 // in the argument list. 299 // in the in and out argument list and dump the bitvector length and
300 static int 300 // data to the provided symbol.
301 pointermap(Sym *gcsym, int off, Node *fn) 301 static void
302 dumpgcargs(Node *fn, Sym *sym)
302 { 303 {
303 Type *thistype, *inargtype, *outargtype; 304 Type *thistype, *inargtype, *outargtype;
304 Bvec *bv; 305 Bvec *bv;
305 int32 i; 306 int32 i;
307 int off;
306 308
307 thistype = getthisx(fn->type); 309 thistype = getthisx(fn->type);
308 inargtype = getinargx(fn->type); 310 inargtype = getinargx(fn->type);
309 outargtype = getoutargx(fn->type); 311 outargtype = getoutargx(fn->type);
310 bv = bvalloc(fn->type->argwid / widthptr); 312 bv = bvalloc(fn->type->argwid / widthptr);
311 if(thistype != nil) 313 if(thistype != nil)
312 walktype(thistype, bv); 314 walktype(thistype, bv);
313 if(inargtype != nil) 315 if(inargtype != nil)
314 walktype(inargtype, bv); 316 walktype(inargtype, bv);
315 if(outargtype != nil) 317 if(outargtype != nil)
316 walktype(outargtype, bv); 318 walktype(outargtype, bv);
317 » off = duint32(gcsym, off, bv->n); 319 » off = duint32(sym, 0, bv->n);
318 for(i = 0; i < bv->n; i += 32) 320 for(i = 0; i < bv->n; i += 32)
319 » » off = duint32(gcsym, off, bv->b[i/32]); 321 » » off = duint32(sym, off, bv->b[i/32]);
320 free(bv); 322 free(bv);
321 » return off; 323 » ggloblsym(sym, off, 0, 1);
324 }
325
326 // Compute a bit vector to describes the pointer containing locations
327 // in local variables and dumps the bitvector length and data out to
328 // the provided symbol.
329 static void
330 dumpgclocals(Node* fn, Sym *sym)
331 {
332 » Bvec *bv;
333 » NodeList *ll;
334 » Node *node;
335 » vlong xoffset;
336 » int32 i;
337 » int off;
338
339 » bv = bvalloc(rnd(stksize, widthptr) / widthptr);
340 » for(ll = fn->dcl; ll != nil; ll = ll->next) {
341 » » node = ll->n;
342 » » if(node->class == PAUTO && node->op == ONAME) {
343 » » » if(haspointers(node->type)) {
344 » » » » xoffset = node->xoffset + rnd(stksize,widthptr);
345 » » » » walktype1(node->type, &xoffset, bv);
346 » » » }
347 » » }
348 » }
349 » off = duint32(sym, 0, bv->n);
350 » for(i = 0; i < bv->n; i += 32) {
351 » » off = duint32(sym, off, bv->b[i/32]);
352 » }
353 » free(bv);
354 » ggloblsym(sym, off, 0, 1);
322 } 355 }
323 356
324 // Sort the list of stack variables. autos after anything else, 357 // Sort the list of stack variables. autos after anything else,
325 // within autos, unused after used, and within used on reverse alignment. 358 // within autos, unused after used, and within used on reverse alignment.
326 // non-autos sort on offset. 359 // non-autos sort on offset.
327 static int 360 static int
328 cmpstackvar(Node *a, Node *b) 361 cmpstackvar(Node *a, Node *b)
329 { 362 {
330 if (a->class != b->class) 363 if (a->class != b->class)
331 return (a->class == PAUTO) ? 1 : -1; 364 return (a->class == PAUTO) ? 1 : -1;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 fixautoused(ptxt); 440 fixautoused(ptxt);
408 441
409 // The debug information needs accurate offsets on the symbols. 442 // The debug information needs accurate offsets on the symbols.
410 for(ll = curfn->dcl ;ll != nil; ll=ll->next) { 443 for(ll = curfn->dcl ;ll != nil; ll=ll->next) {
411 if (ll->n->class != PAUTO || ll->n->op != ONAME) 444 if (ll->n->class != PAUTO || ll->n->op != ONAME)
412 continue; 445 continue;
413 ll->n->xoffset += ll->n->stkdelta; 446 ll->n->xoffset += ll->n->stkdelta;
414 ll->n->stkdelta = 0; 447 ll->n->stkdelta = 0;
415 } 448 }
416 } 449 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b