super1 发表于 2022-2-22 17:58

用CoreCLR运行Unity-干货篇

前言

尽管Unity官方的人写了个文章:Porting the Unity Engine to .NET CoreCLR | xoofx
但是我和Sunnycase可是在2017年,没有Unity源码情况下完成了这点:CoreCLR 盲人摸象 - 知乎 (zhihu.com)
问题

在xoofx的文章中有写到
Typically, It was possible to store in Mono a userdata pointer in the MethodTable (the equivalent of the VTABLE + Type descriptor)
他并没有描述细节,但是当初实现这个项目最后一个卡点就在这里,让我们来看一下CoreCLR的Object和UnityMONO的Object的不同之处:


注意这个+是我改过的,当然直接这么改,会crash在GC里面,我也忘记是怎么发现这里有问题的了。应该是通过数据断点痛苦的调试出来的。让我们看下Mono的头文件


当然,我现在已经不确定是不是因为下面这个sync成员了,但是无论怎么样,因为Object不一样,所以去取成员所加的偏移不一样(这部分代码被inline然后编译到Unity-Player的二进制),必须要调整这里。
调整完之后,GC崩了,于是我看了以下文章:
CoreCLR源码探索(三) GC内存分配器的内部实现 - q303248153 - 博客园 (cnblogs.com)
经过一番痛苦的调试与代码阅读,终于找到了GC所需要的调整:


是的,你妹看错改一下Object基础定义需要改GC的一些奇怪的地方,这些东西并没有注释,这都是因为GC的代码依赖Object最小大小(从图上可以看出最小是sizeof(void*)*3)
只改这些就 了 ,事实上,你改完这些还会编译错误,有一些静态的static_assert需要修改,当然这都是小问题。然后经过SunnyCase指出,JIT的实现中unbox和box也假定了对象大小:使用sizeof(void*),于是


只改CPP代码够了吗?后面我们在调试中发生有个奇怪的内存偏移是JIT产生的代码(CORECLR支持JIT调试,输信息到文件)通过一番调试,我们发现这个偏移来源于 String的字符串内容 偏移



偏移是 offsetof(MonoString,char)

但是我们没在代码里面搜到offsetof和这个奇怪的12。后面想到了JIT应该是C#产生的,一搜索,果然发现了:


后记

为什么不继续搞了?
1.国庆假期结束
2.我已经不再少年
页: [1]
查看完整版本: 用CoreCLR运行Unity-干货篇