summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-09-24 16:55:26 -0400
committerRuss Cox <rsc@golang.org>2014-09-24 16:55:26 -0400
commit14c9b3be770b4a59a4113783600b8d4b06f5ccd3 (patch)
treebbfc37060802619fcfbe4ce647a6571e16e86448 /src/runtime
parent8ca4b32a4ef76cacf6ac5a1ae0e2a1a1113490ee (diff)
downloadgo-14c9b3be770b4a59a4113783600b8d4b06f5ccd3.tar.gz
cmd/cc, cmd/ld, runtime: disallow conservative data/bss objects
In linker, refuse to write conservative (array of pointers) as the garbage collection type for any variable in the data/bss GC program. In the linker, attach the Go type to an already-read C declaration during dedup. This gives us Go types for C globals for free as long as the cmd/dist-generated Go code contains the declaration. (Most runtime C declarations have a corresponding Go declaration. Both are bss declarations and so the linker dedups them.) In cmd/dist, add a few more C files to the auto-Go-declaration list in order to get Go type information for the C declarations into the linker. In C compiler, mark all non-pointer-containing global declarations and all string data as NOPTR. This allows them to exist in C files without any corresponding Go declaration. Count C function pointers as "non-pointer-containing", since we have no heap-allocated C functions. In runtime, add NOPTR to the remaining pointer-containing declarations, none of which refer to Go heap objects. In runtime, also move os.Args and syscall.envs data into runtime-owned variables. Otherwise, in programs that do not import os or syscall, the runtime variables named os.Args and syscall.envs will be missing type information. I believe that this CL eliminates the final source of conservative GC scanning in non-SWIG Go programs, and therefore... Fixes issue 909. LGTM=iant R=iant CC=golang-codereviews https://codereview.appspot.com/149770043
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm_386.s2
-rw-r--r--src/runtime/asm_amd64.s2
-rw-r--r--src/runtime/asm_amd64p32.s2
-rw-r--r--src/runtime/heapdump.c3
-rw-r--r--src/runtime/malloc.c23
-rw-r--r--src/runtime/malloc.h2
-rw-r--r--src/runtime/mcache.c2
-rw-r--r--src/runtime/mgc0.c5
-rw-r--r--src/runtime/os_windows.c6
-rw-r--r--src/runtime/proc.c30
-rw-r--r--src/runtime/proc.go8
-rw-r--r--src/runtime/runtime.c25
-rw-r--r--src/runtime/runtime.go11
-rw-r--r--src/runtime/signals_darwin.h3
-rw-r--r--src/runtime/signals_dragonfly.h3
-rw-r--r--src/runtime/signals_freebsd.h3
-rw-r--r--src/runtime/signals_linux.h3
-rw-r--r--src/runtime/signals_nacl.h3
-rw-r--r--src/runtime/signals_netbsd.h3
-rw-r--r--src/runtime/signals_openbsd.h3
-rw-r--r--src/runtime/signals_plan9.h3
-rw-r--r--src/runtime/signals_solaris.h3
-rw-r--r--src/runtime/stack.c4
-rw-r--r--src/runtime/thunk.s8
24 files changed, 89 insertions, 71 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index 2961f10f2..846a214d5 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -903,8 +903,6 @@ TEXT runtime·emptyfunc(SB),0,$0-0
TEXT runtime·abort(SB),NOSPLIT,$0-0
INT $0x3
-GLOBL runtime·tls0(SB), $32
-
// hash function using AES hardware instructions
TEXT runtime·aeshash(SB),NOSPLIT,$0-16
MOVL p+0(FP), AX // ptr to data
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 44159bb57..7304d79a2 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -871,8 +871,6 @@ TEXT runtime·gocputicks(SB),NOSPLIT,$0-8
MOVQ AX, ret+0(FP)
RET
-GLOBL runtime·tls0(SB), $64
-
// hash function using AES hardware instructions
TEXT runtime·aeshash(SB),NOSPLIT,$0-32
MOVQ p+0(FP), AX // ptr to data
diff --git a/src/runtime/asm_amd64p32.s b/src/runtime/asm_amd64p32.s
index bbbd886a5..13a164256 100644
--- a/src/runtime/asm_amd64p32.s
+++ b/src/runtime/asm_amd64p32.s
@@ -674,8 +674,6 @@ TEXT runtime·gocputicks(SB),NOSPLIT,$0-8
MOVQ AX, ret+0(FP)
RET
-GLOBL runtime·tls0(SB), $64
-
// hash function using AES hardware instructions
// For now, our one amd64p32 system (NaCl) does not
// support using AES instructions, so have not bothered to
diff --git a/src/runtime/heapdump.c b/src/runtime/heapdump.c
index 75897c3d3..54b9666b5 100644
--- a/src/runtime/heapdump.c
+++ b/src/runtime/heapdump.c
@@ -59,6 +59,8 @@ static BitVector makeheapobjbv(byte *p, uintptr size);
// fd to write the dump to.
static uintptr dumpfd;
+
+#pragma dataflag NOPTR /* tmpbuf not a heap pointer at least */
static byte *tmpbuf;
static uintptr tmpbufsize;
@@ -109,6 +111,7 @@ typedef struct TypeCacheBucket TypeCacheBucket;
struct TypeCacheBucket {
Type *t[TypeCacheAssoc];
};
+#pragma dataflag NOPTR /* only initialized and used while world is stopped */
static TypeCacheBucket typecache[TypeCacheBuckets];
// dump a uint64 in a varint format parseable by encoding/binary
diff --git a/src/runtime/malloc.c b/src/runtime/malloc.c
index 60d20a992..b79c30b72 100644
--- a/src/runtime/malloc.c
+++ b/src/runtime/malloc.c
@@ -329,29 +329,6 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
return p;
}
-// Runtime stubs.
-
-static void*
-cnew(Type *typ, intgo n)
-{
- if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
- runtime·throw("runtime: allocation size out of range");
- return runtime·mallocgc(typ->size*n, typ, typ->kind&KindNoPointers ? FlagNoScan : 0);
-}
-
-// same as runtime·new, but callable from C
-void*
-runtime·cnew(Type *typ)
-{
- return cnew(typ, 1);
-}
-
-void*
-runtime·cnewarray(Type *typ, intgo n)
-{
- return cnew(typ, n);
-}
-
void
runtime·setFinalizer_m(void)
{
diff --git a/src/runtime/malloc.h b/src/runtime/malloc.h
index 410a00717..b90f1baf2 100644
--- a/src/runtime/malloc.h
+++ b/src/runtime/malloc.h
@@ -526,8 +526,6 @@ uintptr runtime·sweepone(void);
void runtime·markspan(void *v, uintptr size, uintptr n, bool leftover);
void runtime·unmarkspan(void *v, uintptr size);
void runtime·purgecachedstats(MCache*);
-void* runtime·cnew(Type*);
-void* runtime·cnewarray(Type*, intgo);
void runtime·tracealloc(void*, uintptr, Type*);
void runtime·tracefree(void*, uintptr);
void runtime·tracegc(void);
diff --git a/src/runtime/mcache.c b/src/runtime/mcache.c
index 17ea5d2e2..5fdbe3266 100644
--- a/src/runtime/mcache.c
+++ b/src/runtime/mcache.c
@@ -13,7 +13,7 @@
extern volatile intgo runtime·MemProfileRate;
// dummy MSpan that contains no free objects.
-static MSpan runtime·emptymspan;
+MSpan runtime·emptymspan;
MCache*
runtime·allocmcache(void)
diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c
index 54728d5ad..c92fa1db7 100644
--- a/src/runtime/mgc0.c
+++ b/src/runtime/mgc0.c
@@ -120,7 +120,7 @@ FinBlock* runtime·finc; // cache of free blocks
static byte finptrmask[FinBlockSize/PtrSize/PointersPerByte];
bool runtime·fingwait;
bool runtime·fingwake;
-static FinBlock *runtime·allfin; // list of all blocks
+FinBlock *runtime·allfin; // list of all blocks
BitVector runtime·gcdatamask;
BitVector runtime·gcbssmask;
@@ -140,7 +140,7 @@ static BitVector unrollglobgcprog(byte *prog, uintptr size);
void runtime·bgsweep(void);
static FuncVal bgsweepv = {runtime·bgsweep};
-static struct {
+struct {
uint64 full; // lock-free list of full blocks
uint64 empty; // lock-free list of empty blocks
byte pad0[CacheLineSize]; // prevents false-sharing between full/empty and nproc/nwait
@@ -1038,7 +1038,6 @@ runtime·MSpan_Sweep(MSpan *s, bool preserve)
// State of background runtime·sweep.
// Protected by runtime·gclock.
-// Must match mgc0.go.
struct
{
G* g;
diff --git a/src/runtime/os_windows.c b/src/runtime/os_windows.c
index 62d94b65a..6546d51d3 100644
--- a/src/runtime/os_windows.c
+++ b/src/runtime/os_windows.c
@@ -147,7 +147,7 @@ runtime·get_random_data(byte **rnd, int32 *rnd_len)
void
runtime·goenvs(void)
{
- extern Slice syscall·envs;
+ extern Slice runtime·envs;
uint16 *env;
String *s;
@@ -160,8 +160,8 @@ runtime·goenvs(void)
for(p=env; *p; n++)
p += runtime·findnullw(p)+1;
- syscall·envs = runtime·makeStringSlice(n);
- s = (String*)syscall·envs.array;
+ runtime·envs = runtime·makeStringSlice(n);
+ s = (String*)runtime·envs.array;
p = env;
for(i=0; i<n; i++) {
diff --git a/src/runtime/proc.c b/src/runtime/proc.c
index 564798be7..1f0a79098 100644
--- a/src/runtime/proc.c
+++ b/src/runtime/proc.c
@@ -102,9 +102,9 @@ extern String runtime·buildVersion;
#pragma cgo_export_static main
// Filled in by dynamic linker when Cgo is available.
-void* _cgo_init;
-void* _cgo_malloc;
-void* _cgo_free;
+void (*_cgo_init)(void);
+void (*_cgo_malloc)(void);
+void (*_cgo_free)(void);
// Copy for Go code.
void* runtime·cgoMalloc;
@@ -852,24 +852,19 @@ struct CgoThreadStart
void (*fn)(void);
};
+M *runtime·newM(void); // in proc.go
+
// Allocate a new m unassociated with any thread.
// Can use p for allocation context if needed.
M*
runtime·allocm(P *p)
{
M *mp;
- static Type *mtype; // The Go type M
g->m->locks++; // disable GC because it can be called from sysmon
if(g->m->p == nil)
acquirep(p); // temporarily borrow p for mallocs in this function
- if(mtype == nil) {
- Eface e;
- runtime·gc_m_ptr(&e);
- mtype = ((PtrType*)e.type)->elem;
- }
-
- mp = runtime·cnew(mtype);
+ mp = runtime·newM();
mcommoninit(mp);
// In case of cgo or Solaris, pthread_create will make us a stack.
@@ -889,19 +884,12 @@ runtime·allocm(P *p)
return mp;
}
+G *runtime·newG(void); // in proc.go
+
static G*
allocg(void)
{
- G *gp;
- static Type *gtype;
-
- if(gtype == nil) {
- Eface e;
- runtime·gc_g_ptr(&e);
- gtype = ((PtrType*)e.type)->elem;
- }
- gp = runtime·cnew(gtype);
- return gp;
+ return runtime·newG();
}
static M* lockextra(bool nilokay);
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 9b9586859..4bb661b54 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -202,6 +202,14 @@ func newP() *p {
return new(p)
}
+func newM() *m {
+ return new(m)
+}
+
+func newG() *g {
+ return new(g)
+}
+
func allgadd(gp *g) {
if readgstatus(gp) == _Gidle {
gothrow("allgadd: bad status Gidle")
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index aa8dd8f7a..b3503fb90 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -62,10 +62,12 @@ runtime·mchr(byte *p, byte c, byte *ep)
}
static int32 argc;
+
+#pragma dataflag NOPTR /* argv not a heap pointer */
static uint8** argv;
-Slice os·Args;
-Slice syscall·envs;
+extern Slice runtime·argslice;
+extern Slice runtime·envs;
void (*runtime·sysargs)(int32, uint8**);
@@ -97,8 +99,8 @@ runtime·goargs(void)
if(Windows)
return;
- os·Args = runtime·makeStringSlice(argc);
- s = (String*)os·Args.array;
+ runtime·argslice = runtime·makeStringSlice(argc);
+ s = (String*)runtime·argslice.array;
for(i=0; i<argc; i++)
s[i] = runtime·gostringnocopy(argv[i]);
}
@@ -112,8 +114,8 @@ runtime·goenvs_unix(void)
for(n=0; argv[argc+1+n] != 0; n++)
;
- syscall·envs = runtime·makeStringSlice(n);
- s = (String*)syscall·envs.array;
+ runtime·envs = runtime·makeStringSlice(n);
+ s = (String*)runtime·envs.array;
for(i=0; i<n; i++)
s[i] = runtime·gostringnocopy(argv[argc+1+i]);
}
@@ -122,7 +124,7 @@ runtime·goenvs_unix(void)
Slice
runtime·environ()
{
- return syscall·envs;
+ return runtime·envs;
}
int32
@@ -267,10 +269,15 @@ runtime·check(void)
#pragma dataflag NOPTR
DebugVars runtime·debug;
-static struct {
+typedef struct DbgVar DbgVar;
+struct DbgVar
+{
int8* name;
int32* value;
-} dbgvar[] = {
+};
+
+#pragma dataflag NOPTR /* dbgvar has no heap pointers */
+static DbgVar dbgvar[] = {
{"allocfreetrace", &runtime·debug.allocfreetrace},
{"efence", &runtime·debug.efence},
{"gctrace", &runtime·debug.gctrace},
diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go
index dbaea45a6..4e4e1d17a 100644
--- a/src/runtime/runtime.go
+++ b/src/runtime/runtime.go
@@ -9,6 +9,8 @@ var ticks struct {
val uint64
}
+var tls0 [8]uintptr // available storage for m0's TLS; not necessarily used; opaque to GC
+
// Note: Called by runtime/pprof in addition to runtime code.
func tickspersecond() int64 {
r := int64(atomicload64(&ticks.val))
@@ -47,3 +49,12 @@ func parforalloc(nthrmax uint32) *parfor {
nthrmax: nthrmax,
}
}
+
+var envs []string
+var argslice []string
+
+// called from syscall
+func runtime_envs() []string { return envs }
+
+// called from os
+func runtime_args() []string { return argslice }
diff --git a/src/runtime/signals_darwin.h b/src/runtime/signals_darwin.h
index 229b58590..8761e1bd9 100644
--- a/src/runtime/signals_darwin.h
+++ b/src/runtime/signals_darwin.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_dragonfly.h b/src/runtime/signals_dragonfly.h
index 4d27e050d..07343a766 100644
--- a/src/runtime/signals_dragonfly.h
+++ b/src/runtime/signals_dragonfly.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_freebsd.h b/src/runtime/signals_freebsd.h
index 8d45c50c3..39e0a947e 100644
--- a/src/runtime/signals_freebsd.h
+++ b/src/runtime/signals_freebsd.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_linux.h b/src/runtime/signals_linux.h
index 368afc1c8..374107609 100644
--- a/src/runtime/signals_linux.h
+++ b/src/runtime/signals_linux.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_nacl.h b/src/runtime/signals_nacl.h
index 229b58590..8761e1bd9 100644
--- a/src/runtime/signals_nacl.h
+++ b/src/runtime/signals_nacl.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_netbsd.h b/src/runtime/signals_netbsd.h
index 7140de86f..950a2fe62 100644
--- a/src/runtime/signals_netbsd.h
+++ b/src/runtime/signals_netbsd.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_openbsd.h b/src/runtime/signals_openbsd.h
index 7140de86f..950a2fe62 100644
--- a/src/runtime/signals_openbsd.h
+++ b/src/runtime/signals_openbsd.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: terminal line hangup",
diff --git a/src/runtime/signals_plan9.h b/src/runtime/signals_plan9.h
index 818f508cf..4ee8e542c 100644
--- a/src/runtime/signals_plan9.h
+++ b/src/runtime/signals_plan9.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
@@ -16,6 +18,7 @@
// If you add entries to this table, you must respect the prefix ordering
// and also update the constant values is os_plan9.h.
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
// Traps that we cannot be recovered.
T, "sys: trap: debug exception",
diff --git a/src/runtime/signals_solaris.h b/src/runtime/signals_solaris.h
index c272cad29..1f0a65ea6 100644
--- a/src/runtime/signals_solaris.h
+++ b/src/runtime/signals_solaris.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "textflag.h"
+
#define N SigNotify
#define K SigKill
#define T SigThrow
#define P SigPanic
#define D SigDefault
+#pragma dataflag NOPTR
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ N+K, "SIGHUP: hangup",
diff --git a/src/runtime/stack.c b/src/runtime/stack.c
index 6fbab8fb6..0d8814731 100644
--- a/src/runtime/stack.c
+++ b/src/runtime/stack.c
@@ -32,8 +32,8 @@ enum
// Stacks are assigned an order according to size.
// order = log_2(size/FixedStack)
// There is a free list for each order.
-static MSpan runtime·stackpool[NumStackOrders];
-static Mutex runtime·stackpoolmu;
+MSpan runtime·stackpool[NumStackOrders];
+Mutex runtime·stackpoolmu;
// TODO: one lock per order?
void
diff --git a/src/runtime/thunk.s b/src/runtime/thunk.s
index 5e8e674f5..d6a2d399e 100644
--- a/src/runtime/thunk.s
+++ b/src/runtime/thunk.s
@@ -164,7 +164,7 @@ TEXT runtime·main_init(SB),NOSPLIT,$0-0
TEXT runtime·main_main(SB),NOSPLIT,$0-0
JMP main·main(SB)
-TEXT runtime·timenow(SB), NOSPLIT, $0-0
+TEXT runtime·timenow(SB),NOSPLIT,$0-0
JMP time·now(SB)
TEXT sync∕atomic·runtime_procPin(SB),NOSPLIT,$0-0
@@ -172,3 +172,9 @@ TEXT sync∕atomic·runtime_procPin(SB),NOSPLIT,$0-0
TEXT sync∕atomic·runtime_procUnpin(SB),NOSPLIT,$0-0
JMP sync·runtime_procUnpin(SB)
+
+TEXT syscall·runtime_envs(SB),NOSPLIT,$0-0
+ JMP runtime·runtime_envs(SB)
+
+TEXT os·runtime_args(SB),NOSPLIT,$0-0
+ JMP runtime·runtime_args(SB)