summaryrefslogtreecommitdiff
path: root/src/cmd/gc/reflect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/reflect.c')
-rw-r--r--src/cmd/gc/reflect.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index b8eb79938..8b546e235 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -1026,10 +1026,23 @@ dalgsym(Type *t)
}
static int
+gcinline(Type *t) {
+ switch(t->etype) {
+ case TARRAY:
+ if(t->bound == 1)
+ return 1;
+ if(t->width <= 4*widthptr)
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+static int
dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
{
Type *t1;
- vlong o, off2, fieldoffset;
+ vlong o, off2, fieldoffset, i;
if(t->align > 0 && (*off % t->align) != 0)
fatal("dgcsym1: invalid initial alignment, %T", t);
@@ -1069,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)
@@ -1079,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)
@@ -1132,8 +1154,9 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
} else {
if(t->bound < 1 || !haspointers(t->type)) {
*off += t->width;
- } else if(t->bound == 1) {
- ot = dgcsym1(s, ot, t->type, off, stack_size); // recursive call of dgcsym1
+ } else if(gcinline(t)) {
+ for(i=0; i<t->bound; i++)
+ ot = dgcsym1(s, ot, t->type, off, stack_size); // recursive call of dgcsym1
} else {
if(stack_size < GC_STACK_CAPACITY) {
ot = duintptr(s, ot, GC_ARRAY_START); // a stack push during GC