Mou*_*Lin 5 .net clr jit garbage-collection
这个好的答案解释了GC在方法执行完毕之前如何收集局部变量:
当抖动将IL编译为机器代码时,抖动执行两个重要的任务.... 它还生成一个表,描述如何使用方法体内的局部变量.该表具有每个方法参数的条目和具有两个地址的局部变量.变量首先存储对象引用的地址.以及不再使用该变量的机器代码指令的地址.......表中的"不再使用"地址非常重要.它使垃圾收集器非常有效.它可以收集对象引用,即使它在方法中使用并且该方法尚未完成执行.
我很好奇JIT如何创建内部表,以及如何在真正的clr源代码中维护"不再使用"地址.有人能在最近开源的coreclr源代码中向我展示相关的代码片段吗?
免责声明:我不是 CLR 或 RyuJIT 方面的专家。我对这一切的看法可能完全错误。
对于具有跟踪生命周期的 lvlVar,或者对于涉及 GC 引用的表达式,我们报告引用的有效范围。这是由发射器完成的,发射器将此信息添加到指令组,并在 GC 信息更改时终止指令组。
存储此信息的结构可以在jit/jitgcinfo.h中找到,如下所示:
struct varPtrDsc
{
varPtrDsc * vpdNext;
unsigned vpdVarNum; // which variable is this about?
unsigned vpdBegOfs ; // the offset where life starts
unsigned vpdEndOfs; // the offset where life starts
};
Run Code Online (Sandbox Code Playgroud)
我上面引用的段落表明这些字段由“发射器”填充,我相信它们的意思是jit/emit.cpp。
生命周期间隔的开始时间设置为emitter::emitGCvarLiveSet();相关摘录为(为简洁起见,删除了空白):
/* Allocate a lifetime record */
desc = new (emitComp, CMK_GC) varPtrDsc;
desc->vpdBegOfs = emitCurCodeOffs(addr);
#ifdef DEBUG
desc->vpdEndOfs = 0xFACEDEAD;
#endif
desc->vpdVarNum = offs;
desc->vpdNext = NULL;
Run Code Online (Sandbox Code Playgroud)
生命周期的结束以类似的方式设置,在emitter::emitGCvarDeadSet():
/* Record the death code offset */
assert(desc->vpdEndOfs == 0xFACEDEAD);
desc->vpdEndOfs = emitCurCodeOffs(addr);
Run Code Online (Sandbox Code Playgroud)
最后,这些表似乎是用jit/gcencode.cpp编写的,特别是用GCInfo::gcMakeVarPtrTable().
如果您想进一步探索,希望这将作为一个起点。
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |