How pinning is presented in IL

I was wondering how field pinning is expressed in .Net IL, so I looked at an example code:

struct S { public fixed int buf[8]; } S s = default(S); public void MyMethod() { fixed (int* ptr = s.buf){ *ptr = 2; } } 

This generates IL:

 .method private hidebysig instance void MyMethod () cil managed { // Method begins at RVA 0x2050 // Code size 25 (0x19) .maxstack 2 .locals init ( [0] int32& pinned ) IL_0000: ldarg.0 // Load argument 0 onto the stack IL_0001: ldflda valuetype C/SC::s // Push the address of field of object obj on the stack IL_0006: ldflda valuetype C/S/'<buf>e__FixedBuffer' C/S::buf // Push the address of field of object obj on the stack IL_000b: ldflda int32 C/S/'<buf>e__FixedBuffer'::FixedElementField // Push the address of field of object obj on the stack IL_0010: stloc.0 // Pop a value from stack into local variable 0 IL_0011: ldloc.0 // Load local variable 0 onto stack IL_0012: conv.i // Convert to native int, pushing native int on stack IL_0013: ldc.i4.2 // Push 2 onto the stack as int32 IL_0014: stind.i4 // Store value of type int32 into memory at address IL_0015: ldc.i4.0 // Push 0 onto the stack as int32 IL_0016: conv.u // Convert to native unsigned int, pushing native int on stack IL_0017: stloc.0 // Pop a value from stack into local variable 0 IL_0018: ret // Return from method, possibly with a value } // end of method C::MyMethod 

I don’t see anything here, I will explicitly tell GC to bind an array, which instruction is actually responsible for committing? In addition, are there other basic operations that are associated with fixing “under the hood”?

+7
c # cil pinvoke
source share
1 answer
 .locals init ( [0] int32& pinned ) 

Using pinned is responsible for pinning. This article explains this as follows: How does the 'fixed' keyword work? This article provides the following excerpt from Standard ECMA-335 Common Language Infrastructure (CLI) :

II.7.1.2 fixed

The signature encoding for pinned should appear only in signatures describing local variables (§II.15.4.1.3). Although a method with a fixed local variable is executed, VES should not move the object to which the local belongs. That is, if the CLI implementation uses a garbage collector that moves objects, the collector should not move objects referenced by the active pinned local variable.

[Rationale: if unmanaged pointers are used to dereference managed objects, these objects must be pinned. This happens, for example, when a managed object is passed to a method designed to work with unmanaged data. final rationale]

VES = Virtual Execution System, CLI = Common Language Infrastructure

+10
source share

All Articles