Commit 08e25fc1 authored by Russ Cox's avatar Russ Cox

cmd/compile: introduce //go:systemstack annotation

//go:systemstack means that the function must run on the system stack.

Add one use in runtime as a demonstration.

Fixes #9174.

Change-Id: I8d4a509cb313541426157da703f1c022e964ace4
Reviewed-on: https://go-review.googlesource.com/10840Reviewed-by: 's avatarAustin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
parent e3dc59f3
......@@ -654,11 +654,13 @@ var flag_race int
var flag_largemodel int
var noescape bool
var nosplit bool
var nowritebarrier bool
// Pending annotations for next func declaration.
var (
noescape bool
nosplit bool
nowritebarrier bool
systemstack bool
)
var debuglive int
......
......@@ -1392,6 +1392,7 @@ xfndcl:
$$.Noescape = noescape;
$$.Func.Nosplit = nosplit;
$$.Func.Nowritebarrier = nowritebarrier;
$$.Func.Systemstack = systemstack;
funcbody($$);
}
......@@ -1580,6 +1581,7 @@ xdcl_list:
noescape = false
nosplit = false
nowritebarrier = false
systemstack = false
}
vardcl_list:
......
......@@ -1597,6 +1597,11 @@ func getlinepragma() int {
return c
}
if verb == "go:systemstack" {
systemstack = true
return c
}
if verb == "go:nowritebarrier" {
if compiling_runtime == 0 {
Yyerror("//go:nowritebarrier only allowed in runtime")
......
......@@ -418,6 +418,7 @@ func compile(fn *Node) {
nam = nil
}
ptxt = Thearch.Gins(obj.ATEXT, nam, &nod1)
Afunclit(&ptxt.From, Curfn.Func.Nname)
ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok {
ptxt.From3.Offset |= obj.DUPOK
......@@ -431,6 +432,9 @@ func compile(fn *Node) {
if fn.Func.Nosplit {
ptxt.From3.Offset |= obj.NOSPLIT
}
if fn.Func.Systemstack {
ptxt.From.Sym.Cfunc = 1
}
// Clumsy but important.
// See test/recover.go for test cases and src/reflect/value.go
......@@ -441,8 +445,6 @@ func compile(fn *Node) {
}
}
Afunclit(&ptxt.From, Curfn.Func.Nname)
ginit()
gcargs = makefuncdatasym("gcargs·%d", obj.FUNCDATA_ArgsPointerMaps)
......
......@@ -174,6 +174,7 @@ type Func struct {
Dupok bool // duplicate definitions ok
Wrapper bool // is method wrapper
Needctxt bool // function uses context register (has closure variables)
Systemstack bool // must run on system stack
}
// Node ops.
......
This diff is collapsed.
......@@ -797,6 +797,17 @@ var globalAlloc struct {
// Intended for things like function/type/debug-related persistent data.
// If align is 0, uses default align (currently 8).
func persistentalloc(size, align uintptr, sysStat *uint64) unsafe.Pointer {
var p unsafe.Pointer
systemstack(func() {
p = persistentalloc1(size, align, sysStat)
})
return p
}
// Must run on system stack because stack growth can (re)invoke it.
// See issue 9174.
//go:systemstack
func persistentalloc1(size, align uintptr, sysStat *uint64) unsafe.Pointer {
const (
chunk = 256 << 10
maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
......
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