mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
852dde671e
The compiler needs to know whether a defer is in a loop to determine whether to allocate stack or heap memory. Previously, this performed a DFS of the CFG every time a defer was found. This resulted in time complexity jointly proportional to the number of defers and the number of blocks in the function. Now, the compiler will instead use Tarjan's strongly connected components algorithm to find cycles in linear time. The search is performed lazily, so this has minimal performance impact on functions without defers. In order to implement Tarjan's SCC algorithm, additional state needed to be attached to the blocks. I chose to merge all of the per-block state into a single slice to simplify memory management.
41 lines
432 B
Go
41 lines
432 B
Go
package main
|
|
|
|
func external()
|
|
|
|
func deferSimple() {
|
|
defer func() {
|
|
print(3)
|
|
}()
|
|
external()
|
|
}
|
|
|
|
func deferMultiple() {
|
|
defer func() {
|
|
print(3)
|
|
}()
|
|
defer func() {
|
|
print(5)
|
|
}()
|
|
external()
|
|
}
|
|
|
|
func deferInfiniteLoop() {
|
|
for {
|
|
defer print(8)
|
|
}
|
|
}
|
|
|
|
func deferLoop() {
|
|
for i := 0; i < 10; i++ {
|
|
defer print(i)
|
|
}
|
|
}
|
|
|
|
func deferBetweenLoops() {
|
|
for i := 0; i < 10; i++ {
|
|
}
|
|
defer print(1)
|
|
for i := 0; i < 10; i++ {
|
|
}
|
|
}
|