How is the CLR managed when calling a static method?

I have a static class with static methods as shown below:

public static StaticTest
{
   public static void DoSomeWork()
   {
    /// Do Some work
   }
}

      

When a function is called DoSomeWork()

, how does the CLR manage the function references, since it is obvious that a static class cannot be instantiated?

What is the mechanism behind the scenes for calling the function in this case?

+3


source to share


4 answers


When the CLR loads an assembly that contains static members, those members are placed in an allocated space in memory called High Frequency Heap. Objects on the high-frequency heap are never garbage collected to ensure that static variables are available throughout the life of the application.



+5


source


Let's say you have:

class Foo
{
    public void Bar()
    {
        // instance
    }

    public static void Fiz()
    {
        // instance
    }
}

      

And you do:

var temp = new Foo();
Foo.Fiz();
temp.Bar();

      

Your code is translated to something like:



var temp = new Foo();
Foo.Fiz();
Foo.Bar(temp);

      

This translates to hidden class parameter (first). In C ++ for Intel, this is called the thiscall convention. For static functions this parameter is simply not available.

If you open the Disassembly function in this code, you will see that it is something like:

            var temp = new Foo();
00007FFBD48042EC  lea         rcx,[7FFBD48563D8h]  
00007FFBD48042F3  call        00007FFC33E42400  
00007FFBD48042F8  mov         qword ptr [rsp+2B0h],rax  
00007FFBD4804300  mov         rax,qword ptr [rsp+2B0h]  
00007FFBD4804308  mov         qword ptr [rsp+2B8h],rax  
00007FFBD4804310  mov         rcx,qword ptr [rsp+2B8h]  
00007FFBD4804318  call        00007FFBD46ECA48  
00007FFBD480431D  mov         r11,qword ptr [rsp+2B8h]  
00007FFBD4804325  mov         qword ptr [rsp+30h],r11  
            Foo.Fiz();
00007FFBD480432A  call        00007FFBD46ECA40  
            temp.Bar();
00007FFBD480432F  mov         r11,qword ptr [rsp+30h]  
00007FFBD4804334  cmp         byte ptr [r11],0  
00007FFBD4804338  mov         rcx,qword ptr [rsp+30h]  
00007FFBD480433D  call        00007FFBD46ECA38  

      

As you can see, Foo.Fiz

is straight forward call 00007FFBD46ECA40

, and temp.bar()

first does a check for null

(I think mov

+ cmp

), then puts the rcx

link and doescall

+4


source


The function body exists in the assembly as a set of IL instructions. When you call this function, the IL result is something like:

call     void[assembly]StaticTest:DoSomeWork()

      

therefore the runtime looks at the "build" for the IL DoSomeWork body, JIT, and executes it. From another point of view, a static function is a normal function, but without the "this" reference to work with.

+1


source


When a method runs, the CLR identifies the types used in that method and loads the said assemblies.

It then creates an "Object Type" for each reference type in the method (if they don't exist).

Each type object contains an object type pointer, a sync lock index, static fields, and a method table (which contains one entry for each method of the type).

public void DoSomething()
{
 InstanceClass objectInstance =  new InstanceClass();
 objectInstance.MethodName();
 StaticClass.MethodName();
 // i.e.here clr creates Type Objects for Instance class and StaticClass in the heap
}

      

enter image description here

When a statement is new

used to create an object of a class, the CLR automatically creates a pointer of type Object in an instance of that class and initializes it to refer to the corresponding object of the type.

When the INSTANCE method is called (not virtual), i.e. objectInstance.MethodName()

The CLR identifies the Type object based on the type of the variable used and finds that method in the method table of the type object, followed by the JIT method.

When a static method is called, i.e. StaticTest.DoSomeWork()

The CLR (JIT Compiler) identifies the "type object" of the static class based on the class name, and the JIT compiler looks for the method in the method table of the corresponding Object type, and then the JIT method.

0


source







All Articles