I have a call site cache comprised of an array of this CachePage
class. The cache page has a readonly
array of tokens that are used to determine if this page is the correct one to use.
internal class CachePage
{
internal CachePage(Token[] tokens)
{
this.tokens = tokens;
}
private readonly Token[] tokens;
// other members don't matter...
To simplify matters, On the class I have several CheckTokens
method that take various number of parameters they WLOG all look like this.
public bool CheckTokens(Token g0, Token g1, Token g2)
{
return (g2 == tokens[2] && g1 == tokens[1] && g0 == tokens[0]);
}
I iterate backward through the elements of the array to incur only one bound check. Or so I thought. When I look at the output of the disassembly, I actually see for each comparison it actually is performing a boundcheck.
However, if I change the method like so,the extra boundchecks are eliminated.
public bool CheckTokens(Token g0, Token g1, Token g2)
{
var t=tokens;
return (g2 == t[2] && g1 == t[1] && g0 == t[0]);
}
Why are the extra bound checks added? Doesn't the readonly flag tell the JIT that this private variable cannot be mutated?
This is a low-level cache so the less time spent determining if this is the right path the better.
EDIT: This is for 64bit .net 4.5 tried with both ryuJIT and normal JIT.