diff options
Diffstat (limited to 'src/cmd/gc/reflect.c')
| -rw-r--r-- | src/cmd/gc/reflect.c | 31 | 
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 | 
