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.