Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where CLR allocates local memory pool?

ECMA-335, I.12.3.2.4 states the following:

Part of each method state is a local memory pool. Memory can be explicitly allocated from the local memory pool using the localloc instruction. All memory in the local memory pool is reclaimed on method exit, and that is the only way local memory pool memory is reclaimed (there is no instruction provided to free local memory that was allocated during this method invocation). The local memory pool is used to allocate objects whose type or size is not known at compile time and which the programmer does not wish to allocate in the managed heap. Because the local memory pool cannot be shrunk during the lifetime of the method, a language implementation cannot use the local memory pool for general-purpose memory allocation.

Where does CLR allocate this memory pool? Is it managed heap, thread stack, etc?

like image 553
user2341923 Avatar asked Oct 27 '13 15:10

user2341923


People also ask

How memory is allocated in C#?

Stack and Heap The Common Language Runtime (CLR) allocates memory for objects in these parts. Stack is a simple LIFO(last-in-first-out) structure. Variables allocated on the stack are stored directly to the memory and access to this memory is very fast, and its allocation is done when the program is compiled .

What is dynamic memory allocation C#?

Dynamic memory allocation is the process of assigning the memory space during the execution time or the run time. Reasons and Advantage of allocating memory dynamically: When we do not know how much amount of memory would be needed for the program beforehand.

Where are methods stored in C#?

Methods are stored somewhere else in the memory. Notice that methods are per-class, not per-instance. So typically, the number of methods doesn't change over the run-time of a program (there are exceptions). In traditional models, the place where the methods live is called the "code segment".


1 Answers

This is all intentionally vague because it is a strong implementation detail that the CLI spec doesn't want to nail down. It peeks through the cracks in the MSDN article for Opcodes.Localloc though:

StackOverflowException is thrown if there is insufficient memory to service the request.

There's only one way you ever get SOE: it requires allocating from the stack.

The C# language is less shy about where it gets allocated, it uses the stackalloc keyword. A sample program:

class Program {
    static unsafe void Main(string[] args) {
        int* p = stackalloc int[42];
    }
}

Produces this IL:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       9 (0x9)
  .maxstack  8
  IL_0000:  ldc.i4.s   42
  IL_0002:  conv.u
  IL_0003:  ldc.i4.4
  IL_0004:  mul.ovf.un
  IL_0005:  localloc                   // <=== Here
  IL_0007:  pop
  IL_0008:  ret
} // end of method Program::Main

Which produces this machine code at runtime:

02E42620  push        ebp  
02E42621  mov         ebp,esp  
02E42623  sub         esp,8  
02E42626  mov         dword ptr [ebp-4],esp  
02E42629  mov         dword ptr [ebp-8],6A029823h  
02E42630  mov         eax,esp  
02E42632  test        dword ptr [esp],esp  
02E42635  sub         eax,0A8h                       // <=== Here
02E4263A  mov         esp,eax  
02E4263C  mov         dword ptr [ebp-4],esp  
02E4263F  cmp         dword ptr [ebp-8],6A029823h  
02E42646  je          02E4264D  
02E42648  call        730CA5C0  
02E4264D  lea         esp,[ebp]  
02E42650  pop         ebp  
02E42651  ret  

The sub eax,0A8h instruction subtracts 0xa8 = 168 = 42x4 bytes from the ESP register (the stack pointer), the mov esp,eax instruction adjusts the stack pointer. So yes, this definitely comes from the stack.

like image 58
Hans Passant Avatar answered Oct 19 '22 22:10

Hans Passant