*off += t->width;
break;
- case TCHAN:
case TUNSAFEPTR:
case TFUNC:
if(*off % widthptr != 0)
*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)
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;
mapkey_ti = mapval_ti = 0;
chan = nil;
chantype = nil;
+ chan_ret = nil;
goto next_block;
mapval_kind = maptype->elem->kind;
mapval_ti = (uintptr)maptype->elem->gc | PRECISE;
- map_ret = 0;
+ map_ret = nil;
pc = mapProg;
} else {
goto next_block;
case TypeInfo_Chan:
chan = (Hchan*)b;
chantype = (ChanType*)t;
+ chan_ret = nil;
pc = chanProg;
break;
default:
}
}
}
- if(map_ret == 0)
+ if(map_ret == nil)
goto next_block;
pc = map_ret;
continue;
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.
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");
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)