Skip to content

Commit 6c3fdd2

Browse files
committed
builder: increase stack size margin for automatic stack allocation
Adjust the stack size margin to account for the tinygo_swapTask overhead.
1 parent 1a1506e commit 6c3fdd2

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

builder/build.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,14 @@ func determineStackSizes(mod llvm.Module, executable string) ([]string, map[stri
13521352
}
13531353
baseStackSize, baseStackSizeType, baseStackSizeFailedAt := functions["tinygo_startTask"][0].StackSize()
13541354

1355+
// Account for the bytes that tinygo_swapTask pushes onto the goroutine stack
1356+
// on every context switch. The static analysis correctly traces Go calls,
1357+
// but it cannot see into the assembly-level register push.
1358+
var contextSwitchOverhead uint64
1359+
if swapFuncs, ok := functions["tinygo_swapTask"]; ok && len(swapFuncs) == 1 {
1360+
contextSwitchOverhead = swapFuncs[0].FrameSize
1361+
}
1362+
13551363
sizes := make(map[string]functionStackSize)
13561364

13571365
// Add the reset handler function, for convenience. The reset handler runs
@@ -1400,6 +1408,12 @@ func determineStackSizes(mod llvm.Module, executable string) ([]string, map[stri
14001408
// overflow will occur even before the goroutine is started.
14011409
stackSize = baseStackSize
14021410
}
1411+
if stackSizeType == stacksize.Bounded {
1412+
// Add the overhead of context switching. This is needed because the
1413+
// context switch (tinygo_swapTask) pushes callee-saved registers
1414+
// onto the current stack, which is not seen by the static analysis.
1415+
stackSize += contextSwitchOverhead
1416+
}
14031417
sizes[name] = functionStackSize{
14041418
stackSize: stackSize,
14051419
stackSizeType: stackSizeType,

0 commit comments

Comments
 (0)