builder: try to determine stack size information at compile time

For now, this is just an extra flag that can be used to print stack
frame information, but this is intended to provide a way to determine
stack sizes for goroutines at compile time in many cases.

Stack sizes are often somewhere around 350 bytes so are in fact not all
that big usually. Once this can be determined at compile time in many
cases, it is possible to use this information when available and as a
result increase the fallback stack size if the size cannot be determined
at compile time. This should reduce stack overflows while at the same
time reducing RAM consumption in many cases.

Interesting output for testdata/channel.go:

    function                                 stack usage (in bytes)
    Reset_Handler                            332
    .Lcommand-line-arguments.fastreceiver    220
    .Lcommand-line-arguments.fastsender      192
    .Lcommand-line-arguments.iterator        192
    .Lcommand-line-arguments.main$1          184
    .Lcommand-line-arguments.main$2          200
    .Lcommand-line-arguments.main$3          200
    .Lcommand-line-arguments.main$4          328
    .Lcommand-line-arguments.receive         176
    .Lcommand-line-arguments.selectDeadlock  72
    .Lcommand-line-arguments.selectNoOp      72
    .Lcommand-line-arguments.send            184
    .Lcommand-line-arguments.sendComplex     192
    .Lcommand-line-arguments.sender          192
    .Lruntime.run$1                          548

This shows that the stack size (if these numbers are correct) can in
fact be determined automatically in many cases, especially for small
goroutines. One of the great things about Go is lightweight goroutines,
and reducing stack sizes is very important to make goroutines
lightweight on microcontrollers.
This commit is contained in:
Ayke van Laethem
2020-07-10 17:05:09 +02:00
committed by Ron Evans
parent 60fdf81209
commit d606315515
9 changed files with 681 additions and 0 deletions
+5
View File
@@ -18,6 +18,7 @@ tinygo_startTask:
// After return, exit this goroutine. This is a tail call.
bl tinygo_pause
.size tinygo_startTask, .-tinygo_startTask
.section .text.tinygo_getSystemStackPointer
.global tinygo_getSystemStackPointer
@@ -44,6 +45,7 @@ tinygo_switchToScheduler:
str r1, [r0]
b tinygo_swapTask
.size tinygo_switchToScheduler, .-tinygo_switchToScheduler
.global tinygo_switchToTask
.type tinygo_switchToTask, %function
@@ -56,6 +58,7 @@ tinygo_switchToTask:
// Continue executing in the swapTask function, which swaps the stack
// pointer.
.size tinygo_switchToTask, .-tinygo_switchToTask
.global tinygo_swapTask
.type tinygo_swapTask, %function
@@ -111,6 +114,7 @@ tinygo_swapTask:
mov r11, r3
pop {pc}
#endif
.size tinygo_swapTask, .-tinygo_swapTask
.section .text.tinygo_scanCurrentStack
.global tinygo_scanCurrentStack
@@ -135,3 +139,4 @@ tinygo_scanCurrentStack:
// Restore stack state and return.
add sp, #32
pop {pc}
.size tinygo_scanCurrentStack, .-tinygo_scanCurrentStack