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); }
// 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·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·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这边的实现方式 }
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); }
static void appendslice1(SliceType *t, Slice x, Slice y, Slice *ret) { int32 m; uintptr w; m = x.len+y.len; if(m < x.len) runtime·throw("append: slice overflow"); if(m > x.cap) growslice1(t, x, m, ret); else *ret = x; w = t->elem->size; runtime·memmove(ret->array + ret->len*w, y.array, y.len*w); ret->len += y.len; }
// growslice(type *Type, x, []T, n int64) []T void runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) { int64 cap; if(n < 1) runtime·panicstring("growslice: invalid n"); cap = old.cap + n; if((int32)cap != cap || cap > ((uintptr)-1) / t->elem->size) runtime·panicstring("growslice: cap out of range"); 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); } }