mirror of
https://github.com/golang/go
synced 2024-11-20 00:04:43 -07:00
cmd/gc: support channel types in the garbage collector
R=golang-dev, dvyukov, rsc CC=golang-dev https://golang.org/cl/7473044
This commit is contained in:
parent
d8714ca49f
commit
6e69df6102
@ -1082,7 +1082,6 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
|
||||
*off += t->width;
|
||||
break;
|
||||
|
||||
case TCHAN:
|
||||
case TUNSAFEPTR:
|
||||
case TFUNC:
|
||||
if(*off % widthptr != 0)
|
||||
@ -1092,6 +1091,16 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
|
||||
*off += t->width;
|
||||
break;
|
||||
|
||||
// struct Hchan*
|
||||
case TCHAN:
|
||||
if(*off % widthptr != 0)
|
||||
fatal("dgcsym1: invalid alignment, %T", t);
|
||||
ot = duintptr(s, ot, GC_CHAN_PTR);
|
||||
ot = duintptr(s, ot, *off);
|
||||
ot = dsymptr(s, ot, dtypesym(t), 0);
|
||||
*off += t->width;
|
||||
break;
|
||||
|
||||
// struct Hmap*
|
||||
case TMAP:
|
||||
if(*off % widthptr != 0)
|
||||
|
@ -566,7 +566,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
byte *b, *arena_start, *arena_used;
|
||||
uintptr n, i, end_b, elemsize, size, ti, objti, count, type;
|
||||
uintptr *pc, precise_type, nominal_size;
|
||||
uintptr *map_ret, mapkey_size, mapval_size, mapkey_ti, mapval_ti;
|
||||
uintptr *map_ret, mapkey_size, mapval_size, mapkey_ti, mapval_ti, *chan_ret;
|
||||
void *obj;
|
||||
Type *t;
|
||||
Slice *sliceptr;
|
||||
@ -627,6 +627,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
mapkey_ti = mapval_ti = 0;
|
||||
chan = nil;
|
||||
chantype = nil;
|
||||
chan_ret = nil;
|
||||
|
||||
goto next_block;
|
||||
|
||||
@ -692,7 +693,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
mapval_kind = maptype->elem->kind;
|
||||
mapval_ti = (uintptr)maptype->elem->gc | PRECISE;
|
||||
|
||||
map_ret = 0;
|
||||
map_ret = nil;
|
||||
pc = mapProg;
|
||||
} else {
|
||||
goto next_block;
|
||||
@ -701,6 +702,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
case TypeInfo_Chan:
|
||||
chan = (Hchan*)b;
|
||||
chantype = (ChanType*)t;
|
||||
chan_ret = nil;
|
||||
pc = chanProg;
|
||||
break;
|
||||
default:
|
||||
@ -941,7 +943,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
}
|
||||
}
|
||||
}
|
||||
if(map_ret == 0)
|
||||
if(map_ret == nil)
|
||||
goto next_block;
|
||||
pc = map_ret;
|
||||
continue;
|
||||
@ -957,6 +959,25 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
flushobjbuf(objbuf, &objbufpos, &wp, &wbuf, &nobj);
|
||||
continue;
|
||||
|
||||
case GC_CHAN_PTR:
|
||||
// Similar to GC_MAP_PTR
|
||||
chan = *(Hchan**)(stack_top.b + pc[1]);
|
||||
if(chan == nil) {
|
||||
pc += 3;
|
||||
continue;
|
||||
}
|
||||
if(markonly(chan)) {
|
||||
chantype = (ChanType*)pc[2];
|
||||
if(!(chantype->elem->kind & KindNoPointers)) {
|
||||
// Start chanProg.
|
||||
chan_ret = pc+3;
|
||||
pc = chanProg+1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pc += 3;
|
||||
continue;
|
||||
|
||||
case GC_CHAN:
|
||||
// There are no heap pointers in struct Hchan,
|
||||
// so we can ignore the leading sizeof(Hchan) bytes.
|
||||
@ -975,7 +996,10 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
flushobjbuf(objbuf, &objbufpos, &wp, &wbuf, &nobj);
|
||||
}
|
||||
}
|
||||
goto next_block;
|
||||
if(chan_ret == nil)
|
||||
goto next_block;
|
||||
pc = chan_ret;
|
||||
continue;
|
||||
|
||||
default:
|
||||
runtime·throw("scanblock: invalid GC instruction");
|
||||
|
@ -24,6 +24,7 @@ enum {
|
||||
GC_ARRAY_NEXT, // The next element of an array. Args: none
|
||||
GC_CALL, // Call a subroutine. Args: (off, objgcrel)
|
||||
GC_MAP_PTR, // Go map. Args: (off, MapType*)
|
||||
GC_CHAN_PTR, // Go channel. Args: (off, ChanType*)
|
||||
GC_STRING, // Go string. Args: (off)
|
||||
GC_EFACE, // interface{}. Args: (off)
|
||||
GC_IFACE, // interface{...}. Args: (off)
|
||||
|
Loading…
Reference in New Issue
Block a user