@@ -7530,6 +7530,14 @@ MethodTableBuilder::PlaceInterfaceMethods()
75307530 BOOL fParentInterface ;
75317531 DispatchMapTypeID * rgInterfaceDispatchMapTypeIDs = NULL ;
75327532
7533+ // Optimization for fast discovery of possible matches below
7534+ // Lazily initialized the first time we want to walk the list of methods
7535+ // The memory allocated for these pointers is on the StackingAllocator, which
7536+ // has the same lifetime as the MethodTableBuilder
7537+ uint32_t *pNameHashArray = NULL ;
7538+ bmtMDMethod **pMDMethodArray = NULL ;
7539+ DWORD interfaceImplCandidateArraySize = 0 ;
7540+
75337541 for (DWORD dwCurInterface = 0 ;
75347542 dwCurInterface < bmtInterface->dwInterfaceMapSize ;
75357543 dwCurInterface++)
@@ -7719,33 +7727,58 @@ MethodTableBuilder::PlaceInterfaceMethods()
77197727 // First, try to find the method explicitly declared in our class
77207728 //
77217729
7722- DeclaredMethodIterator methIt (*this );
7723- while (methIt.Next ())
7730+ if (pNameHashArray == NULL )
77247731 {
7725- // Note that non-publics can legally be exposed via an interface, but only
7726- // through methodImpls.
7727- if (IsMdVirtual (methIt.Attrs ()) && IsMdPublic (methIt.Attrs ()))
7732+ S_SIZE_T cbAllocPointers = S_SIZE_T (NumDeclaredMethods ()) * S_SIZE_T (sizeof (bmtMDMethod*));
7733+ S_SIZE_T cbAllocHashes = S_SIZE_T (NumDeclaredMethods ()) * S_SIZE_T (sizeof (uint32_t ));
7734+
7735+ pNameHashArray = (uint32_t *)GetStackingAllocator ()->Alloc (cbAllocHashes);
7736+ pMDMethodArray = (bmtMDMethod **)GetStackingAllocator ()->Alloc (cbAllocPointers);
7737+
7738+ DeclaredMethodIterator methIt (*this );
7739+ while (methIt.Next ())
77287740 {
7741+ // Note that non-publics and statics can legally be exposed via an interface, but only
7742+ // through methodImpls.
7743+ bmtMDMethod* mdMethod = methIt.GetMDMethod ();
7744+ DWORD attrs = mdMethod->GetDeclAttrs ();
7745+ if (IsMdVirtual (attrs) && IsMdPublic (attrs))
7746+ {
7747+ pNameHashArray[interfaceImplCandidateArraySize] = mdMethod->GetMethodSignature ().GetNameHash ();
7748+ pMDMethodArray[interfaceImplCandidateArraySize++] = mdMethod;
7749+ }
7750+ }
7751+ }
7752+
7753+ DeclaredMethodIterator methIt (*this );
7754+ UINT32 nameHashItfMethod = pCurItfMethod->GetMethodSignature ().GetNameHash ();
7755+
7756+ for (DWORD iPublicVirtualNonStaticMethod = 0 ; iPublicVirtualNonStaticMethod < interfaceImplCandidateArraySize; ++iPublicVirtualNonStaticMethod)
7757+ {
7758+ if (pNameHashArray[iPublicVirtualNonStaticMethod] != nameHashItfMethod)
7759+ continue ;
7760+
7761+ bmtMDMethod* declaredMethod = pMDMethodArray[iPublicVirtualNonStaticMethod];
7762+ const MethodSignature& declaredMethodSig = declaredMethod->GetMethodSignature ();
77297763#ifdef _DEBUG
7730- if (GetHalfBakedClass ()->m_fDebuggingClass && g_pConfig->ShouldBreakOnMethod (methIt. Name ()))
7731- CONSISTENCY_CHECK_MSGF (false , (" BreakOnMethodName: '%s' " , methIt. Name ()));
7764+ if (GetHalfBakedClass ()->m_fDebuggingClass && g_pConfig->ShouldBreakOnMethod (declaredMethodSig. GetName ()))
7765+ CONSISTENCY_CHECK_MSGF (false , (" BreakOnMethodName: '%s' " , declaredMethodSig. GetName ()));
77327766#endif // _DEBUG
77337767
7734- if (pCurItfMethod->GetMethodSignature ().Equivalent (methIt-> GetMethodSignature () ))
7735- {
7736- fFoundMatchInBuildingClass = TRUE ;
7737- curItfSlot.Impl () = methIt ->GetSlotIndex ();
7768+ if (pCurItfMethod->GetMethodSignature ().Equivalent (declaredMethodSig ))
7769+ {
7770+ fFoundMatchInBuildingClass = TRUE ;
7771+ curItfSlot.Impl () = declaredMethod ->GetSlotIndex ();
77387772
7739- DispatchMapTypeID dispatchMapTypeID =
7740- DispatchMapTypeID::InterfaceClassID (dwCurInterface);
7741- bmtVT->pDispatchMapBuilder ->InsertMDMapping (
7742- dispatchMapTypeID,
7743- static_cast <UINT32>(itfSlotIt.CurrentIndex ()),
7744- methIt ->GetMethodDesc (),
7745- FALSE );
7773+ DispatchMapTypeID dispatchMapTypeID =
7774+ DispatchMapTypeID::InterfaceClassID (dwCurInterface);
7775+ bmtVT->pDispatchMapBuilder ->InsertMDMapping (
7776+ dispatchMapTypeID,
7777+ static_cast <UINT32>(itfSlotIt.CurrentIndex ()),
7778+ declaredMethod ->GetMethodDesc (),
7779+ FALSE );
77467780
7747- break ;
7748- }
7781+ break ;
77497782 }
77507783 } // end ... try to find method
77517784
0 commit comments