Exemplo n.º 1
0
void
runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
{
	intgo m;
	uintptr w;
	void *pc;
	uint8 *p, *q;

	m = x.len+y.len;
	w = t->elem->size;

	if(m < x.len)
		runtime·throw("append: slice overflow");

	//如果前一个slice的cap是足够大的,则直接将后一个赋值过来,否则要进行grow
	if(m > x.cap)
		growslice1(t, x, m, &ret);
	else
		ret = x;

	if(raceenabled) {
		// Don't mark read/writes on the newly allocated slice.
		pc = runtime·getcallerpc(&t);
		// read x[:len]
		if(m > x.cap)
			runtime·racereadrangepc(x.array, x.len*w, w, pc, runtime·appendslice);
		// read y
		runtime·racereadrangepc(y.array, y.len*w, w, pc, runtime·appendslice);
		// write x[len(x):len(x)+len(y)]
		if(m <= x.cap)
			runtime·racewriterangepc(ret.array+ret.len*w, y.len*w, w, pc, runtime·appendslice);
	}

	// A very common case is appending bytes. Small appends can avoid the overhead of memmove.
	// We can generalize a bit here, and just pick small-sized appends.
	//如果只是复制很少的内容,直接for循环赋值效率会高一些,避免了memmove函数调用的开销
	p = ret.array+ret.len*w;
	q = y.array;
	w *= y.len;
	if(w <= appendCrossover) { //appendCrossover在386和amd64中是16,在arm中是8
		if(p <= q || w <= p-q) // No overlap.
			while(w-- > 0)
				*p++ = *q++;
		else {
			p += w;
			q += w;
			while(w-- > 0)
				*--p = *--q;
		}
	} else {
		runtime·memmove(p, q, w);
	}
	ret.len += y.len;
	FLUSH(&ret); //go的多值返回在c这边的实现方式
}
Exemplo n.º 2
0
Arquivo: slice.c Projeto: abustany/go
// growslice(type *Type, x, []T, n int64) []T
void
runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret)
{
	int64 cap;
	void *pc;

	if(n < 1)
		runtime·panicstring("growslice: invalid n");

	cap = old.cap + n;

	if((intgo)cap != cap || cap < old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size))
		runtime·panicstring("growslice: cap out of range");

	if(raceenabled) {
		pc = runtime·getcallerpc(&t);
		runtime·racereadrangepc(old.array, old.len*t->elem->size, t->elem->size, pc, runtime·growslice);
	}

	growslice1(t, old, cap, &ret);

	FLUSH(&ret);

	if(debug) {
		runtime·printf("growslice(%S,", *t->string);
		runtime·printslice(old);
		runtime·printf(", new cap=%D) =", cap);
		runtime·printslice(ret);
	}
}
Exemplo n.º 3
0
void
runtime·slicerunetostring(Slice b, String s)
{
	s.str = 0;
	s.len = 0;
	FLUSH(&s);
#line 309 "/home/14/ren/source/golang/go/src/pkg/runtime/string.goc"

	intgo siz1, siz2, i;
	int32 *a;
	byte dum[8];
	void *pc;

	if(raceenabled) {
		pc = runtime·getcallerpc(&b);
		runtime·racereadrangepc(b.array, b.len*sizeof(*a), pc, runtime·slicerunetostring);
	}
	a = (int32*)b.array;
	siz1 = 0;
	for(i=0; i<b.len; i++) {
		siz1 += runtime·runetochar(dum, a[i]);
	}

	s = gostringsize(siz1+4);
	siz2 = 0;
	for(i=0; i<b.len; i++) {
		// check for race
		if(siz2 >= siz1)
			break;
		siz2 += runtime·runetochar(s.str+siz2, a[i]);
	}
	s.len = siz2;
	s.str[s.len] = 0;
	FLUSH(&s);
}
Exemplo n.º 4
0
void
runtime·growslice(SliceType* t, Slice old, int64 n, Slice ret)
{
	ret.array = 0;
	ret.len = 0;
	ret.cap = 0;
	FLUSH(&ret);
#line 59 "C:\Users\ADMINI~1\AppData\Local\Temp\2\makerelease686069423\go\src\pkg\runtime\slice.goc"

	int64 cap;
	void *pc;

	if(n < 1)
		runtime·panicstring("growslice: invalid n");

	cap = old.cap + n;

	if((intgo)cap != cap || cap < (int64)old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size))
		runtime·panicstring("growslice: cap out of range");

	if(raceenabled) {
		pc = runtime·getcallerpc(&t);
		runtime·racereadrangepc(old.array, old.len*t->elem->size, pc, runtime·growslice);
	}

	growslice1(t, old, cap, &ret);

	if(debug) {
		runtime·printf("growslice(%S,", *t->string);
		runtime·printslice(old);
		runtime·printf(", new cap=%D) =", cap);
		runtime·printslice(ret);
	}
	FLUSH(&ret);
}
Exemplo n.º 5
0
void
runtime·growslice(SliceType* t, Slice old, int64 n, Slice ret)
{
	ret.array = 0;
	ret.len = 0;
	ret.cap = 0;
	FLUSH(&ret);
#line 59 "/home/14/ren/source/golang/go/src/pkg/runtime/slice.goc"

	int64 cap;
	void *pc;

	if(n < 1)
		runtime·panicstring("growslice: invalid n");

	cap = old.cap + n;

	if((intgo)cap != cap || cap < (int64)old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size))
		runtime·panicstring("growslice: cap out of range");

	if(raceenabled) {
		pc = runtime·getcallerpc(&t);
		runtime·racereadrangepc(old.array, old.len*t->elem->size, pc, runtime·growslice);
	}

	growslice1(t, old, cap, &ret);

	if(debug) {
		runtime·printf("growslice(%S,", *t->string);
		runtime·printslice(old);
		runtime·printf(", new cap=%D) =", cap);
		runtime·printslice(ret);
	}
	FLUSH(&ret);
}
Exemplo n.º 6
0
void
runtime·slicebytetostring(Slice b, String s)
{
#line 250 "/home/pi/go_build/go/src/pkg/runtime/string.goc"

	void *pc;

	if(raceenabled) {
		pc = runtime·getcallerpc(&b);
		runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostring);
	}
	s = gostringsize(b.len);
	runtime·memmove(s.str, b.array, s.len);
	FLUSH(&s);
}
Exemplo n.º 7
0
void
runtime·copy(Slice to, Slice fm, uintptr width, intgo ret)
{
	ret = 0;
	FLUSH(&ret);
#line 135 "C:\Users\ADMINI~1\AppData\Local\Temp\2\makerelease686069423\go\src\pkg\runtime\slice.goc"

	void *pc;

	if(fm.len == 0 || to.len == 0 || width == 0) {
		ret = 0;
		goto out;
	}

	ret = fm.len;
	if(to.len < ret)
		ret = to.len;

	if(raceenabled) {
		pc = runtime·getcallerpc(&to);
		runtime·racewriterangepc(to.array, ret*width, pc, runtime·copy);
		runtime·racereadrangepc(fm.array, ret*width, pc, runtime·copy);
	}

	if(ret == 1 && width == 1) {	// common case worth about 2x to do here
		*to.array = *fm.array;	// known to be a byte pointer
	} else {
		runtime·memmove(to.array, fm.array, ret*width);
	}

out:

	if(debug) {
		runtime·prints("main·copy: to=");
		runtime·printslice(to);
		runtime·prints("; fm=");
		runtime·printslice(fm);
		runtime·prints("; width=");
		runtime·printint(width);
		runtime·prints("; ret=");
		runtime·printint(ret);
		runtime·prints("\n");
	}
	FLUSH(&ret);
}
Exemplo n.º 8
0
void
runtime·copy(Slice to, Slice fm, uintptr width, intgo ret)
{
	ret = 0;
	FLUSH(&ret);
#line 139 "/home/14/ren/source/golang/go/src/pkg/runtime/slice.goc"

	void *pc;

	if(fm.len == 0 || to.len == 0 || width == 0) {
		ret = 0;
		goto out;
	}

	ret = fm.len;
	if(to.len < ret)
		ret = to.len;

	if(raceenabled) {
		pc = runtime·getcallerpc(&to);
		runtime·racewriterangepc(to.array, ret*width, pc, runtime·copy);
		runtime·racereadrangepc(fm.array, ret*width, pc, runtime·copy);
	}

	if(ret == 1 && width == 1) {	// common case worth about 2x to do here
		*to.array = *fm.array;	// known to be a byte pointer
	} else {
		runtime·memmove(to.array, fm.array, ret*width);
	}

out:

	if(debug) {
		runtime·prints("main·copy: to=");
		runtime·printslice(to);
		runtime·prints("; fm=");
		runtime·printslice(fm);
		runtime·prints("; width=");
		runtime·printint(width);
		runtime·prints("; ret=");
		runtime·printint(ret);
		runtime·prints("\n");
	}
	FLUSH(&ret);
}
Exemplo n.º 9
0
void
runtime·slicebytetostring(Slice b, String s)
{
	s.str = 0;
	s.len = 0;
	FLUSH(&s);
#line 286 "/home/14/ren/source/golang/go/src/pkg/runtime/string.goc"

	void *pc;

	if(raceenabled) {
		pc = runtime·getcallerpc(&b);
		runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostring);
	}
	s = gostringsize(b.len);
	runtime·memmove(s.str, b.array, s.len);
	FLUSH(&s);
}
Exemplo n.º 10
0
Arquivo: slice.c Projeto: abustany/go
void
runtime·appendstr(SliceType *t, Slice x, String y, Slice ret)
{
	intgo m;
	void *pc;
	uintptr w;
	uint8 *p, *q;

	m = x.len+y.len;

	if(m < x.len)
		runtime·throw("append: string overflow");

	if(m > x.cap)
		growslice1(t, x, m, &ret);
	else
		ret = x;

	if(raceenabled) {
		// Don't mark read/writes on the newly allocated slice.
		pc = runtime·getcallerpc(&t);
		// read x[:len]
		if(m > x.cap)
			runtime·racereadrangepc(x.array, x.len, 1, pc, runtime·appendstr);
		// write x[len(x):len(x)+len(y)]
		if(m <= x.cap)
			runtime·racewriterangepc(ret.array+ret.len, y.len, 1, pc, runtime·appendstr);
	}

	// Small appends can avoid the overhead of memmove.
	w = y.len;
	p = ret.array+ret.len;
	q = y.str;
	if(w <= appendCrossover) {
		while(w-- > 0)
			*p++ = *q++;
	} else {
		runtime·memmove(p, q, w);
	}
	ret.len += y.len;
	FLUSH(&ret);
}