Previously, the func structure contained an inaccurate value for
the args member and a 0 value for the locals member.
This change populates the func structure with args and locals
values computed by the compiler. The number of args was
already available in the ATEXT instruction. The number of
locals is now passed through in the new ALOCALS instruction.
This change also switches the unit of args and locals to be
bytes, just like the frame member, instead of 32-bit words.
R=golang-dev, bradfitz, cshapiro, dave, rsc
CC=golang-dev
https://golang.org/cl/
7399045
if(v->reg == (uchar)REGARG)
return 3;
return 0;
+
+ case ALOCALS: /* funny */
+ return 0;
}
}
AMULAWB,
AUSEFIELD,
+ ALOCALS,
ALAST,
};
int32 size;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
+ int32 locals; // size of stack frame locals area
+ int32 args; // size of stack frame incoming arguments area
uchar special;
uchar fnptr; // used as fn ptr
uchar stkcheck;
pc++;
break;
+ case ALOCALS:
+ cursym->locals = p->to.offset;
+ pc++;
+ break;
+
case ATEXT:
if(cursym != nil && cursym->text) {
histtoauto();
s->type = STEXT;
s->text = p;
s->value = pc;
+ s->args = p->to.offset2;
lastp = p;
p->pc = pc;
pc++;
case ARFE:
case ATEXT:
case AUSEFIELD:
+ case ALOCALS:
case ACASE:
case ABCASE:
break;
APSHUFD,
AUSEFIELD,
+ ALOCALS,
ALAST
};
int32 got;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
+ int32 locals; // size of stack frame locals area
+ int32 args; // size of stack frame incoming arguments area
Sym* hash; // in hash table
Sym* allsym; // in all symbol list
Sym* next; // in text or data list
pc++;
goto loop;
+ case ALOCALS:
+ cursym->locals = p->to.offset;
+ pc++;
+ goto loop;
+
case ATEXT:
s = p->from.sym;
if(s->text != nil) {
}
s->type = STEXT;
s->value = pc;
+ s->args = p->to.offset >> 32;
lastp = p;
p->pc = pc++;
goto loop;
{ APSHUFD, yaes2, Pq, 0x70,(0) },
{ AUSEFIELD, ynop, Px, 0,0 },
+ { ALOCALS },
{ AEND },
0
AXORPS,
AUSEFIELD,
+ ALOCALS,
ALAST
};
int32 got;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
+ int32 locals; // size of stack frame locals area
+ int32 args; // size of stack frame incoming arguments area
Sym* hash; // in hash table
Sym* allsym; // in all symbol list
Sym* next; // in text or data list
pc++;
goto loop;
+ case ALOCALS:
+ cursym->locals = p->to.offset;
+ pc++;
+ goto loop;
+
case ATEXT:
s = p->from.sym;
if(s->text != nil) {
}
s->type = STEXT;
s->value = pc;
+ s->args = p->to.offset2;
lastp = p;
p->pc = pc++;
goto loop;
{ AXORPS, yxm, Pm, 0x57 },
{ AUSEFIELD, ynop, Px, 0,0 },
+ { ALOCALS },
0
};
{
Plist *pl;
Node nod1, *n;
- Prog *ptxt;
+ Prog *plocals, *ptxt;
int32 lno;
Type *t;
Iter save;
ginit();
+ plocals = gins(ALOCALS, N, N);
+
for(t=curfn->paramfld; t; t=t->down)
gtrack(tracksym(t->type));
oldstksize = stksize;
allocauto(ptxt);
+
+ plocals->to.offset = stksize;
+
if(0)
print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize);
put(s, s->name, 'T', s->value, s->size, s->version, s->gotype);
- /* frame, auto and param after */
+ /* frame, locals, args, auto and param after */
put(nil, ".frame", 'm', s->text->to.offset+PtrSize, 0, 0, 0);
+ put(nil, ".locals", 'm', s->locals, 0, 0, 0);
+ put(nil, ".args", 'm', s->args, 0, 0, 0);
for(a=s->autom; a; a=a->link)
if(a->type == D_AUTO)
pc0 uintptr // starting pc, ln for table
ln0 int32
frame int32 // stack frame size
- args int32 // number of 32-bit in/out args
- locals int32 // number of 32-bit locals
+ args int32 // in/out args size
+ locals int32 // locals size
}
// FuncForPC returns a *Func describing the function that contains the
uintptr pc0; // starting pc, ln for table
int32 ln0;
int32 frame; // stack frame size
- int32 args; // number of 32-bit in/out args
- int32 locals; // number of 32-bit locals
+ int32 args; // in/out args size
+ int32 locals; // locals size
};
// layout of Itab known to compilers
f->frame = -sizeof(uintptr);
break;
case 'm':
- if(nfunc > 0 && func != nil)
- func[nfunc-1].frame += sym->value;
- break;
- case 'p':
- if(nfunc > 0 && func != nil) {
- f = &func[nfunc-1];
- // args counts 32-bit words.
- // sym->value is the arg's offset.
- // don't know width of this arg, so assume it is 64 bits.
- if(f->args < sym->value/4 + 2)
- f->args = sym->value/4 + 2;
+ if(nfunc <= 0 || func == nil)
+ break;
+ if(runtime·strcmp(sym->name, (byte*)".frame") == 0)
+ func[nfunc-1].frame = sym->value;
+ else if(runtime·strcmp(sym->name, (byte*)".locals") == 0)
+ func[nfunc-1].locals = sym->value;
+ else if(runtime·strcmp(sym->name, (byte*)".args") == 0)
+ func[nfunc-1].args = sym->value;
+ else {
+ runtime·printf("invalid 'm' symbol named '%s'\n", sym->name);
+ runtime·throw("mangled symbol table");
}
break;
case 'f':
if(m->throwing && gp == m->curg)
runtime·printf("[fp=%p] ", fp);
runtime·printf("%S(", f->name);
- for(i = 0; i < f->args; i++) {
+ for(i = 0; i < f->args/sizeof(uintptr); i++) {
if(i != 0)
runtime·prints(", ");
runtime·printhex(((uintptr*)fp)[1+i]);
if(m->throwing && gp == m->curg)
runtime·printf("[fp=%p] ", fp);
runtime·printf("%S(", f->name);
- for(i = 0; i < f->args; i++) {
+ for(i = 0; i < f->args/sizeof(uintptr); i++) {
if(i != 0)
runtime·prints(", ");
runtime·printhex(((uintptr*)fp)[i]);