LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "arch_GOARCH.h" | 6 #include "arch_GOARCH.h" |
7 #include "type.h" | 7 #include "type.h" |
8 #include "typekind.h" | 8 #include "typekind.h" |
9 #include "malloc.h" | 9 #include "malloc.h" |
10 #include "race.h" | 10 #include "race.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 // you can't tell that they all have the same base pointer. | 49 // you can't tell that they all have the same base pointer. |
50 uintptr runtime·zerobase; | 50 uintptr runtime·zerobase; |
51 | 51 |
52 static void | 52 static void |
53 makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret) | 53 makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret) |
54 { | 54 { |
55 ret->len = len; | 55 ret->len = len; |
56 ret->cap = cap; | 56 ret->cap = cap; |
57 ret->array = runtime·cnewarray(t->elem, cap); | 57 ret->array = runtime·cnewarray(t->elem, cap); |
58 } | 58 } |
59 | |
60 // appendslice(type *Type, x, y, []T) []T | |
61 #pragma textflag NOSPLIT | |
62 void | |
63 runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret) | |
64 { | |
65 intgo m; | |
66 uintptr w; | |
67 void *pc; | |
68 uint8 *p, *q; | |
69 | |
70 m = x.len+y.len; | |
71 w = t->elem->size; | |
72 | |
73 if(m < x.len) | |
74 runtime·throw("append: slice overflow"); | |
75 | |
76 if(m > x.cap) | |
77 growslice1(t, x, m, &ret); | |
78 else | |
79 ret = x; | |
80 | |
81 if(raceenabled) { | |
82 // Don't mark read/writes on the newly allocated slice. | |
83 pc = runtime·getcallerpc(&t); | |
84 // read x[:len] | |
85 if(m > x.cap) | |
86 runtime·racereadrangepc(x.array, x.len*w, pc, runtime·ap
pendslice); | |
87 // read y | |
88 runtime·racereadrangepc(y.array, y.len*w, pc, runtime·appendslic
e); | |
89 // write x[len(x):len(x)+len(y)] | |
90 if(m <= x.cap) | |
91 runtime·racewriterangepc(ret.array+ret.len*w, y.len*w, p
c, runtime·appendslice); | |
92 } | |
93 | |
94 // A very common case is appending bytes. Small appends can avoid the ov
erhead of memmove. | |
95 // We can generalize a bit here, and just pick small-sized appends. | |
96 p = ret.array+ret.len*w; | |
97 q = y.array; | |
98 w *= y.len; | |
99 if(appendCrossover > 0 && w <= appendCrossover) { | |
100 if(p <= q || w <= p-q) // No overlap. | |
101 while(w-- > 0) | |
102 *p++ = *q++; | |
103 else { | |
104 p += w; | |
105 q += w; | |
106 while(w-- > 0) | |
107 *--p = *--q; | |
108 } | |
109 } else { | |
110 runtime·memmove(p, q, w); | |
111 } | |
112 ret.len += y.len; | |
113 FLUSH(&ret); | |
114 } | |
115 | |
116 | |
117 // appendstr([]byte, string) []byte | |
118 #pragma textflag NOSPLIT | |
119 void | |
120 runtime·appendstr(SliceType *t, Slice x, String y, Slice ret) | |
121 { | |
122 intgo m; | |
123 void *pc; | |
124 uintptr w; | |
125 uint8 *p, *q; | |
126 | |
127 m = x.len+y.len; | |
128 | |
129 if(m < x.len) | |
130 runtime·throw("append: string overflow"); | |
131 | |
132 if(m > x.cap) | |
133 growslice1(t, x, m, &ret); | |
134 else | |
135 ret = x; | |
136 | |
137 if(raceenabled) { | |
138 // Don't mark read/writes on the newly allocated slice. | |
139 pc = runtime·getcallerpc(&t); | |
140 // read x[:len] | |
141 if(m > x.cap) | |
142 runtime·racereadrangepc(x.array, x.len, pc, runtime·appe
ndstr); | |
143 // write x[len(x):len(x)+len(y)] | |
144 if(m <= x.cap) | |
145 runtime·racewriterangepc(ret.array+ret.len, y.len, pc, r
untime·appendstr); | |
146 } | |
147 | |
148 // Small appends can avoid the overhead of memmove. | |
149 w = y.len; | |
150 p = ret.array+ret.len; | |
151 q = y.str; | |
152 if(appendCrossover > 0 && w <= appendCrossover) { | |
153 while(w-- > 0) | |
154 *p++ = *q++; | |
155 } else { | |
156 runtime·memmove(p, q, w); | |
157 } | |
158 ret.len += y.len; | |
159 FLUSH(&ret); | |
160 } | |
161 | |
162 | 59 |
163 // growslice(type *Type, x, []T, n int64) []T | 60 // growslice(type *Type, x, []T, n int64) []T |
164 void | 61 void |
165 runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) | 62 runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) |
166 { | 63 { |
167 int64 cap; | 64 int64 cap; |
168 void *pc; | 65 void *pc; |
169 | 66 |
170 if(n < 1) | 67 if(n < 1) |
171 runtime·panicstring("growslice: invalid n"); | 68 runtime·panicstring("growslice: invalid n"); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 void | 187 void |
291 runtime·printslice(Slice a) | 188 runtime·printslice(Slice a) |
292 { | 189 { |
293 runtime·prints("["); | 190 runtime·prints("["); |
294 runtime·printint(a.len); | 191 runtime·printint(a.len); |
295 runtime·prints("/"); | 192 runtime·prints("/"); |
296 runtime·printint(a.cap); | 193 runtime·printint(a.cap); |
297 runtime·prints("]"); | 194 runtime·prints("]"); |
298 runtime·printpointer(a.array); | 195 runtime·printpointer(a.array); |
299 } | 196 } |
LEFT | RIGHT |