LEFT | RIGHT |
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 "../../cmd/ld/textflag.h" |
7 | 8 |
8 enum { | 9 enum { |
9 maxround = sizeof(uintptr), | 10 maxround = sizeof(uintptr), |
10 }; | 11 }; |
11 | 12 |
12 /* | 13 /* |
13 * We assume that all architectures turn faults and the like | 14 * We assume that all architectures turn faults and the like |
14 * into apparent calls to runtime.sigpanic. If we see a "call" | 15 * into apparent calls to runtime.sigpanic. If we see a "call" |
15 * to runtime.sigpanic, we do not back up the PC to find the | 16 * to runtime.sigpanic, we do not back up the PC to find the |
16 * line number of the CALL instruction, because there is no CALL. | 17 * line number of the CALL instruction, because there is no CALL. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 return nil; | 69 return nil; |
69 } | 70 } |
70 | 71 |
71 static int32 argc; | 72 static int32 argc; |
72 static uint8** argv; | 73 static uint8** argv; |
73 | 74 |
74 Slice os·Args; | 75 Slice os·Args; |
75 Slice syscall·envs; | 76 Slice syscall·envs; |
76 | 77 |
77 void (*runtime·sysargs)(int32, uint8**); | 78 void (*runtime·sysargs)(int32, uint8**); |
78 uint8** (*runtime·getenviron)(void); | 79 uint8** (*_cgo_getenviron)(void); |
79 | 80 |
80 void | 81 void |
81 runtime·args(int32 c, uint8 **v) | 82 runtime·args(int32 c, uint8 **v) |
82 { | 83 { |
83 argc = c; | 84 argc = c; |
84 argv = v; | 85 argv = v; |
85 if(runtime·sysargs != nil) | 86 if(runtime·sysargs != nil) |
86 runtime·sysargs(c, v); | 87 runtime·sysargs(c, v); |
87 } | 88 } |
88 | 89 |
(...skipping 24 matching lines...) Expand all Loading... |
113 } | 114 } |
114 | 115 |
115 void | 116 void |
116 runtime·goenvs_unix(void) | 117 runtime·goenvs_unix(void) |
117 { | 118 { |
118 String *s; | 119 String *s; |
119 int32 i, n; | 120 int32 i, n; |
120 uint8** environ; | 121 uint8** environ; |
121 | 122 |
122 environ = nil; | 123 environ = nil; |
123 » if(runtime·getenviron != nil) { | 124 » if(argc > 0) { |
124 » » environ = runtime·getenviron(); | |
125 » } else if(argc > 0) { | |
126 environ = argv + argc + 1; | 125 environ = argv + argc + 1; |
| 126 } else if(_cgo_getenviron != nil) { |
| 127 environ = _cgo_getenviron(); |
127 } else | 128 } else |
128 runtime·throw("argc is 0"); | 129 runtime·throw("argc is 0"); |
129 | 130 |
130 for(n=0; environ[n] != nil; n++) | 131 for(n=0; environ[n] != nil; n++) |
131 ; | 132 ; |
132 | 133 |
133 s = runtime·malloc(n*sizeof s[0]); | 134 s = runtime·malloc(n*sizeof s[0]); |
134 for(i=0; i<n; i++) | 135 for(i=0; i<n; i++) |
135 s[i] = runtime·gostringnocopy(environ[i]); | 136 s[i] = runtime·gostringnocopy(environ[i]); |
136 syscall·envs.array = (byte*)s; | 137 syscall·envs.array = (byte*)s; |
(...skipping 23 matching lines...) Expand all Loading... |
160 } | 161 } |
161 | 162 |
162 static void | 163 static void |
163 TestAtomic64(void) | 164 TestAtomic64(void) |
164 { | 165 { |
165 uint64 z64, x64; | 166 uint64 z64, x64; |
166 | 167 |
167 z64 = 42; | 168 z64 = 42; |
168 x64 = 0; | 169 x64 = 0; |
169 PREFETCH(&z64); | 170 PREFETCH(&z64); |
170 » if(runtime·cas64(&z64, &x64, 1)) | 171 » if(runtime·cas64(&z64, x64, 1)) |
171 runtime·throw("cas64 failed"); | 172 runtime·throw("cas64 failed"); |
172 » if(x64 != 42) | 173 » if(x64 != 0) |
173 runtime·throw("cas64 failed"); | 174 runtime·throw("cas64 failed"); |
174 » if(!runtime·cas64(&z64, &x64, 1)) | 175 » x64 = 42; |
| 176 » if(!runtime·cas64(&z64, x64, 1)) |
175 runtime·throw("cas64 failed"); | 177 runtime·throw("cas64 failed"); |
176 if(x64 != 42 || z64 != 1) | 178 if(x64 != 42 || z64 != 1) |
177 runtime·throw("cas64 failed"); | 179 runtime·throw("cas64 failed"); |
178 if(runtime·atomicload64(&z64) != 1) | 180 if(runtime·atomicload64(&z64) != 1) |
179 runtime·throw("load64 failed"); | 181 runtime·throw("load64 failed"); |
180 runtime·atomicstore64(&z64, (1ull<<40)+1); | 182 runtime·atomicstore64(&z64, (1ull<<40)+1); |
181 if(runtime·atomicload64(&z64) != (1ull<<40)+1) | 183 if(runtime·atomicload64(&z64) != (1ull<<40)+1) |
182 runtime·throw("store64 failed"); | 184 runtime·throw("store64 failed"); |
183 if(runtime·xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2) | 185 if(runtime·xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2) |
184 runtime·throw("xadd64 failed"); | 186 runtime·throw("xadd64 failed"); |
(...skipping 11 matching lines...) Expand all Loading... |
196 int8 a; | 198 int8 a; |
197 uint8 b; | 199 uint8 b; |
198 int16 c; | 200 int16 c; |
199 uint16 d; | 201 uint16 d; |
200 int32 e; | 202 int32 e; |
201 uint32 f; | 203 uint32 f; |
202 int64 g; | 204 int64 g; |
203 uint64 h; | 205 uint64 h; |
204 float32 i, i1; | 206 float32 i, i1; |
205 float64 j, j1; | 207 float64 j, j1; |
206 » void* k; | 208 » byte *k, *k1; |
207 uint16* l; | 209 uint16* l; |
208 struct x1 { | 210 struct x1 { |
209 byte x; | 211 byte x; |
210 }; | 212 }; |
211 struct y1 { | 213 struct y1 { |
212 struct x1 x1; | 214 struct x1 x1; |
213 byte y; | 215 byte y; |
214 }; | 216 }; |
215 | 217 |
216 if(sizeof(a) != 1) runtime·throw("bad a"); | 218 if(sizeof(a) != 1) runtime·throw("bad a"); |
217 if(sizeof(b) != 1) runtime·throw("bad b"); | 219 if(sizeof(b) != 1) runtime·throw("bad b"); |
218 if(sizeof(c) != 2) runtime·throw("bad c"); | 220 if(sizeof(c) != 2) runtime·throw("bad c"); |
219 if(sizeof(d) != 2) runtime·throw("bad d"); | 221 if(sizeof(d) != 2) runtime·throw("bad d"); |
220 if(sizeof(e) != 4) runtime·throw("bad e"); | 222 if(sizeof(e) != 4) runtime·throw("bad e"); |
221 if(sizeof(f) != 4) runtime·throw("bad f"); | 223 if(sizeof(f) != 4) runtime·throw("bad f"); |
222 if(sizeof(g) != 8) runtime·throw("bad g"); | 224 if(sizeof(g) != 8) runtime·throw("bad g"); |
223 if(sizeof(h) != 8) runtime·throw("bad h"); | 225 if(sizeof(h) != 8) runtime·throw("bad h"); |
224 if(sizeof(i) != 4) runtime·throw("bad i"); | 226 if(sizeof(i) != 4) runtime·throw("bad i"); |
225 if(sizeof(j) != 8) runtime·throw("bad j"); | 227 if(sizeof(j) != 8) runtime·throw("bad j"); |
226 if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k"); | 228 if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k"); |
227 if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l"); | 229 if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l"); |
228 if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1"); | 230 if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1"); |
229 if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y"); | 231 if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y"); |
230 if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1"); | 232 if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1"); |
231 | 233 |
| 234 if(runtime·timediv(12345LL*1000000000+54321, 1000000000, &e) != 12345 ||
e != 54321) |
| 235 runtime·throw("bad timediv"); |
| 236 |
232 uint32 z; | 237 uint32 z; |
233 z = 1; | 238 z = 1; |
234 if(!runtime·cas(&z, 1, 2)) | 239 if(!runtime·cas(&z, 1, 2)) |
235 runtime·throw("cas1"); | 240 runtime·throw("cas1"); |
236 if(z != 2) | 241 if(z != 2) |
237 runtime·throw("cas2"); | 242 runtime·throw("cas2"); |
238 | 243 |
239 z = 4; | 244 z = 4; |
240 if(runtime·cas(&z, 5, 6)) | 245 if(runtime·cas(&z, 5, 6)) |
241 runtime·throw("cas3"); | 246 runtime·throw("cas3"); |
242 if(z != 4) | 247 if(z != 4) |
243 runtime·throw("cas4"); | 248 runtime·throw("cas4"); |
| 249 |
| 250 k = (byte*)0xfedcb123; |
| 251 if(sizeof(void*) == 8) |
| 252 k = (byte*)((uintptr)k<<10); |
| 253 if(runtime·casp((void**)&k, nil, nil)) |
| 254 runtime·throw("casp1"); |
| 255 k1 = k+1; |
| 256 if(!runtime·casp((void**)&k, k, k1)) |
| 257 runtime·throw("casp2"); |
| 258 if(k != k1) |
| 259 runtime·throw("casp3"); |
244 | 260 |
245 *(uint64*)&j = ~0ULL; | 261 *(uint64*)&j = ~0ULL; |
246 if(j == j) | 262 if(j == j) |
247 runtime·throw("float64nan"); | 263 runtime·throw("float64nan"); |
248 if(!(j != j)) | 264 if(!(j != j)) |
249 runtime·throw("float64nan1"); | 265 runtime·throw("float64nan1"); |
250 | 266 |
251 *(uint64*)&j1 = ~1ULL; | 267 *(uint64*)&j1 = ~1ULL; |
252 if(j == j1) | 268 if(j == j1) |
253 runtime·throw("float64nan2"); | 269 runtime·throw("float64nan2"); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 if(runtime·callers(1+skip-1, rpc, 2) < 2) { | 301 if(runtime·callers(1+skip-1, rpc, 2) < 2) { |
286 retfile = runtime·emptystring; | 302 retfile = runtime·emptystring; |
287 retline = 0; | 303 retline = 0; |
288 retbool = false; | 304 retbool = false; |
289 } else if((f = runtime·findfunc(rpc[1])) == nil) { | 305 } else if((f = runtime·findfunc(rpc[1])) == nil) { |
290 retfile = runtime·emptystring; | 306 retfile = runtime·emptystring; |
291 retline = 0; | 307 retline = 0; |
292 retbool = true; // have retpc at least | 308 retbool = true; // have retpc at least |
293 } else { | 309 } else { |
294 retpc = rpc[1]; | 310 retpc = rpc[1]; |
295 retfile = f->src; | |
296 pc = retpc; | 311 pc = retpc; |
297 g = runtime·findfunc(rpc[0]); | 312 g = runtime·findfunc(rpc[0]); |
298 if(pc > f->entry && (g == nil || g->entry != (uintptr)runtime·si
gpanic)) | 313 if(pc > f->entry && (g == nil || g->entry != (uintptr)runtime·si
gpanic)) |
299 pc--; | 314 pc--; |
300 » » retline = runtime·funcline(f, pc); | 315 » » retline = runtime·funcline(f, pc, &retfile); |
301 retbool = true; | 316 retbool = true; |
302 } | 317 } |
303 FLUSH(&retpc); | 318 FLUSH(&retpc); |
304 FLUSH(&retfile); | 319 FLUSH(&retfile); |
305 FLUSH(&retline); | 320 FLUSH(&retline); |
306 FLUSH(&retbool); | 321 FLUSH(&retbool); |
307 } | 322 } |
308 | 323 |
309 void | 324 void |
310 runtime·Callers(intgo skip, Slice pc, intgo retn) | 325 runtime·Callers(intgo skip, Slice pc, intgo retn) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 runtime·unlock(&ticksLock); | 383 runtime·unlock(&ticksLock); |
369 return res; | 384 return res; |
370 } | 385 } |
371 | 386 |
372 void | 387 void |
373 runtime∕pprof·runtime_cyclesPerSecond(int64 res) | 388 runtime∕pprof·runtime_cyclesPerSecond(int64 res) |
374 { | 389 { |
375 res = runtime·tickspersecond(); | 390 res = runtime·tickspersecond(); |
376 FLUSH(&res); | 391 FLUSH(&res); |
377 } | 392 } |
| 393 |
| 394 DebugVars runtime·debug; |
| 395 |
| 396 static struct { |
| 397 int8* name; |
| 398 int32* value; |
| 399 } dbgvar[] = { |
| 400 {"gctrace", &runtime·debug.gctrace}, |
| 401 {"schedtrace", &runtime·debug.schedtrace}, |
| 402 {"scheddetail", &runtime·debug.scheddetail}, |
| 403 }; |
| 404 |
| 405 void |
| 406 runtime·parsedebugvars(void) |
| 407 { |
| 408 byte *p; |
| 409 intgo i, n; |
| 410 |
| 411 p = runtime·getenv("GODEBUG"); |
| 412 if(p == nil) |
| 413 return; |
| 414 for(;;) { |
| 415 for(i=0; i<nelem(dbgvar); i++) { |
| 416 n = runtime·findnull((byte*)dbgvar[i].name); |
| 417 if(runtime·mcmp(p, (byte*)dbgvar[i].name, n) == 0 && p[n
] == '=') |
| 418 *dbgvar[i].value = runtime·atoi(p+n+1); |
| 419 } |
| 420 p = runtime·strstr(p, (byte*)","); |
| 421 if(p == nil) |
| 422 break; |
| 423 p++; |
| 424 } |
| 425 } |
| 426 |
| 427 // Poor mans 64-bit division. |
| 428 // This is a very special function, do not use it if you are not sure what you a
re doing. |
| 429 // int64 division is lowered into _divv() call on 386, which does not fit into n
osplit functions. |
| 430 // Handles overflow in a time-specific manner. |
| 431 #pragma textflag NOSPLIT |
| 432 int32 |
| 433 runtime·timediv(int64 v, int32 div, int32 *rem) |
| 434 { |
| 435 int32 res, bit; |
| 436 |
| 437 if(v >= (int64)div*0x7fffffffLL) { |
| 438 if(rem != nil) |
| 439 *rem = 0; |
| 440 return 0x7fffffff; |
| 441 } |
| 442 res = 0; |
| 443 for(bit = 30; bit >= 0; bit--) { |
| 444 if(v >= ((int64)div<<bit)) { |
| 445 v = v - ((int64)div<<bit); |
| 446 res += 1<<bit; |
| 447 } |
| 448 } |
| 449 if(rem != nil) |
| 450 *rem = v; |
| 451 return res; |
| 452 } |
LEFT | RIGHT |