Question

I'm working on a system which "bakes" a complete set of .NET assemblies to native code at development time. Ideally it would output machine language directly, but to spare myself the trouble of dealing with register colouring, different machine code for different target platforms, etc., I opted to make it output C code which is then compiled to ML using an existing compiler.

One problem this introduces is that overflow checking on integer math operations cannot be performed efficiently in C code. Certain CIL instructions - namely those with the .ovf suffix, explicitly check for overflow. Another question's numerous answers propose various techniques for such checking in C but they all perform very poorly compared to the machine code a JIT compiler might output (for instance, jo or into on Intel.)

Considering that the application is fairly performance critical, it would be highly tempting to just ignore the .ovf on these instructions and emit the same C code as for the non-checked variants. This would of course break my CLI implementation strictly speaking per ECMA-335, but I'm wondering whether it would really be broken in practice.

I am under the impression that these checks are mainly intended for program debugging. In the context in which my CLI is being used, the program is already debugged, and it is not controlling nuclear warheads (not real ones anyway.)

The system is to be used mainly on our own code, none of which depends on overflow checks for correctness. (According to this it would be bad form.) My concern is mainly for .NET class libraries we may link to and which my system will also of course have to process.

Out of all the code I foresee having to link to, my main concern is the BCL that comes with Mono. We're considering using that BCL since it's already ready-made and liberally licensed. However, when I do an IL dump of System.dll from Mono, I find it peppered with .ovf instructions (many of these are conv.ovf, which can be implemented in C as efficiently as in ML, but some are on arithmetic.)

Would Mono's BCL actually be depending upon any of these checks for correctness, or are they just sanity checks that can safely be ignored for code already deemed to be sane? (I expect the latter, but thought I'd ask in case others know better.)

Was it helpful?

Solution

I think that the main issue you will have in terms of converting it to C is that CIL is essentially a lower level language than C, and it is typically very difficult to "climb" the language levels. Your example shows this as checking for overflow is trivial in x86 but is actually quite difficult in C.

In terms of ignoring overflow checks in the Mono BCL, the most important question to ask is

If the checks weren't needed, why would they be used?

The Mono BCL is a fairly mature library so it would be sensible to expect that it is well written by people who know what they're doing; So if you modify the code by removing the overflow checks the code may appear to work just fine, but remember, overflow situation should be the exception rather than the rule.Also, whilst previously overflow would have immediately thrown an exception, it will now pass "bad data" on where it may or may not cause greater issues.

In short, removing overflow checks will probably mean that most of the time most of the code will work, but there will no longer be any guarantee that it will. This means that unless you very thoroughly check every possible code path or cover all code with test cases, you expose yourself to very great risk by avoiding these checks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top