aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/mgcmark.go4
-rw-r--r--src/runtime/stack.go16
2 files changed, 19 insertions, 1 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 2d0cbd203c..00b96fd00b 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -174,7 +174,9 @@ func markroot(gcw *gcWork, i uint32) {
// Only do this once per GC cycle; preferably
// concurrently.
if !work.markrootDone {
- markrootFreeGStacks()
+ // Switch to the system stack so we can call
+ // stackfree.
+ systemstack(markrootFreeGStacks)
}
case baseSpans <= i && i < baseStacks:
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 8e344cdf03..ee2797e144 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -251,6 +251,8 @@ func stackpoolfree(x gclinkptr, order uint8) {
// stackcacherefill/stackcacherelease implement a global pool of stack segments.
// The pool is required to prevent unlimited growth of per-thread caches.
+//
+//go:systemstack
func stackcacherefill(c *mcache, order uint8) {
if stackDebug >= 1 {
print("stackcacherefill order=", order, "\n")
@@ -272,6 +274,7 @@ func stackcacherefill(c *mcache, order uint8) {
c.stackcache[order].size = size
}
+//go:systemstack
func stackcacherelease(c *mcache, order uint8) {
if stackDebug >= 1 {
print("stackcacherelease order=", order, "\n")
@@ -290,6 +293,7 @@ func stackcacherelease(c *mcache, order uint8) {
c.stackcache[order].size = size
}
+//go:systemstack
func stackcache_clear(c *mcache) {
if stackDebug >= 1 {
print("stackcache clear\n")
@@ -308,6 +312,12 @@ func stackcache_clear(c *mcache) {
unlock(&stackpoolmu)
}
+// stackalloc allocates an n byte stack.
+//
+// stackalloc must run on the system stack because it uses per-P
+// resources and must not split the stack.
+//
+//go:systemstack
func stackalloc(n uint32) (stack, []stkbar) {
// Stackalloc must be called on scheduler stack, so that we
// never try to grow the stack during the code that stackalloc runs.
@@ -405,6 +415,12 @@ func stackalloc(n uint32) (stack, []stkbar) {
return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice))
}
+// stackfree frees an n byte stack allocation at stk.
+//
+// stackfree must run on the system stack because it uses per-P
+// resources and must not split the stack.
+//
+//go:systemstack
func stackfree(stk stack, n uintptr) {
gp := getg()
v := unsafe.Pointer(stk.lo)