Skip to content

Commit 866e917

Browse files
committed
docs: add immix sweep docs
1 parent 82b5748 commit 866e917

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

book/src/references/immix.md

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub type VtableFunc = fn(*mut u8, &Collector, VisitFunc, VisitFunc, VisitFunc);
217217

218218
```mermaid
219219
graph LR;
220-
subgraph Roots
220+
subgraph Stack
221221
Root1
222222
Root2
223223
Root3
@@ -314,7 +314,69 @@ Sweep阶段的主要工作是:
314314

315315
真正的evacuation过程是在`mark`阶段一起完成的,我们会在遍历到处于待evacuate的block中的对象时,为它分配一个新的地址,并且
316316
将它原地址的值替换为一个指向新地址的指针(forward pointer),且将line header中的`forward`字段设置为`true`。之后如果再次遍历到
317-
该对象,收集器会修正指向原地址的指针的值,这一过程我们称之为自愈。
317+
该对象,收集器会修正指向原地址的指针的值,这一过程我们称之为自愈。该过程如下图所示
318+
319+
```mermaid
320+
graph TD;
321+
subgraph BeforeEva
322+
direction TB
323+
EvaBlock
324+
EmptyBlock
325+
Pointer
326+
end
327+
subgraph EvaBlock
328+
Line1
329+
Line2
330+
LineK[...]
331+
LineN
332+
end
333+
subgraph Line1
334+
Addr[addr: 0x1000]
335+
Value[value: 0x4321]
336+
Forward[forward: false]
337+
end
338+
subgraph EmptyBlock
339+
EL1
340+
ELK[...]
341+
end
342+
subgraph EL1[Line1]
343+
AddrEL[addr: 0x2000]
344+
ValueEL[value: 0x0000]
345+
end
346+
Pointer
347+
Pointer-->Line1
348+
subgraph AfterEva
349+
direction TB
350+
EvaBlock1
351+
EmptyBlock1
352+
Pointer1[Pointer]
353+
end
354+
subgraph EvaBlock1[EvaBlock]
355+
Line11
356+
Line21[Line2]
357+
LineK1[...]
358+
LineN1[LineN]
359+
end
360+
subgraph Line11[Line1]
361+
Addr1[addr: 0x1000]
362+
Value1[value: 0x2000]
363+
Forward1[forward: true]
364+
end
365+
subgraph EmptyBlock1[EmptyBlock]
366+
EL11
367+
ELK1[...]
368+
end
369+
subgraph EL11[Line1]
370+
AddrEL1[addr: 0x2000]
371+
ValueEL1[value: 0x4321]
372+
end
373+
Pointer1-->EL11
374+
BeforeEva-->AfterEva
375+
376+
```
377+
378+
每次驱逐是以分配的对象为单位,如果一个block被标记为待evacuate,那么在驱逐过程中,该block中的所有对象都一定会被驱逐。
379+
318380

319381
请注意,一部分其他gc的驱逐算法中的自愈需要读写屏障的参与,immix不需要。这带来了较大的mutator性能提升。
320382

book/src/references/stackmap.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ graph LR;
8585
```
8686

8787
```admonish tip title="gc safepoint介绍"
88-
safepoint说白了就是潜在的可以触发gc的点位,本来多用于进行多线程回收的同步:大部分gc
88+
safepoint是潜在的可以触发gc的点位,本来多用于进行多线程回收的同步:大部分gc
8989
回收算法在回收时(全部或一部分时间)是不允许mutator运行的,这个时候需要暂停所有mutator
9090
线程(stop the world),等回收完成后再恢复。使用safepoint机制的gc,在mutator线程运行到safepoint时会对
9191
一个特殊flag进行检查,以判断自己是否需要暂停进行gc。在我们的immix gc中,
@@ -94,6 +94,12 @@ safepoint通常由其中一个工作线程在自己的safepoint发起,别的
9494
safepoint处理。
9595
9696
safepoint对于stackmap至关重要,因为在回收时gc就是通过在stackmap中查询当前暂停对应的safepoint地址来获取当前栈中的root集的。在暂停的时候safepoint地址在当前栈帧的ip寄存器中。
97+
98+
由于gc回收需要等待所有线程到达safepoint,所以如果一个线程长期不到达safepoint,别的线程在回收的时候就可能会一直等待。因此
99+
immix提供一些工具函数。`thread_stuck_start`和`thread_stuck_end`,用于标记线程在执行某些长时间“卡住”的任务,在此期间
100+
该线程需要保证不会使用gc分配新的内存,否则可能导致内存安全问题。在线程被标记为stuck的阶段触发的gc会跳过同步该线程。`no_gc_thread`
101+
可以告知gc目前正在执行的线程不需要gc功能,该线程不会分配对应的ThreadLocalAllocator。
102+
97103
```
98104

99105
我们的llvm插件会将stackmap信息生成到每个目标文件的数据段中,应用程序可以使用weak link的方式用对应的全局变量获取到这个数据标签对应的地址,然后就可以通过这个地址来获取到stackmap信息了。对应数据区域标签的命名规则是:`_GC_MAP_$source_file_name`,其中`$source_file_name`是对应llvm module中记录的的源文件名。

0 commit comments

Comments
 (0)