@@ -7530,6 +7530,14 @@ MethodTableBuilder::PlaceInterfaceMethods()
7530
7530
BOOL fParentInterface ;
7531
7531
DispatchMapTypeID * rgInterfaceDispatchMapTypeIDs = NULL ;
7532
7532
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
+
7533
7541
for (DWORD dwCurInterface = 0 ;
7534
7542
dwCurInterface < bmtInterface->dwInterfaceMapSize ;
7535
7543
dwCurInterface++)
@@ -7719,33 +7727,58 @@ MethodTableBuilder::PlaceInterfaceMethods()
7719
7727
// First, try to find the method explicitly declared in our class
7720
7728
//
7721
7729
7722
- DeclaredMethodIterator methIt (*this );
7723
- while (methIt.Next ())
7730
+ if (pNameHashArray == NULL )
7724
7731
{
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 ())
7728
7740
{
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 ();
7729
7763
#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 ()));
7732
7766
#endif // _DEBUG
7733
7767
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 ();
7738
7772
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 );
7746
7780
7747
- break ;
7748
- }
7781
+ break ;
7749
7782
}
7750
7783
} // end ... try to find method
7751
7784
0 commit comments