Where is the implementation of InternalEquals(object objA, object objB)

后端 未结 2 1024
你的背包
你的背包 2020-12-06 13:50

While disassembling the .Net Source Code using Reflector, I came upon the Equals implementation in the Object Class and it refers to

bool InternalEquals(obj         


        
相关标签:
2条回答
  • 2020-12-06 14:44

    First, find in sscli20\clr\src\vm\ecall.cpp function mapping ("InternalEquals" -> ObjectNative::Equals):

    FCFuncStart(gObjectFuncs)
        FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
        FCFuncElement("InternalGetHashCode", ObjectNative::GetHashCode)
        FCFuncElement("InternalEquals", ObjectNative::Equals)
        FCFuncElement("MemberwiseClone", ObjectNative::Clone)
    FCFuncEnd()
    

    Next, find an implementation ObjectNative::Equals (published by Mehrdad Afshari)

    0 讨论(0)
  • 2020-12-06 14:46

    It's declared as [MethodImpl(MethodImplOptions.InternalCall)]. It means that it's implemented in the CLR itself, as a native procedure, not a .NET assembly.

    You can view a similar CLR source code by looking at Microsoft SSCLI (aka Rotor).

    In SSCLI 2.0 it's implemented as (in sscli20/clr/src/vm/comobject.cpp):

    FCIMPL2(FC_BOOL_RET, ObjectNative::Equals, Object *pThisRef, Object *pCompareRef)
    {
        CONTRACTL
        {
            THROWS;
            DISABLED(GC_NOTRIGGER);
            INJECT_FAULT(FCThrow(kOutOfMemoryException););
            MODE_COOPERATIVE;
            SO_TOLERANT;          
        }
        CONTRACTL_END;
    
        if (pThisRef == pCompareRef)    
            FC_RETURN_BOOL(TRUE);
    
        // Since we are in FCALL, we must handle NULL specially.
        if (pThisRef == NULL || pCompareRef == NULL)
             FC_RETURN_BOOL(FALSE);
    
        MethodTable *pThisMT = pThisRef->GetMethodTable();
    
        // If it's not a value class, don't compare by value
        if (!pThisMT->IsValueClass())
             FC_RETURN_BOOL(FALSE);
    
        // Make sure they are the same type.
        if (pThisMT != pCompareRef->GetMethodTable())
            FC_RETURN_BOOL(FALSE);
    
        // Compare the contents (size - vtable - sink block index).
        BOOL ret = memcmp(
            (void *) (pThisRef+1), 
            (void *) (pCompareRef+1), 
            pThisRef->GetMethodTable()->GetBaseSize() - sizeof(Object) - sizeof(int)) == 0;
    
        FC_GC_POLL_RET();
    
        FC_RETURN_BOOL(ret);
    }
    FCIMPLEND
    
    0 讨论(0)
提交回复
热议问题