Commit 67487878 by Ian Lance Taylor

runtime: copy runtime.go and runtime1.go from Go 1.7

    
    Also copy over cputicks.go, env_posix.go, vdso_none.go, stubs2.go, and a
    part of os_linux.go.  Remove the corresponding functions from the C code
    in libgo/go/runtime.  Add some transitional support functions to
    stubs.go.  This converts several minor functions from C to Go.
    
    Reviewed-on: https://go-review.googlesource.com/29962

From-SVN: r240609
parent 83194649
c79a35411c1065c71add196fdeca6e5207a79248
e51657a576367c7a498c94baf985b79066fc082a
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
// careful: cputicks is not guaranteed to be monotonic! In particular, we have
// noticed drift between cpus on certain os/arch combinations. See issue 8976.
func cputicks() int64
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
package runtime
func gogetenv(key string) string {
env := environ()
if env == nil {
throw("getenv before env init")
}
for _, s := range environ() {
if len(s) > len(key) && s[len(key)] == '=' && s[:len(key)] == key {
return s[len(key)+1:]
}
}
return ""
}
......@@ -6,10 +6,6 @@
package runtime
import (
"unsafe"
)
//var Fadd64 = fadd64
//var Fsub64 = fsub64
//var Fmul64 = fmul64
......@@ -103,20 +99,6 @@ var HashLoad = &hashLoad
//type Uintreg uintreg
//extern __go_open
func open(path *byte, mode int32, perm int32) int32
func Open(path *byte, mode int32, perm int32) int32 {
return open(path, mode, perm)
}
//extern close
func close(int32) int32
func Close(fd int32) int32 {
return close(fd)
}
/*
func RunSchedLocalQueueTest() {
_p_ := new(p)
......@@ -224,25 +206,13 @@ var IfaceHash = ifaceHash
var MemclrBytes = memclrBytes
*/
//extern read
func read(fd int32, buf unsafe.Pointer, size int32) int32
var Open = open
var Close = closefd
var Read = read
var Write = write
func Read(fd int32, buf unsafe.Pointer, size int32) int32 {
return read(fd, buf, size)
}
//extern write
func write(fd int32, buf unsafe.Pointer, size int32) int32
func Write(fd uintptr, buf unsafe.Pointer, size int32) int32 {
return write(int32(fd), buf, size)
}
func envs() []string
func setenvs([]string)
var Envs = envs
var SetEnvs = setenvs
func Envs() []string { return envs }
func SetEnvs(e []string) { envs = e }
//var BigEndian = sys.BigEndian
......@@ -287,7 +257,10 @@ var ForceGCPeriod = &forcegcperiod
// SetTracebackEnv is like runtime/debug.SetTraceback, but it raises
// the "environment" traceback level, so later calls to
// debug.SetTraceback (e.g., from testing timeouts) can't lower it.
func SetTracebackEnv(level string)
func SetTracebackEnv(level string) {
setTraceback(level)
traceback_env = traceback_cache
}
/*
var ReadUnaligned32 = readUnaligned32
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import (
"runtime/internal/sys"
"unsafe"
)
const (
_AT_NULL = 0 // End of vector
_AT_PAGESZ = 6 // System physical page size
_AT_RANDOM = 25 // introduced in 2.6.29
)
func sysargs(argc int32, argv **byte) {
n := argc + 1
// skip over argv, envp to get to auxv
for argv_index(argv, n) != nil {
n++
}
// skip NULL separator
n++
// now argv+n is auxv
auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
for i := 0; auxv[i] != _AT_NULL; i += 2 {
tag, val := auxv[i], auxv[i+1]
switch tag {
case _AT_RANDOM:
// The kernel provides a pointer to 16-bytes
// worth of random data.
startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
case _AT_PAGESZ:
// Check that the true physical page size is
// compatible with the runtime's assumed
// physical page size.
if sys.PhysPageSize < val {
print("runtime: kernel page size (", val, ") is larger than runtime page size (", sys.PhysPageSize, ")\n")
exit(1)
}
if sys.PhysPageSize%val != 0 {
print("runtime: runtime page size (", sys.PhysPageSize, ") is not a multiple of kernel page size (", val, ")\n")
exit(1)
}
}
// Commented out for gccgo for now.
// archauxv(tag, val)
}
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import (
"runtime/internal/atomic"
_ "unsafe" // for go:linkname
)
//go:generate go run wincallback.go
//go:generate go run mkduff.go
//go:generate go run mkfastlog2table.go
// For gccgo, while we still have C runtime code, use go:linkname to
// rename some functions to themselves, so that the compiler will
// export them.
//
//go:linkname tickspersecond runtime.tickspersecond
var ticks struct {
lock mutex
pad uint32 // ensure 8-byte alignment of val on 386
val uint64
}
// Note: Called by runtime/pprof in addition to runtime code.
func tickspersecond() int64 {
r := int64(atomic.Load64(&ticks.val))
if r != 0 {
return r
}
lock(&ticks.lock)
r = int64(ticks.val)
if r == 0 {
t0 := nanotime()
c0 := cputicks()
usleep(100 * 1000)
t1 := nanotime()
c1 := cputicks()
if t1 == t0 {
t1++
}
r = (c1 - c0) * 1000 * 1000 * 1000 / (t1 - t0)
if r == 0 {
r++
}
atomic.Store64(&ticks.val, uint64(r))
}
unlock(&ticks.lock)
return r
}
var envs []string
var argslice []string
//go:linkname syscall_runtime_envs syscall.runtime_envs
func syscall_runtime_envs() []string { return append([]string{}, envs...) }
//go:linkname os_runtime_args os.runtime_args
func os_runtime_args() []string { return append([]string{}, argslice...) }
// Temporary, for the gccgo runtime code written in C.
//go:linkname get_envs runtime_get_envs
func get_envs() []string { return envs }
//go:linkname get_args runtime_get_args
func get_args() []string { return argslice }
......@@ -678,11 +678,11 @@ type forcegcstate struct {
idle uint32
}
/*
// startup_random_data holds random bytes initialized at startup. These come from
// the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.go or os_linux_386.go).
var startupRandomData []byte
/*
// extendRandom extends the random numbers in r[:n] to the whole slice r.
// Treats n<0 as n==0.
func extendRandom(r []byte, n int) {
......@@ -797,8 +797,8 @@ var (
// Set by the linker so the runtime can determine the buildmode.
var (
// islibrary bool // -buildmode=c-shared
// isarchive bool // -buildmode=c-archive
islibrary bool // -buildmode=c-shared
isarchive bool // -buildmode=c-archive
)
// Types that are only used by gccgo.
......
......@@ -5,6 +5,7 @@
package runtime
import (
"runtime/internal/atomic"
"runtime/internal/sys"
"unsafe"
)
......@@ -209,10 +210,10 @@ func round(n, a uintptr) uintptr {
return (n + a - 1) &^ (a - 1)
}
/*
// checkASM returns whether assembly runtime checks have passed.
func checkASM() bool
*/
func checkASM() bool {
return true
}
// throw crashes the program.
// For gccgo unless and until we port panic.go.
......@@ -251,3 +252,119 @@ type stringStruct struct {
func stringStructOf(sp *string) *stringStruct {
return (*stringStruct)(unsafe.Pointer(sp))
}
// Here for gccgo unless and until we port slice.go.
type slice struct {
array unsafe.Pointer
len int
cap int
}
// Here for gccgo until we port malloc.go.
const (
_64bit = 1 << (^uintptr(0) >> 63) / 2
_MHeapMap_TotalBits = (_64bit*sys.GoosWindows)*35 + (_64bit*(1-sys.GoosWindows)*(1-sys.GoosDarwin*sys.GoarchArm64))*39 + sys.GoosDarwin*sys.GoarchArm64*31 + (1-_64bit)*32
_MaxMem = uintptr(1<<_MHeapMap_TotalBits - 1)
)
// Here for gccgo until we port malloc.go.
//extern runtime_mallocgc
func c_mallocgc(size uintptr, typ uintptr, flag uint32) unsafe.Pointer
func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
flag := uint32(0)
if !needzero {
flag = 1 << 3
}
return c_mallocgc(size, uintptr(unsafe.Pointer(typ)), flag)
}
// Here for gccgo unless and until we port string.go.
func rawstring(size int) (p unsafe.Pointer, s string) {
p = mallocgc(uintptr(size), nil, false)
(*(*stringStruct)(unsafe.Pointer(&s))).str = p
(*(*stringStruct)(unsafe.Pointer(&s))).len = size
return
}
// Here for gccgo unless and until we port string.go.
func gostring(p *byte) string {
l := findnull(p)
if l == 0 {
return ""
}
m, s := rawstring(l)
memmove(m, unsafe.Pointer(p), uintptr(l))
return s
}
// Here for gccgo unless and until we port string.go.
func index(s, t string) int {
if len(t) == 0 {
return 0
}
for i := 0; i < len(s); i++ {
if s[i] == t[0] && hasprefix(s[i:], t) {
return i
}
}
return -1
}
// Here for gccgo unless and until we port string.go.
func hasprefix(s, t string) bool {
return len(s) >= len(t) && s[:len(t)] == t
}
// Here for gccgo unless and until we port string.go.
//go:nosplit
func findnull(s *byte) int {
if s == nil {
return 0
}
p := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s))
l := 0
for p[l] != 0 {
l++
}
return l
}
// Here for gccgo unless and until we port string.go.
//go:nosplit
func gostringnocopy(str *byte) string {
ss := stringStruct{str: unsafe.Pointer(str), len: findnull(str)}
return *(*string)(unsafe.Pointer(&ss))
}
// Here for gccgo unless and until we port string.go.
func atoi(s string) int {
n := 0
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
n = n*10 + int(s[0]) - '0'
s = s[1:]
}
return n
}
// Here for gccgo until we port mgc.go.
var writeBarrier struct {
enabled bool // compiler emits a check of this before calling write barrier
needed bool // whether we need a write barrier for current GC phase
cgo bool // whether we need a write barrier for a cgo check
alignme uint64 // guarantee alignment so that compiler can use a 32 or 64-bit load
}
// Here for gccgo until we port atomic_pointer.go and mgc.go.
//go:nosplit
func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
if !atomic.Casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) {
return false
}
return true
}
// Here for gccgo until we port lock_*.go.
func lock(l *mutex)
func unlock(l *mutex)
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !plan9
// +build !windows
// +build !nacl
package runtime
import "unsafe"
func read(fd int32, p unsafe.Pointer, n int32) int32
func closefd(fd int32) int32
//extern exit
func exit(code int32)
func nanotime() int64
func usleep(usec uint32)
func munmap(addr unsafe.Pointer, n uintptr)
//go:noescape
func write(fd uintptr, p unsafe.Pointer, n int32) int32
//go:noescape
func open(name *byte, mode, perm int32) int32
func madvise(addr unsafe.Pointer, n uintptr, flags int32)
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !linux
package runtime
func sysargs(argc int32, argv **byte) {
}
......@@ -9,7 +9,7 @@
#include "arch.h"
#include "malloc.h"
extern Slice envs;
extern Slice runtime_get_envs(void);
String
runtime_getenv(const char *s)
......@@ -17,12 +17,14 @@ runtime_getenv(const char *s)
int32 i, j;
intgo len;
const byte *v, *bs;
Slice envs;
String* envv;
int32 envc;
String ret;
bs = (const byte*)s;
len = runtime_findnull(bs);
envs = runtime_get_envs();
envv = (String*)envs.__values;
envc = envs.__count;
for(i=0; i<envc; i++){
......
......@@ -76,6 +76,10 @@ static void *back_state;
static Lock back_state_lock;
/* The program arguments. */
extern Slice runtime_get_args(void);
/* Fetch back_state, creating it if necessary. */
struct backtrace_state *
......@@ -84,15 +88,19 @@ __go_get_backtrace_state ()
runtime_lock (&back_state_lock);
if (back_state == NULL)
{
Slice args;
const char *filename;
struct stat s;
filename = (const char *) runtime_progname ();
args = runtime_get_args();
filename = NULL;
if (args.__count > 0)
filename = (const char*)((String*)args.__values)[0].str;
/* If there is no '/' in FILENAME, it was found on PATH, and
might not be the same as the file with the same name in the
current directory. */
if (__builtin_strchr (filename, '/') == NULL)
if (filename != NULL && __builtin_strchr (filename, '/') == NULL)
filename = NULL;
/* If the file is small, then it's not the real executable.
......
......@@ -75,7 +75,6 @@ typedef struct ParFor ParFor;
typedef struct ParForThread ParForThread;
typedef struct cgoMal CgoMal;
typedef struct PollDesc PollDesc;
typedef struct DebugVars DebugVars;
typedef struct __go_open_array Slice;
typedef struct __go_interface Iface;
......@@ -115,7 +114,8 @@ struct FuncVal
* Per-CPU declaration.
*/
extern M* runtime_m(void);
extern G* runtime_g(void);
extern G* runtime_g(void)
__asm__(GOSYM_PREFIX "runtime.getg");
extern M runtime_m0;
extern G runtime_g0;
......@@ -240,28 +240,6 @@ struct ParFor
uint64 nsleep;
};
// Holds variables parsed from GODEBUG env var.
struct DebugVars
{
int32 allocfreetrace;
int32 cgocheck;
int32 efence;
int32 gccheckmark;
int32 gcpacertrace;
int32 gcshrinkstackoff;
int32 gcstackbarrieroff;
int32 gcstackbarrierall;
int32 gcstoptheworld;
int32 gctrace;
int32 gcdead;
int32 invalidptr;
int32 sbrk;
int32 scavenge;
int32 scheddetail;
int32 schedtrace;
int32 wbshadow;
};
extern bool runtime_precisestack;
extern bool runtime_copystack;
......@@ -309,7 +287,7 @@ extern int8* runtime_goos;
extern int32 runtime_ncpu;
extern void (*runtime_sysargs)(int32, uint8**);
extern uint32 runtime_Hchansize;
extern DebugVars runtime_debug;
extern struct debugVars runtime_debug;
extern uintptr runtime_maxstacksize;
extern bool runtime_isstarted;
......@@ -327,11 +305,14 @@ void runtime_dump(byte*, int32);
void runtime_gogo(G*);
struct __go_func_type;
void runtime_args(int32, byte**);
void runtime_args(int32, byte**)
__asm__ (GOSYM_PREFIX "runtime.args");
void runtime_osinit();
void runtime_goargs(void);
void runtime_goargs(void)
__asm__ (GOSYM_PREFIX "runtime.goargs");
void runtime_goenvs(void);
void runtime_goenvs_unix(void);
void runtime_goenvs_unix(void)
__asm__ (GOSYM_PREFIX "runtime.goenvs_unix");
void runtime_throw(const char*) __attribute__ ((noreturn));
void runtime_panicstring(const char*) __attribute__ ((noreturn));
bool runtime_canpanic(G*);
......@@ -377,7 +358,8 @@ int32 runtime_mcount(void);
int32 runtime_gcount(void);
void runtime_mcall(void(*)(G*));
uint32 runtime_fastrand1(void) __asm__ (GOSYM_PREFIX "runtime.fastrand1");
int32 runtime_timediv(int64, int32, int32*);
int32 runtime_timediv(int64, int32, int32*)
__asm__ (GOSYM_PREFIX "runtime.timediv");
int32 runtime_round2(int32 x); // round x up to a power of 2.
// atomic operations
......@@ -417,7 +399,8 @@ G* __go_go(void (*pfn)(void*), void*);
void siginit(void);
bool __go_sigsend(int32 sig);
int32 runtime_callers(int32, Location*, int32, bool keep_callers);
int64 runtime_nanotime(void); // monotonic time
int64 runtime_nanotime(void) // monotonic time
__asm__(GOSYM_PREFIX "runtime.nanotime");
int64 runtime_unixnanotime(void); // real time, can skip
void runtime_dopanic(int32) __attribute__ ((noreturn));
void runtime_startpanic(void);
......@@ -426,9 +409,12 @@ void runtime_unwindstack(G*, byte*);
void runtime_sigprof();
void runtime_resetcpuprofiler(int32);
void runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32);
void runtime_usleep(uint32);
int64 runtime_cputicks(void);
int64 runtime_tickspersecond(void);
void runtime_usleep(uint32)
__asm__ (GOSYM_PREFIX "runtime.usleep");
int64 runtime_cputicks(void)
__asm__ (GOSYM_PREFIX "runtime.cputicks");
int64 runtime_tickspersecond(void)
__asm__ (GOSYM_PREFIX "runtime.tickspersecond");
void runtime_blockevent(int64, int32);
extern int64 runtime_blockprofilerate;
void runtime_addtimer(Timer*);
......@@ -445,7 +431,8 @@ bool runtime_netpollclosing(PollDesc*);
void runtime_netpolllock(PollDesc*);
void runtime_netpollunlock(PollDesc*);
void runtime_crash(void);
void runtime_parsedebugvars(void);
void runtime_parsedebugvars(void)
__asm__(GOSYM_PREFIX "runtime.parsedebugvars");
void _rt0_go(void);
void* runtime_funcdata(Func*, int32);
int32 runtime_setmaxthreads(int32);
......@@ -462,8 +449,10 @@ extern uint32 runtime_worldsema;
* but on the contention path they sleep in the kernel.
* a zeroed Lock is unlocked (no need to initialize each lock).
*/
void runtime_lock(Lock*);
void runtime_unlock(Lock*);
void runtime_lock(Lock*)
__asm__(GOSYM_PREFIX "runtime.lock");
void runtime_unlock(Lock*)
__asm__(GOSYM_PREFIX "runtime.unlock");
/*
* sleep and wakeup on one-time events.
......@@ -609,7 +598,8 @@ enum
#define runtime_setitimer setitimer
void runtime_check(void);
void runtime_check(void)
__asm__ (GOSYM_PREFIX "runtime.check");
// A list of global variables that the garbage collector must scan.
struct root_list {
......@@ -630,7 +620,6 @@ extern uintptr runtime_stacks_sys;
struct backtrace_state;
extern struct backtrace_state *__go_get_backtrace_state(void);
extern _Bool __go_file_line(uintptr, int, String*, String*, intgo *);
extern byte* runtime_progname();
extern void runtime_main(void*);
extern uint32 runtime_in_callers;
......
......@@ -84,13 +84,3 @@ func sync_atomic.runtime_procPin() (p int) {
func sync_atomic.runtime_procUnpin() {
runtime_m()->locks--;
}
extern Slice envs;
func envs() (s Slice) {
s = envs;
}
func setenvs(e Slice) {
envs = e;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment