# 2019q1 Homework6 (gc)
contributed by < `afcidk` >
* [F10: gc](https://hackmd.io/s/SkZpf5HiE)
## 資料結構
### \_\_gc\_ptr
```
struct __gc_ptr {
uintptr_t start;
size_t size;
bool marked;
};
```
gc_ptr 紀錄的是可能被配置過的記憶體區塊,我們需要開頭的位址、長度以及是否被 mark 過。
### \_\_gc\_list
```
struct __gc_list {
struct __gc_list *next;
gc_ptr_t data;
};
```
gc_list 是一個 linked list,把所有的 gc_ptr 串起來。
### \_\_gc
```
struct __gc {
void *stack_start;
gc_list_t *ptr_map[PTR_MAP_SIZE];
size_t ptr_num;
size_t limit;
size_t ref_count;
uintptr_t min, max;
gc_list_t *globals;
};
```
gc 是在整個程式裏面唯一的一個 garbage collector
* stack_start
gc 執行時起始的 stack 位址,在 test 中我們直接取 argc 的位址當作 stack 的起始位址。之後在執行 `gc_run` 的時候會以 stack_start 當起點開始掃。
* ptr_map
ptr_map 把記憶體分成數個相同大小的區塊來儲存,如果遇到已經被佔用的 ptr_map,會透過 linked list 來儲存起來。這樣做可以減少純粹使用 linked list 時搜尋需要花費的時間。
* ptr_num
當前的 gc 紀錄的 gc_ptr 數量,如果超過 limit 就會執行 garbage collect。
* limit
gc 中 garbage collect 的下限,如果當前 gc 紀錄的 gc_ptr 數量超過 limit 的話就會執行 garbage collect(gc_run)。
* ref_count
gc object 在整份程式中只能有一份 instance。ref_count 是用來紀錄 gc 當前有幾份 reference,當最後一個 reference 被刪除時,需要順帶把其佔用的記憶體空間也釋放掉。
* min, max
min 還有 max 用來標示當前 gc 維護的記憶體位址範圍。在 `gc_ptr_index` 中會先判斷我們傳入的指標是否在範圍內,若不是則不必尋找且回傳 NULL。
* globals
觀察程式碼,發現 globals 只可能被指派成 NULL, 推測一開始應該是想要對 global variable 做 garbage collection,但是還沒寫好或是因為某些原因忘記刪除而已。
> 說是這樣說,但是我想不太到 global variable 應該被 gc 的時間點
```
./src/utils.c: for (gc_list_t *e = __gc_object.globals; e; e = e->next) {
./src/core.c: .globals = NULL};
./src/gc_internal.h: gc_list_t *globals;
```