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