MonoTouch AOT编译器 - 大型方法失败

7

我正在开发一款游戏,我们一直在以JSON格式存储我们的关卡信息。由于这些关卡信息相当庞大,因此我们转而将它们存储为纯C#代码:

  • 顶层方法有一个switch语句用于关卡/对象的名称
  • 有几个自动生成的方法使用标准属性初始化程序“new up”我们的对象树

例如:

private OurObject Autogenerated_Object1()
{
   return new OurObject { Name = "Object1", X = 1, Y = 2, Width = 200, Height = 100 };
}

除非这些方法非常大且嵌套有其他对象的列表/字典等。

这将把加载级别的时间从2-3秒加速到几分之一秒(在Windows上)。 我们的数据大小也相对较小,因为与JSON相比,编译的IL更小。

问题是当我们在MonoDevelop中为MonoTouch编译它们时,我们会得到:

mtouch以代码1退出

打开-v -v -v,我们可以看到错误:

MONO_PATH=/Users/jonathanpeppers/Desktop/DrawAStickman/Game/Code/iOS/DrawAStickman.iPhone/bin/iPhone/Release/DrawAStickmaniPhone.app /Developer/MonoTouch/usr/bin/arm-darwin-mono --aot=mtriple=armv7-darwin,full,static,asmonly,nodebug,outfile=/var/folders/4s/lcvdj54x0g72nrsw9vzq6nm80000gn/T/tmp54777849.tmp/monotouch.dll.7.s "/Users/jonathanpeppers/Desktop/DrawAStickman/Game/Code/iOS/DrawAStickman.iPhone/bin/iPhone/Release/DrawAStickmaniPhone.app/monotouch.dll"
AOT Compilation exited with code 134, command:
MONO_PATH=/Users/jonathanpeppers/Desktop/DrawAStickman/Game/Code/iOS/DrawAStickman.iPhone/bin/iPhone/Release/DrawAStickmaniPhone.app /Developer/MonoTouch/usr/bin/arm-darwin-mono --aot=mtriple=armv7-darwin,full,static,asmonly,nodebug,outfile=/var/folders/4s/lcvdj54x0g72nrsw9vzq6nm80000gn/T/tmp54777849.tmp/DrawAStickmanCore.dll.7.s "/Users/jonathanpeppers/Desktop/DrawAStickman/Game/Code/iOS/DrawAStickman.iPhone/bin/iPhone/Release/DrawAStickmaniPhone.app/DrawAStickmanCore.dll"
Mono Ahead of Time compiler - compiling assembly /Users/jonathanpeppers/Desktop/DrawAStickman/Game/Code/iOS/DrawAStickman.iPhone/bin/iPhone/Release/DrawAStickmaniPhone.app/DrawAStickmanCore.dll
* Assertion: should not be reached at ../../../../../mono/mono/mini/mini-arm.c:2758

在进行AOT编译时,方法中的行数是否有限制?我们是否可以传递某些参数给mtouch来解决这个问题?一些文件可以正常工作,但是一个特定的文件包含了3000行的方法,导致出现错误。无论如何,在模拟器上编译都可以正常工作。

由于这仍然是一个实验阶段,所以我们意识到这是一个相当疯狂的情况。


它能够处理小规模的级别吗? - Chuck Savage
是的,在较小的地图级别下可以正常工作。但是一旦添加了特定的灌木或树木,问题就开始了 - 但模拟器仍然可以正常工作。 - jonathanpeppers
2个回答

4
这些断言会在AOT编译器中出现,当你遇到一个本不应该发生的条件时,请向http://bugzilla.xamarin.com报告此类情况。

我们可以通过向mtouch传递一些参数来解决吗?

你可以尝试使用LLVM(或不使用它),因为它是不同的代码生成引擎,这样可能会解决问题。根据发生的阶段(有些是共享的),您可能不会遇到相同的情况。当然,LLVM构建速度较慢,不支持调试,所以这并非所有情况下都是理想的解决方案。

我会制作一个样例项目并报告这个错误。我使用LLVM编译时出现了类似的错误:* Assertion at ../../../../../mono/mono/mini/ssa.c:243, condition stack_history_len < stack_history_size' not met`。 - jonathanpeppers
Zoltan说已经修复了,不确定需要多长时间才能在alpha/beta频道中尝试。 - jonathanpeppers
它不会出现在5.2.12中,因为该发布过程已经在进行中。下一个版本应该是5.3.4(alpha),应该包含它。 - poupou

1

关于存储级别的建议,我想推荐一种非常快速的二进制格式——Protocol Buffers。你是否考虑过使用它来存储级别?.NET有一个很棒的Protocol Buffers库,叫做Protobuf-net,你可以去看看。


我已经看过了,问题是我的列表/字典嵌套,还有带有多个列表(不规则数组)的类,但它不支持这种情况。 - jonathanpeppers
你可能可以将内部的数组/列表包装为类并进行序列化。但是你可能已经探索过这个选项了。 - tamaslnagy
MsgPack是另一个选择。我正在使用它来在网络上进行序列化,并且在某些时候可能会用它来替换Json,以实现更快的磁盘序列化。 - Jared Thirsk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接