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:
parent
fcf6a7e5ce
commit
87fdb8fb9a
@ -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;
|
||||
|
||||
|
@ -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});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user