Repository: dotnet/runtime
File: src/coreclr/vm/dllimport.cpp (C++)

Code before:
    {
        STANDARD_VM_CONTRACT;

        DWORD dwStubFlags = pParams->m_dwStubFlags;

        // The target MethodDesc may be NULL for field marshalling.
        // Forward P/Invoke stubs (non-CALLI, non-vararg) each target a specific method,
        // so the hash blob is just the target MethodDesc pointer. This ensures racing
        // threads for the same P/Invoke converge on the same DynamicMethodDesc in the
        // ILStubCache, while different P/Invoke methods get distinct cache entries.
        if (pTargetMD != NULL
            && SF_IsForwardPInvokeStub(dwStubFlags)
            && !SF_IsCALLIStub(dwStubFlags)
            && !SF_IsVarArgStub(dwStubFlags))
        {
            size_t blobSize = sizeof(ILStubHashBlobBase) + sizeof(MethodDesc*);
            NewArrayHolder<BYTE> pBytes = new BYTE[blobSize];
            ZeroMemory(pBytes, blobSize);
            ILStubHashBlob* pBlob = (ILStubHashBlob*)(BYTE*)pBytes;
            pBlob->m_cbSizeOfBlob = blobSize;
            memcpy(pBlob->m_rgbBlobData, &pTargetMD, sizeof(pTargetMD));
            pBytes.SuppressRelease();
            return pBlob;
        }

        PInvokeStubHashBlob*    pBlob;

        IMDInternalImport* pInternalImport = pParams->m_pModule->GetMDImport();

        CQuickBytes paramInfoBytes;
        paramInfoBytes.AllocThrows(sizeof(ParamInfo)*pParams->m_nParamTokens);
        ParamInfo *paramInfos = (ParamInfo *)paramInfoBytes.Ptr();
        ::ZeroMemory(paramInfos, sizeof(ParamInfo) * pParams->m_nParamTokens);

        size_t cbNativeTypeTotal = 0;

        //
        // Collect information for function parameters
        //
        for (int idx = 0; idx < pParams->m_nParamTokens; idx++)
        {
            mdParamDef token = pParams->m_pParamTokenArray[idx];
            if (TypeFromToken(token) == mdtParamDef && mdParamDefNil != token)
            {
                USHORT usSequence_Ignore;       // We don't need usSequence in the hash as the param array is already sorted
                LPCSTR szParamName_Ignore;
                IfFailThrow(pInternalImport->GetParamDefProps(token, &usSequence_Ignore, &paramInfos[idx].dwParamAttr, &szParamName_Ignore));

                if (paramInfos[idx].dwParamAttr & pdHasFieldMarshal)
                {
                    IfFailThrow(pInternalImport->GetFieldMarshal(token, &paramInfos[idx].pvNativeType, &paramInfos[idx].cbNativeType));

Review comment (suggestion):
nit: we could be consistent with the `sizeof` arguments
```suggestion
            memcpy(pBlob->m_rgbBlobData, &pTargetMD, sizeof(MethodDesc*));
```

Code after:
    {
        STANDARD_VM_CONTRACT;

        // The hash blob for a forward P/Invoke stub is just the target MethodDesc pointer.
        // In order to help avoid collisions, ensure various blob sizes are different.
        // See asserts below.
        constexpr size_t forwardPInvokeHashBlobSize = sizeof(ILStubHashBlobBase) + sizeof(MethodDesc*);

        DWORD dwStubFlags = pParams->m_dwStubFlags;

        // The target MethodDesc may be NULL for field marshalling.
        // Forward P/Invoke stubs (non-CALLI, non-vararg) each target a specific method,
        // so the hash blob is just the target MethodDesc pointer. This ensures racing
        // threads for the same P/Invoke converge on the same DynamicMethodDesc in the
        // ILStubCache, while different P/Invoke methods get distinct cache entries.
        if (pTargetMD != NULL
            && SF_IsForwardPInvokeStub(dwStubFlags)
            && !SF_IsCALLIStub(dwStubFlags)
            && !SF_IsVarArgStub(dwStubFlags))
        {
            const size_t blobSize = forwardPInvokeHashBlobSize;
            NewArrayHolder<BYTE> pBytes = new BYTE[blobSize];
            ZeroMemory(pBytes, blobSize);
            ILStubHashBlob* pBlob = (ILStubHashBlob*)(BYTE*)pBytes;
            pBlob->m_cbSizeOfBlob = blobSize;
            memcpy(pBlob->m_rgbBlobData, &pTargetMD, sizeof(pTargetMD));
            pBytes.SuppressRelease();
            return pBlob;
        }

        PInvokeStubHashBlob*    pBlob;

        IMDInternalImport* pInternalImport = pParams->m_pModule->GetMDImport();

        CQuickBytes paramInfoBytes;
        paramInfoBytes.AllocThrows(sizeof(ParamInfo)*pParams->m_nParamTokens);
        ParamInfo *paramInfos = (ParamInfo *)paramInfoBytes.Ptr();
        ::ZeroMemory(paramInfos, sizeof(ParamInfo) * pParams->m_nParamTokens);

        size_t cbNativeTypeTotal = 0;

        //
        // Collect information for function parameters
        //
        for (int idx = 0; idx < pParams->m_nParamTokens; idx++)
        {
            mdParamDef token = pParams->m_pParamTokenArray[idx];
            if (TypeFromToken(token) == mdtParamDef && mdParamDefNil != token)
            {
                USHORT usSequence_Ignore;       // We don't need usSequence in the hash as the param array is already sorted
                LPCSTR szParamName_Ignore;