From 6917faabf5ab42dc3be6cfb1da6cabccb15e6e20 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 23 Aug 2019 18:05:31 +0200 Subject: [PATCH] runtime: fix GC to take goroutines into account This fix is needed because with the new task-based scheduler, the current stack pointer may not be on the system stack. --- src/runtime/gc_stack_raw.go | 3 ++- src/runtime/scheduler_coroutines.go | 6 ++++++ src/runtime/scheduler_tasks.go | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/runtime/gc_stack_raw.go b/src/runtime/gc_stack_raw.go index 62fff6b1..d13e90bf 100644 --- a/src/runtime/gc_stack_raw.go +++ b/src/runtime/gc_stack_raw.go @@ -9,5 +9,6 @@ package runtime // the linker) and getting the current stack pointer from a register. Also, it // assumes a descending stack. Thus, it is not very portable. func markStack() { - markRoots(getCurrentStackPointer(), stackTop) + // Mark system stack. + markRoots(getSystemStackPointer(), stackTop) } diff --git a/src/runtime/scheduler_coroutines.go b/src/runtime/scheduler_coroutines.go index fa8fff6c..aa72c357 100644 --- a/src/runtime/scheduler_coroutines.go +++ b/src/runtime/scheduler_coroutines.go @@ -93,3 +93,9 @@ func chanYield() { // Nothing to do here, simply returning from the channel operation also exits // the goroutine temporarily. } + +// getSystemStackPointer returns the current stack pointer of the system stack. +// This is always the current stack pointer. +func getSystemStackPointer() uintptr { + return getCurrentStackPointer() +} diff --git a/src/runtime/scheduler_tasks.go b/src/runtime/scheduler_tasks.go index 8f118921..83565336 100644 --- a/src/runtime/scheduler_tasks.go +++ b/src/runtime/scheduler_tasks.go @@ -129,3 +129,15 @@ func reactivateParent(t *task) { func chanYield() { Goexit() } + +// getSystemStackPointer returns the current stack pointer of the system stack. +// This is not necessarily the same as the current stack pointer. +func getSystemStackPointer() uintptr { + if currentTask == nil { + // Currently on the system stack. + return getCurrentStackPointer() + } else { + // Currently in a goroutine. + return schedulerState.sp + } +}