6
6
#include "arch_GOARCH.h"
10
static int32 debug = 0;
12
static void makeslice1(SliceType*, int32, int32, Slice*);
13
static void growslice1(SliceType*, Slice, int32, Slice *);
14
void runtime·copy(Slice to, Slice fm, uintptr width, int32 ret);
12
static bool debug = 0;
14
static void makeslice1(SliceType*, intgo, intgo, Slice*);
15
static void growslice1(SliceType*, Slice, intgo, Slice *);
16
void runtime·copy(Slice to, Slice fm, uintptr width, intgo ret);
16
18
// see also unsafe·NewArray
17
19
// makeslice(typ *Type, len, cap int64) (ary []any);
19
21
runtime·makeslice(SliceType *t, int64 len, int64 cap, Slice ret)
21
if(len < 0 || (int32)len != len)
23
// NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
24
// but it produces a 'len out of range' error instead of a 'cap out of range' error
25
// when someone does make([]T, bignumber). 'cap out of range' is true too,
26
// but since the cap is only being supplied implicitly, saying len is clearer.
28
if(len < 0 || (intgo)len != len || t->elem->size > 0 && len > MaxMem / t->elem->size)
22
29
runtime·panicstring("makeslice: len out of range");
23
if(cap < len || (int32)cap != cap || t->elem->size > 0 && cap > ((uintptr)-1) / t->elem->size)
31
if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size)
24
32
runtime·panicstring("makeslice: cap out of range");
26
34
makeslice1(t, len, cap, &ret);
35
43
// Dummy word to use as base pointer for make([]T, 0).
36
44
// Since you cannot take the address of such a slice,
37
45
// you can't tell that they all have the same base pointer.
38
static uintptr zerobase;
46
uintptr runtime·zerobase;
41
makeslice1(SliceType *t, int32 len, int32 cap, Slice *ret)
49
makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
45
size = cap*t->elem->size;
51
ret->array = (byte*)&zerobase;
52
else if((t->elem->kind&KindNoPointers))
53
ret->array = runtime·mallocgc(size, FlagNoPointers, 1, 1);
55
ret->array = runtime·mal(size);
53
ret->array = runtime·cnewarray(t->elem, cap);
58
56
// appendslice(type *Type, x, y, []T) []T
60
59
runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
68
runtime·throw("append: slice overflow");
71
growslice1(t, x, m, &ret);
76
runtime·memmove(ret.array + ret.len*w, y.array, y.len*w);
70
runtime·throw("append: slice overflow");
73
growslice1(t, x, m, &ret);
78
// Don't mark read/writes on the newly allocated slice.
79
pc = runtime·getcallerpc(&t);
82
runtime·racereadrangepc(x.array, x.len*w, w, pc, runtime·appendslice);
84
runtime·racereadrangepc(y.array, y.len*w, w, pc, runtime·appendslice);
85
// write x[len(x):len(x)+len(y)]
87
runtime·racewriterangepc(ret.array+ret.len*w, y.len*w, w, pc, runtime·appendslice);
90
// A very common case is appending bytes. Small appends can avoid the overhead of memmove.
91
// We can generalize a bit here, and just pick small-sized appends.
92
p = ret.array+ret.len*w;
95
if(w <= appendCrossover) {
96
if(p <= q || w <= p-q) // No overlap.
106
runtime·memmove(p, q, w);
82
113
// appendstr([]byte, string) []byte
84
116
runtime·appendstr(SliceType *t, Slice x, String y, Slice ret)
91
runtime·throw("append: slice overflow");
126
runtime·throw("append: string overflow");
94
129
growslice1(t, x, m, &ret);
98
runtime·memmove(ret.array + ret.len, y.str, y.len);
134
// Don't mark read/writes on the newly allocated slice.
135
pc = runtime·getcallerpc(&t);
138
runtime·racereadrangepc(x.array, x.len, 1, pc, runtime·appendstr);
139
// write x[len(x):len(x)+len(y)]
141
runtime·racewriterangepc(ret.array+ret.len, y.len, 1, pc, runtime·appendstr);
144
// Small appends can avoid the overhead of memmove.
146
p = ret.array+ret.len;
148
if(w <= appendCrossover) {
152
runtime·memmove(p, q, w);
106
161
runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret)
111
167
runtime·panicstring("growslice: invalid n");
113
169
cap = old.cap + n;
115
if((int32)cap != cap || cap > ((uintptr)-1) / t->elem->size)
171
if((intgo)cap != cap || cap < old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size))
116
172
runtime·panicstring("growslice: cap out of range");
175
pc = runtime·getcallerpc(&t);
176
runtime·racereadrangepc(old.array, old.len*t->elem->size, t->elem->size, pc, runtime·growslice);
118
179
growslice1(t, old, cap, &ret);
147
213
runtime·memmove(ret->array, x.array, ret->len * t->elem->size);
150
// sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any);
152
runtime·sliceslice(Slice old, uint64 lb, uint64 hb, uint64 width, Slice ret)
154
if(hb > old.cap || lb > hb) {
156
runtime·prints("runtime.sliceslice: old=");
157
runtime·printslice(old);
158
runtime·prints("; lb=");
159
runtime·printint(lb);
160
runtime·prints("; hb=");
161
runtime·printint(hb);
162
runtime·prints("; width=");
163
runtime·printint(width);
164
runtime·prints("\n");
166
runtime·prints("oldarray: nel=");
167
runtime·printint(old.len);
168
runtime·prints("; cap=");
169
runtime·printint(old.cap);
170
runtime·prints("\n");
172
runtime·panicslice();
175
// new array is inside old array
177
ret.cap = old.cap - lb;
178
ret.array = old.array + lb*width;
183
runtime·prints("runtime.sliceslice: old=");
184
runtime·printslice(old);
185
runtime·prints("; lb=");
186
runtime·printint(lb);
187
runtime·prints("; hb=");
188
runtime·printint(hb);
189
runtime·prints("; width=");
190
runtime·printint(width);
191
runtime·prints("; ret=");
192
runtime·printslice(ret);
193
runtime·prints("\n");
197
// sliceslice1(old []any, lb uint64, width uint64) (ary []any);
199
runtime·sliceslice1(Slice old, uint64 lb, uint64 width, Slice ret)
203
runtime·prints("runtime.sliceslice: old=");
204
runtime·printslice(old);
205
runtime·prints("; lb=");
206
runtime·printint(lb);
207
runtime·prints("; width=");
208
runtime·printint(width);
209
runtime·prints("\n");
211
runtime·prints("oldarray: nel=");
212
runtime·printint(old.len);
213
runtime·prints("; cap=");
214
runtime·printint(old.cap);
215
runtime·prints("\n");
217
runtime·panicslice();
220
// new array is inside old array
221
ret.len = old.len - lb;
222
ret.cap = old.cap - lb;
223
ret.array = old.array + lb*width;
228
runtime·prints("runtime.sliceslice: old=");
229
runtime·printslice(old);
230
runtime·prints("; lb=");
231
runtime·printint(lb);
232
runtime·prints("; width=");
233
runtime·printint(width);
234
runtime·prints("; ret=");
235
runtime·printslice(ret);
236
runtime·prints("\n");
240
// slicearray(old *any, nel uint64, lb uint64, hb uint64, width uint64) (ary []any);
242
runtime·slicearray(byte* old, uint64 nel, uint64 lb, uint64 hb, uint64 width, Slice ret)
244
if(nel > 0 && old == nil) {
245
// crash if old == nil.
246
// could give a better message
247
// but this is consistent with all the in-line checks
248
// that the compiler inserts for other uses.
252
if(hb > nel || lb > hb) {
254
runtime·prints("runtime.slicearray: old=");
255
runtime·printpointer(old);
256
runtime·prints("; nel=");
257
runtime·printint(nel);
258
runtime·prints("; lb=");
259
runtime·printint(lb);
260
runtime·prints("; hb=");
261
runtime·printint(hb);
262
runtime·prints("; width=");
263
runtime·printint(width);
264
runtime·prints("\n");
266
runtime·panicslice();
269
// new array is inside old array
272
ret.array = old + lb*width;
277
runtime·prints("runtime.slicearray: old=");
278
runtime·printpointer(old);
279
runtime·prints("; nel=");
280
runtime·printint(nel);
281
runtime·prints("; lb=");
282
runtime·printint(lb);
283
runtime·prints("; hb=");
284
runtime·printint(hb);
285
runtime·prints("; width=");
286
runtime·printint(width);
287
runtime·prints("; ret=");
288
runtime·printslice(ret);
289
runtime·prints("\n");
293
// copy(to any, fr any, wid uint32) int
295
runtime·copy(Slice to, Slice fm, uintptr width, int32 ret)
216
// copy(to any, fr any, wid uintptr) int
219
runtime·copy(Slice to, Slice fm, uintptr width, intgo ret)
297
223
if(fm.len == 0 || to.len == 0 || width == 0) {