12

I don't believe the generated code would check if the class has been initialized everytime it access a static member (which includes functions). I believe checking every access would be inefficient. I looked at §17.11 in ECMA 334 and it says

The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

It looks like how to figure out when 'first' happens is not defined. I can't think of any way to do it but to check every time. How might it be done?

  • 3
    Related, for the static case: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx - it is non-trivial – Marc Gravell Feb 17 '12 at 21:29
  • Isn't it the question of setting a function pointer to a different location after the first call? At first it points at the class loader or whatever, then at the body of the function... – user1096188 Feb 17 '12 at 21:31
  • 1
    @Marc: That discusses when calling the static constructor BEFORE the first access to a static member is allowed, not how the first access is detected. – Ben Voigt Feb 17 '12 at 21:33
  • @Ben - k; rephrased. Anyone interested in this area will still benefit from the article, though - so left link there – Marc Gravell Feb 17 '12 at 21:34
  • I think that "...is triggered by the first of the following..." is saying that if either of these events happen, then the static constructor is called. That text could be more concise - I think it is a little ambiguous. – RobertMS Feb 17 '12 at 21:34
  • @Marc: That was interesting to me. I had no idea the initalizer (in 4.0 with the link in that article http://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0.aspx) will do that. However, i still cant figure out if it checks a variable (or even calls a function ptr) on every static use/when new is used. (assuming it hasnt been called previously in the function) –  Feb 17 '12 at 21:44

2 Answers2

17

When you have a problem to solve, a good technique is: solve an even harder problem, such that the solution of your small problem is solved by the solution of the harder problem.

The CLR has a much harder problem to solve: it has to run the jitter exactly once on every method right before the method is called for the first time. If the CLR can solve that problem, then it can obviously solve the comparatively trivial sub-problem of detecting when a static ctor needs to run.

Perhaps your question should then be "how does the jitter know when to jit a method for the first time?"

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Interesting. I just assumed the JIT on non embedded systems just jits everything right away and stands by for loading new dlls. I assumed embed systems use ahead of time complication. Bad assumption especially when large code comes into play. +1 for the thoughts –  Feb 17 '12 at 21:48
  • 1
    @acidzombie24 actually, some embedded systems don't JIT/AOT **at all** - Micro Framework is an IL interpreter (crosses fingers that I haven't got this backwards...) – Marc Gravell Feb 17 '12 at 21:52
  • and some systems like .Net Compact Framework JIT only basic things e.g. get property is a function call – Lukasz Madon Feb 17 '12 at 23:18
  • You haven't answered the question. – nightcoder Apr 15 '14 at 18:02
5

When you are generating code at runtime, you have lots of options. You can call a NULL function pointer, catch the access violation, run the static constructor, compile the property getter, update the function pointer, and continue. Or have the property getter call a helper function that runs the static constructor and rewrites the getter code without the helper function call. Or insert a check on every static member access, that when hit recompiles the calling function with the check removed.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720