欢迎光临散文网 会员登陆 & 注册

huatuo之AOT泛型限制及原理介绍

2022-12-22 18:50 作者:unity小能手  | 我要投稿

CLR 泛型



CLR中有两类泛型特性:泛型类型和泛型函数。泛型是c#中使用极其广泛的特性。即使一个没有明显包含泛型的用法,可能隐含了泛型相关的定义或者操作。

例如

  • int[]隐含就实现 IEnemrable之类的接口。

  • 为async生成状态机代码时,也会隐含生成一些对 System.Runtime.CompilerServices.AsyncTaskMethodBuilder::AwaitUnsafeOnCompleted 之类的泛型代码的调用。

AOT泛型的问题

泛型类型本身只是元数据,内存可以动态创造出任意泛型类型的实例化,无论是AOT泛型还是解释器泛型。但泛型函数(包括泛型类的普通成员函数)则情况有点不同。

解释器泛型函数没有任何限制,但AOT泛型函数则遇到一个严重的问题:由于泛型函数的原始函数体元数据在il2cpp翻译后已经丢失,理论不可能根据已有的c++泛型函数指针为一个新的泛型类型产生对应泛型实例化函数。

对于一些特殊的AOT泛型,huatuo作了特殊处理,没有限制:

  • 泛型数组,包括多维数组

  • 泛型delegate

  • 泛型Nullable类型

但显然不可能对每个AOT泛型类特殊处理。因此,如果你在热更新脚本里定义了个值类型:

il2cpp的泛型共享机制

il2cpp为了避免泛型代码膨胀,节约内存,在保证代码逻辑正确性的情况下对于一些能够共享代码,只生成一份代码。为此引入一个概念叫泛型代码共享 Generic Sharing,此技术更早则源于mono。CLR中也有同样的概念,CLR认为所有引用类型实参都一样,所以可以代码共享,例如,为 List<string> 方法编译的代码可以直接用于List<Stream>方法,这是因为所有引用类型实参/变量只是指向托管堆的一个8字节指针(这里假设64位系统),但是对于值类型,则必须每种类型都进行代码生成,因为值类型大小不定。

以List<T> 举例:

  • 可以使用AOT中使用过的任何List的实例化类型。例如你在AOT里用过List<vector3>,则热更新里也可以用

  • 可以使用任意 List<EnumType>。 只需要你在AOT里实例化某一个List<相同underlying type的EnumType>。

  • 可以使用任意引用类型的泛型参数 List<ClassType>。 只需要你在AOT里实例化过 List<object>(或任意一个引用泛型参数如 List<string>)

注意!!!il2cpp泛型共享机制 不支持 List<热更新值类型>。因为值类型无法泛型共享,而热更新值类型不可能提前在AOT里泛型实例化。这个限制由下一节 基于补充元数据的泛型函数实例化技术 彻底解决。不过即使没有这个限制,对于AOT值类型,能提前泛型实例化,可以大幅提升性能(毕竟不用解释执行了)。后续会有工具帮助自动收集热更新模块中的泛型实例,尽量让它提前AOT实例化。

il2cpp中值类型不支持泛型共享的原因

主要有两个原因:

  1. 值类型大小不定,且值类型对齐方式不一样,不同对齐会导致所在的类的布局不同。

举例

基于补充元数据的泛型函数实例化技术(huatuo的专利技术)

既然AOT泛型函数无法实例化的问题本质上是il2cpp翻译造成的元数据缺失的问题,那解决思路也很简单,补充上原始元数据那就能正常实例化了。使用 HuatuoApi.LoadMetadataForAOTAssembly 函数为AOT的assembly补充对应的元数据。

注意,当前要求补充的dll与打包时裁剪后的dll精确一致,因此必须使用build过程中生成的裁剪后的dll,则不能直接复制原始dll,这个限制将来可能会去掉。这些dll可以在目录 {project}/Temp/StagingArea/Il2Cpp/Managed 下找到。另外,对于一些平台如Win Standalone的包,在 {build}/{project}/Managed 目录下也能找到。

你只要在使用AOT泛型前调用即可(只需要调用一次)。如果未注册相应的泛型元数据,则退回到il2cpp的泛型共享机制。

基于补充元数据的泛型函数实例化技术虽然相当完美,但毕竟实例化的函数以解释方式执行,如果能提前在AOT中泛型实例化,可以大幅提升性能。 所以推荐对于常用尤其是性能敏感的泛型类和函数,提前在AOT中实例化。后续我们也会提供工具帮助自动扫描收集相应的泛型实例。

以下代码来自 huatuo_trial 。


huatuo之AOT泛型限制及原理介绍的评论 (共 条)

分享到微博请遵守国家法律