我在 ILDASM 和 Reflector 中进行了深入研究,发现:
- == 被编译为“ceq”MSIL 命令
- object.Equals 保持原样
- object.Equals 调用
对象.InternalEquals
This https://stackoverflow.com/questions/384294/where-is-the-implementation-of-internalequalsobject-obja-object-objb问题向我展示了如何找出如何实现InternalEquals,即在.cpp类(或CLR中的某个地方)中。
我的问题是:
ceq 变成了什么?不同 .cpp 类中的另一种方法? IE。它们是完全不同的代码?那么,虽然 == 和 Equals 的默认行为看起来是相同的,但它是不同的代码?
== 运算符并不总是被翻译为 ceq。类型可以使用运算符 ==() 重载它。例如,System.Decimal 就是这样做的,它会重载所有运算符,因为它们的实现很重要,并且抖动没有类型的特殊知识(编译器有)。
您将通过 Reflector 作为 Decimal.op_Equality() 方法找到它。这会将您引向 FCallCompare,这是一个归属于 MethodImplOptions.InternalCall 的方法。这些方法很特殊,抖动对它们有秘密了解。您可以通过Rotor中的clr/src/vm/ecall.cpp源代码文件找到它们的实现。它包含所有内部调用函数的表,抖动通过方法名称查找表项。然后将表中对应的C++函数的地址编译成call指令。请注意,自 Rotor 发布以来函数名称已更改,搜索 FCallAdd,它是表中的下一个条目。这将带您进入 COMDecimal::Compare。这将带您进入 comdecimal.cpp 源代码文件。
x86 和 x64 jitter 知道如何直接将 ceq 操作码转换为机器代码,而不需要辅助函数,它会内联生成本机机器指令。实际生成的代码取决于所比较的值的类型。而目标,x64抖动使用SSE指令,x86使用FPU指令来比较浮点值。当然,其他的不安也会以不同的方式实现它们。
像 Object.InternalEquals() 这样的辅助函数也是一个内部方法,就像 FCallCompare 一样。您可以使用相同的策略来找到实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)