固定在 IL 中是如何表示的
How is pinning represented in IL
我想知道 .Net 的 IL 语言如何表达字段固定,
所以我看了一下示例代码:
struct S
{
public fixed int buf[8];
}
S s = default(S);
public void MyMethod() {
fixed (int* ptr = s.buf){
*ptr = 2;
}
}
这会生成 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/S C::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
我在这里没有看到任何明确告诉 GC 固定数组的内容,哪条指令实际上负责固定?
另外,是否还有其他涉及固定的基本操作"under the hood"?
.locals init (
[0] int32& pinned
)
pinned
的使用负责固定。本文对此进行了解释:How does the 'fixed' keyword work? The article points to the following excerpt from Standard ECMA-335 Common Language Infrastructure (CLI):
II.7.1.2 pinned
The signature encoding for pinned shall appear only in
signatures that describe local variables (§II.15.4.1.3). While a
method with a pinned local variable is executing, the VES shall not
relocate the object to which the local refers. That is, if the
implementation of the CLI uses a garbage collector that moves objects,
the collector shall not move objects that are referenced by an active
pinned local variable.
[Rationale: If unmanaged pointers are used to dereference managed
objects, these objects shall be pinned. This happens, for example,
when a managed object is passed to a method designed to operate with
unmanaged data. end rationale]
VES = 虚拟执行系统,CLI = 公共语言基础设施
我想知道 .Net 的 IL 语言如何表达字段固定, 所以我看了一下示例代码:
struct S
{
public fixed int buf[8];
}
S s = default(S);
public void MyMethod() {
fixed (int* ptr = s.buf){
*ptr = 2;
}
}
这会生成 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/S C::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
我在这里没有看到任何明确告诉 GC 固定数组的内容,哪条指令实际上负责固定? 另外,是否还有其他涉及固定的基本操作"under the hood"?
.locals init (
[0] int32& pinned
)
pinned
的使用负责固定。本文对此进行了解释:How does the 'fixed' keyword work? The article points to the following excerpt from Standard ECMA-335 Common Language Infrastructure (CLI):
II.7.1.2 pinned
The signature encoding for pinned shall appear only in signatures that describe local variables (§II.15.4.1.3). While a method with a pinned local variable is executing, the VES shall not relocate the object to which the local refers. That is, if the implementation of the CLI uses a garbage collector that moves objects, the collector shall not move objects that are referenced by an active pinned local variable.
[Rationale: If unmanaged pointers are used to dereference managed objects, these objects shall be pinned. This happens, for example, when a managed object is passed to a method designed to operate with unmanaged data. end rationale]
VES = 虚拟执行系统,CLI = 公共语言基础设施