Commit 267aee1
committed
runtime (gc): restructure blocks GC metadata
Originally, the blocks GC simply stored a 2-bit state value for each block with 4 options:
- umarked head
- marked head
- tail (continuation of an object)
- free
The GC cycled the blocks through these states appropriately.
Then the allocator would search for appropriate ranges of free blocks.
This design resulted in excessive memory fragmentation due to the way that the allocator had to search for free ranges.
To fix this issue, we created a data structure to track the free ranges that is rebuilt after every GC.
This mostly fixed the memory fragmentation issue.
The other issue with this original approach is that it resulted in quadratic performance degredation when scanning free lists.
To solve this, we added a header to each heap object to form a linked stack.
This ensured that each object only needed to be visited once.
As these improvements were made, TinyGo began practically supporting larger and larger heaps.
The current structure where we loop over individual blocks is no longer efficient.
We need to change the metadata to support more efficient traversal.
This commit changes the per-block metadata into a pair of bitmaps: an "ends" bitmap and a "visited" bitmap.
The "ends" bitmap is used by the marking and sweeping logic to find the end (containing the header) of an object.
The "visited" bitmap is to track blocks which have been visited by mark, including both ends and non-ends.
Most operations can be performed by scanning over these bitmaps rather than looping over individual blocks.
The "visited" bitmap also fixes the last remaining case for quadratic performance degredation.
In the event that many pointers referred to the start of a large object, the marking code would scan across the whole object to find the end every time.
The new marking code adds every block between the marked address and the end to the bitmap.
Subsequent marks to the same object will detect the already-visited tail and stop early.1 parent 6f686d1 commit 267aee1
11 files changed
Lines changed: 611 additions & 461 deletions
File tree
- builder
- compiler
- src/runtime
- targets
- testdata
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
47 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
96 | 101 | | |
97 | 102 | | |
98 | 103 | | |
| |||
162 | 167 | | |
163 | 168 | | |
164 | 169 | | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
165 | 175 | | |
166 | 176 | | |
167 | 177 | | |
| |||
0 commit comments