1
0
mirror of https://github.com/golang/go synced 2024-09-30 02:34:40 -06:00

undo CL 13010045 / 04f8101b46dd

Update the original change but do not read interface types in
the arguments area.  Once the arguments area is zeroed as the
locals area is we can safely read interface type values there
too.

««« original CL description
undo CL 12785045 / 71ce80dc4195

This has broken the 32-bit builds.

««« original CL description
cmd/gc, runtime: use type information to scan interface values

R=golang-dev, rsc, dvyukov
CC=golang-dev
https://golang.org/cl/12785045
»»»

R=khr, golang-dev, khr
CC=golang-dev
https://golang.org/cl/13010045
»»»

R=khr, khr
CC=golang-dev
https://golang.org/cl/13073045
This commit is contained in:
Carl Shapiro 2013-08-21 13:51:00 -07:00
parent fcf6a7e5ce
commit 87fdb8fb9a
2 changed files with 43 additions and 12 deletions

View File

@ -257,7 +257,6 @@ walktype1(Type *t, vlong *xoffset, Bvec *bv)
bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1);
if(isnilinter(t))
bvset(bv, ((*xoffset / widthptr) * BitsPerPointer));
bvset(bv, ((*xoffset + widthptr) / widthptr) * BitsPerPointer);
*xoffset += t->width;
break;

View File

@ -36,6 +36,10 @@ enum {
// Pointer map
BitsPerPointer = 2,
BitsNoPointer = 0,
BitsPointer = 1,
BitsIface = 2,
BitsEface = 3,
};
// Bits in per-word bitmap.
@ -1398,26 +1402,52 @@ struct BitVector
uint32 data[];
};
// Scans an interface data value when the interface type indicates
// that it is a pointer.
static void
scaninterfacedata(uintptr bits, byte *scanp, bool afterprologue)
{
Itab *tab;
Type *type;
if(afterprologue) {
if(bits == BitsIface) {
tab = *(Itab**)scanp;
if(tab->type->size <= sizeof(void*) && (tab->type->kind & KindNoPointers))
return;
} else { // bits == BitsEface
type = *(Type**)scanp;
if(type->size <= sizeof(void*) && (type->kind & KindNoPointers))
return;
}
}
addroot((Obj){scanp+PtrSize, PtrSize, 0});
}
// Starting from scanp, scans words corresponding to set bits.
static void
scanbitvector(byte *scanp, BitVector *bv)
scanbitvector(byte *scanp, BitVector *bv, bool afterprologue)
{
uint32 *wp;
uint32 w;
uintptr word, bits;
uint32 *wordp;
int32 i, remptrs;
wp = bv->data;
wordp = bv->data;
for(remptrs = bv->n; remptrs > 0; remptrs -= 32) {
w = *wp++;
word = *wordp++;
if(remptrs < 32)
i = remptrs;
else
i = 32;
i /= BitsPerPointer;
for(; i > 0; i--) {
if(w & 3)
bits = word & 3;
if(bits != BitsNoPointer && *(void**)scanp != nil)
if(bits == BitsPointer)
addroot((Obj){scanp, PtrSize, 0});
w >>= BitsPerPointer;
else
scaninterfacedata(bits, scanp, afterprologue);
word >>= BitsPerPointer;
scanp += PtrSize;
}
}
@ -1430,12 +1460,14 @@ addframeroots(Stkframe *frame, void*)
Func *f;
BitVector *args, *locals;
uintptr size;
bool afterprologue;
f = frame->fn;
// Scan local variables if stack frame has been allocated.
// Use pointer information if known.
if(frame->varp > (byte*)frame->sp) {
afterprologue = (frame->varp > (byte*)frame->sp);
if(afterprologue) {
locals = runtime·funcdata(f, FUNCDATA_GCLocals);
if(locals == nil) {
// No locals information, scan everything.
@ -1450,7 +1482,7 @@ addframeroots(Stkframe *frame, void*)
// Locals bitmap information, scan just the
// pointers in locals.
size = (locals->n*PtrSize) / BitsPerPointer;
scanbitvector(frame->varp - size, locals);
scanbitvector(frame->varp - size, locals, afterprologue);
}
}
@ -1458,7 +1490,7 @@ addframeroots(Stkframe *frame, void*)
// Use pointer information if known.
args = runtime·funcdata(f, FUNCDATA_GCArgs);
if(args != nil && args->n > 0)
scanbitvector(frame->argp, args);
scanbitvector(frame->argp, args, false);
else
addroot((Obj){frame->argp, frame->arglen, 0});
}