我正在开发一个系统,该系统在开发时将一整套 .NET 程序集“烘焙”为本机代码。理想情况下,它会直接输出机器语言,但为了省去处理寄存器着色、针对不同目标平台的不同机器代码等的麻烦,我选择让它输出 C 代码,然后使用现有的编译器将其编译为 ML。
这引入的一个问题是整数数学运算的溢出检查不能在 C 代码中有效地执行。某些 CIL 指令——即带有.ovf
后缀的指令,明确地检查溢出。 另一个问题的众多答案提出了在 C 中进行此类检查的各种技术,但与 JIT 编译器可能输出的机器代码(例如,jo
或into
在英特尔上)相比,它们的性能都非常差。
考虑到应用程序对性能非常关键,很容易忽略.ovf
这些指令并发出与未检查变体相同的 C 代码。根据 ECMA-335 严格来说,这当然会破坏我的 CLI 实现,但我想知道它是否真的会在实践中被破坏。
我的印象是这些检查主要用于程序调试。在使用我的 CLI 的上下文中,该程序已经调试过了,并且它没有控制核弹头(反正不是真正的核弹头。)
该系统主要用于我们自己的代码,这些代码都不依赖于溢出检查的正确性。(据此,这将是一种糟糕的形式。)我关心的主要是我们可能链接到的 .NET 类库,我的系统当然也必须处理这些类库。
在我预见到必须链接的所有代码中,我主要关心的是 Mono 附带的 BCL。我们正在考虑使用该 BCL,因为它已经是现成的并且获得了自由许可。但是,当我从 Mono 对 System.dll 进行 IL 转储时,我发现它充满了.ovf
指令(其中许多是conv.ovf
,可以在 C 中像在 ML 中一样高效地实现,但有些是在算术上。)
Mono 的 BCL 实际上是否会依赖于任何这些检查的正确性,或者它们只是对于已经被认为是健全的代码可以安全地忽略的健全性检查?(我期待后者,但我想我会问,以防其他人知道得更好。)