kill_autoinc_value can take a rtx_insn *
[official-gcc.git] / libgo / runtime / runtime.c
blobe3320356c47c142f962082c4c6d37b056382fbe7
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 #include <signal.h>
6 #include <unistd.h>
8 #include "config.h"
10 #include "runtime.h"
11 #include "arch.h"
12 #include "array.h"
14 enum {
15 maxround = sizeof(uintptr),
18 // Keep a cached value to make gotraceback fast,
19 // since we call it on every call to gentraceback.
20 // The cached value is a uint32 in which the low bit
21 // is the "crash" setting and the top 31 bits are the
22 // gotraceback value.
23 static uint32 traceback_cache = ~(uint32)0;
25 extern volatile intgo runtime_MemProfileRate
26 __asm__ (GOSYM_PREFIX "runtime.MemProfileRate");
29 // The GOTRACEBACK environment variable controls the
30 // behavior of a Go program that is crashing and exiting.
31 // GOTRACEBACK=0 suppress all tracebacks
32 // GOTRACEBACK=1 default behavior - show tracebacks but exclude runtime frames
33 // GOTRACEBACK=2 show tracebacks including runtime frames
34 // GOTRACEBACK=crash show tracebacks including runtime frames, then crash (core dump etc)
35 int32
36 runtime_gotraceback(bool *crash)
38 const byte *p;
39 uint32 x;
41 if(crash != nil)
42 *crash = false;
43 if(runtime_m()->traceback != 0)
44 return runtime_m()->traceback;
45 x = runtime_atomicload(&traceback_cache);
46 if(x == ~(uint32)0) {
47 p = runtime_getenv("GOTRACEBACK");
48 if(p == nil)
49 p = (const byte*)"";
50 if(p[0] == '\0')
51 x = 1<<1;
52 else if(runtime_strcmp((const char *)p, "crash") == 0)
53 x = (2<<1) | 1;
54 else
55 x = runtime_atoi(p)<<1;
56 runtime_atomicstore(&traceback_cache, x);
58 if(crash != nil)
59 *crash = x&1;
60 return x>>1;
63 static int32 argc;
64 static byte** argv;
66 static Slice args;
67 Slice envs;
69 void (*runtime_sysargs)(int32, uint8**);
71 void
72 runtime_args(int32 c, byte **v)
74 argc = c;
75 argv = v;
76 if(runtime_sysargs != nil)
77 runtime_sysargs(c, v);
80 byte*
81 runtime_progname()
83 return argc == 0 ? nil : argv[0];
86 void
87 runtime_goargs(void)
89 String *s;
90 int32 i;
92 // for windows implementation see "os" package
93 if(Windows)
94 return;
96 s = runtime_malloc(argc*sizeof s[0]);
97 for(i=0; i<argc; i++)
98 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
99 args.__values = (void*)s;
100 args.__count = argc;
101 args.__capacity = argc;
104 void
105 runtime_goenvs_unix(void)
107 String *s;
108 int32 i, n;
110 for(n=0; argv[argc+1+n] != 0; n++)
113 s = runtime_malloc(n*sizeof s[0]);
114 for(i=0; i<n; i++)
115 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
116 envs.__values = (void*)s;
117 envs.__count = n;
118 envs.__capacity = n;
121 // Called from the syscall package.
122 Slice runtime_envs(void) __asm__ (GOSYM_PREFIX "syscall.runtime_envs");
124 Slice
125 runtime_envs()
127 return envs;
130 Slice os_runtime_args(void) __asm__ (GOSYM_PREFIX "os.runtime_args");
132 Slice
133 os_runtime_args()
135 return args;
138 int32
139 runtime_atoi(const byte *p)
141 int32 n;
143 n = 0;
144 while('0' <= *p && *p <= '9')
145 n = n*10 + *p++ - '0';
146 return n;
149 static struct root_list runtime_roots =
150 { nil,
151 { { &envs, sizeof envs },
152 { &args, sizeof args },
153 { nil, 0 } },
156 static void
157 TestAtomic64(void)
159 uint64 z64, x64;
161 z64 = 42;
162 x64 = 0;
163 PREFETCH(&z64);
164 if(runtime_cas64(&z64, x64, 1))
165 runtime_throw("cas64 failed");
166 if(x64 != 0)
167 runtime_throw("cas64 failed");
168 x64 = 42;
169 if(!runtime_cas64(&z64, x64, 1))
170 runtime_throw("cas64 failed");
171 if(x64 != 42 || z64 != 1)
172 runtime_throw("cas64 failed");
173 if(runtime_atomicload64(&z64) != 1)
174 runtime_throw("load64 failed");
175 runtime_atomicstore64(&z64, (1ull<<40)+1);
176 if(runtime_atomicload64(&z64) != (1ull<<40)+1)
177 runtime_throw("store64 failed");
178 if(runtime_xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2)
179 runtime_throw("xadd64 failed");
180 if(runtime_atomicload64(&z64) != (2ull<<40)+2)
181 runtime_throw("xadd64 failed");
182 if(runtime_xchg64(&z64, (3ull<<40)+3) != (2ull<<40)+2)
183 runtime_throw("xchg64 failed");
184 if(runtime_atomicload64(&z64) != (3ull<<40)+3)
185 runtime_throw("xchg64 failed");
188 void
189 runtime_check(void)
191 __go_register_gc_roots(&runtime_roots);
193 TestAtomic64();
196 uint32
197 runtime_fastrand1(void)
199 M *m;
200 uint32 x;
202 m = runtime_m();
203 x = m->fastrand;
204 x += x;
205 if(x & 0x80000000L)
206 x ^= 0x88888eefUL;
207 m->fastrand = x;
208 return x;
211 int64
212 runtime_cputicks(void)
214 #if defined(__386__) || defined(__x86_64__)
215 uint32 low, high;
216 asm("rdtsc" : "=a" (low), "=d" (high));
217 return (int64)(((uint64)high << 32) | (uint64)low);
218 #elif defined (__s390__) || defined (__s390x__)
219 uint64 clock = 0;
220 /* stckf may not write the return variable in case of a clock error, so make
221 it read-write to prevent that the initialisation is optimised out.
222 Note: Targets below z9-109 will crash when executing store clock fast, i.e.
223 we don't support Go for machines older than that. */
224 asm volatile(".insn s,0xb27c0000,%0" /* stckf */ : "+Q" (clock) : : "cc" );
225 return (int64)clock;
226 #else
227 // FIXME: implement for other processors.
228 return 0;
229 #endif
232 bool
233 runtime_showframe(String s, bool current)
235 static int32 traceback = -1;
237 if(current && runtime_m()->throwing > 0)
238 return 1;
239 if(traceback < 0)
240 traceback = runtime_gotraceback(nil);
241 return traceback > 1 || (__builtin_memchr(s.str, '.', s.len) != nil && __builtin_memcmp(s.str, "runtime.", 7) != 0);
244 static Lock ticksLock;
245 static int64 ticks;
247 int64
248 runtime_tickspersecond(void)
250 int64 res, t0, t1, c0, c1;
252 res = (int64)runtime_atomicload64((uint64*)&ticks);
253 if(res != 0)
254 return ticks;
255 runtime_lock(&ticksLock);
256 res = ticks;
257 if(res == 0) {
258 t0 = runtime_nanotime();
259 c0 = runtime_cputicks();
260 runtime_usleep(100*1000);
261 t1 = runtime_nanotime();
262 c1 = runtime_cputicks();
263 if(t1 == t0)
264 t1++;
265 res = (c1-c0)*1000*1000*1000/(t1-t0);
266 if(res == 0)
267 res++;
268 runtime_atomicstore64((uint64*)&ticks, res);
270 runtime_unlock(&ticksLock);
271 return res;
274 // Called to initialize a new m (including the bootstrap m).
275 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
276 void
277 runtime_mpreinit(M *mp)
279 mp->gsignal = runtime_malg(32*1024, &mp->gsignalstack, &mp->gsignalstacksize); // OS X wants >=8K, Linux >=2K
282 // Called to initialize a new m (including the bootstrap m).
283 // Called on the new thread, can not allocate memory.
284 void
285 runtime_minit(void)
287 M* m;
288 sigset_t sigs;
290 // Initialize signal handling.
291 m = runtime_m();
292 runtime_signalstack(m->gsignalstack, m->gsignalstacksize);
293 if (sigemptyset(&sigs) != 0)
294 runtime_throw("sigemptyset");
295 pthread_sigmask(SIG_SETMASK, &sigs, nil);
298 // Called from dropm to undo the effect of an minit.
299 void
300 runtime_unminit(void)
302 runtime_signalstack(nil, 0);
306 void
307 runtime_signalstack(byte *p, int32 n)
309 stack_t st;
311 st.ss_sp = p;
312 st.ss_size = n;
313 st.ss_flags = 0;
314 if(p == nil)
315 st.ss_flags = SS_DISABLE;
316 if(sigaltstack(&st, nil) < 0)
317 *(int *)0xf1 = 0xf1;
320 DebugVars runtime_debug;
322 // Holds variables parsed from GODEBUG env var,
323 // except for "memprofilerate" since there is an
324 // existing var for that value which is int
325 // instead of in32 and might have an
326 // initial value.
327 static struct {
328 const char* name;
329 int32* value;
330 } dbgvar[] = {
331 {"allocfreetrace", &runtime_debug.allocfreetrace},
332 {"efence", &runtime_debug.efence},
333 {"gctrace", &runtime_debug.gctrace},
334 {"gcdead", &runtime_debug.gcdead},
335 {"scheddetail", &runtime_debug.scheddetail},
336 {"schedtrace", &runtime_debug.schedtrace},
339 void
340 runtime_parsedebugvars(void)
342 const byte *p;
343 intgo i, n;
344 bool tmp;
346 // gotraceback caches the GOTRACEBACK setting in traceback_cache.
347 // gotraceback can be called before the environment is available.
348 // traceback_cache must be reset after the environment is made
349 // available, in order for the environment variable to take effect.
350 // The code is fixed differently in Go 1.4.
351 // This is a limited fix for Go 1.3.3.
352 traceback_cache = ~(uint32)0;
353 runtime_gotraceback(&tmp);
355 p = runtime_getenv("GODEBUG");
356 if(p == nil)
357 return;
358 for(;;) {
359 for(i=0; i<(intgo)nelem(dbgvar); i++) {
360 n = runtime_findnull((const byte*)dbgvar[i].name);
361 if(runtime_mcmp(p, "memprofilerate", n) == 0 && p[n] == '=')
362 // Set the MemProfileRate directly since it
363 // is an int, not int32, and should only lbe
364 // set here if specified by GODEBUG
365 runtime_MemProfileRate = runtime_atoi(p+n+1);
366 else if(runtime_mcmp(p, dbgvar[i].name, n) == 0 && p[n] == '=')
367 *dbgvar[i].value = runtime_atoi(p+n+1);
369 p = (const byte *)runtime_strstr((const char *)p, ",");
370 if(p == nil)
371 break;
372 p++;
376 // Poor mans 64-bit division.
377 // This is a very special function, do not use it if you are not sure what you are doing.
378 // int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
379 // Handles overflow in a time-specific manner.
380 int32
381 runtime_timediv(int64 v, int32 div, int32 *rem)
383 int32 res, bit;
385 if(v >= (int64)div*0x7fffffffLL) {
386 if(rem != nil)
387 *rem = 0;
388 return 0x7fffffff;
390 res = 0;
391 for(bit = 30; bit >= 0; bit--) {
392 if(v >= ((int64)div<<bit)) {
393 v = v - ((int64)div<<bit);
394 res += 1<<bit;
397 if(rem != nil)
398 *rem = v;
399 return res;
402 // Setting the max stack size doesn't really do anything for gccgo.
404 uintptr runtime_maxstacksize = 1<<20; // enough until runtime.main sets it for real
406 void memclrBytes(Slice)
407 __asm__ (GOSYM_PREFIX "runtime.memclrBytes");
409 void
410 memclrBytes(Slice s)
412 runtime_memclr(s.__values, s.__count);