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这边的实现方式 }
// 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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }