Ejemplo n.º 1
0
 internal DispatchCellInfo ConvertDispatchCellInfo(IntPtr module, DispatchCellInfo cellInfo)
 {
     using (LockHolder.Hold(_typeLoaderLock))
     {
         return ConvertDispatchCellInfo_Inner(
             module,
             cellInfo);
     }
 }
Ejemplo n.º 2
0
 internal DispatchCellInfo ConvertDispatchCellInfo(NativeFormatModuleInfo module, DispatchCellInfo cellInfo)
 {
     using (LockHolder.Hold(_typeLoaderLock))
     {
         return ConvertDispatchCellInfo_Inner(
             module,
             cellInfo);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Attempt to convert the dispatch cell to a metadata token to a more efficient vtable dispatch or interface/slot dispatch.
        /// Failure to convert is not a correctness issue. We also support performing a dispatch based on metadata token alone.
        /// </summary>
        private static DispatchCellInfo ConvertDispatchCellInfo_Inner(NativeFormatModuleInfo module, DispatchCellInfo cellInfo)
        {
            Debug.Assert(cellInfo.CellType == DispatchCellType.MetadataToken);

            TypeSystemContext context = TypeSystemContextFactory.Create();

            MethodDesc targetMethod = context.ResolveMetadataUnit(module).GetMethod(cellInfo.MetadataToken.AsHandle(), null);

            Debug.Assert(!targetMethod.HasInstantiation); // At this time we do not support generic virtuals through the dispatch mechanism
            Debug.Assert(targetMethod.IsVirtual);
            if (targetMethod.OwningType.IsInterface)
            {
                if (!LazyVTableResolver.TryGetInterfaceSlotNumberFromMethod(targetMethod, out cellInfo.InterfaceSlot))
                {
                    // Unable to resolve interface method. Fail, by not mutating cellInfo
                    return(cellInfo);
                }

                if (!targetMethod.OwningType.RetrieveRuntimeTypeHandleIfPossible())
                {
                    new TypeBuilder().BuildType(targetMethod.OwningType);
                }

                cellInfo.CellType      = DispatchCellType.InterfaceAndSlot;
                cellInfo.InterfaceType = targetMethod.OwningType.RuntimeTypeHandle.ToIntPtr();
                cellInfo.MetadataToken = 0;
            }
            else
            {
                // Virtual function case, attempt to resolve to a VTable slot offset.
                // If the offset is less than 4096 update the cellInfo
#if DEBUG
                // The path of resolving a metadata token at dispatch time is relatively rare in practice.
                // Force it to occur in debug builds with much more regularity
                if ((s_ConvertDispatchCellInfoCounter % 16) == 0)
                {
                    s_ConvertDispatchCellInfoCounter++;
                    TypeSystemContextFactory.Recycle(context);
                    return(cellInfo);
                }
                s_ConvertDispatchCellInfoCounter++;
#endif

                int slotIndexOfMethod = LazyVTableResolver.VirtualMethodToSlotIndex(targetMethod);
                int vtableOffset      = -1;
                if (slotIndexOfMethod >= 0)
                {
                    vtableOffset = LazyVTableResolver.SlotIndexToEETypeVTableOffset(slotIndexOfMethod);
                }
                if ((vtableOffset < 4096) && (vtableOffset != -1))
                {
                    cellInfo.CellType      = DispatchCellType.VTableOffset;
                    cellInfo.VTableOffset  = checked ((uint)vtableOffset);
                    cellInfo.MetadataToken = 0;
                }
                // Otherwise, do nothing, and resolve with a metadata dispatch later
            }

            TypeSystemContextFactory.Recycle(context);
            return(cellInfo);
        }
Ejemplo n.º 4
0
 internal DispatchCellInfo ConvertDispatchCellInfo(IntPtr module, DispatchCellInfo cellInfo)
 {
     using (LockHolder.Hold(_typeLoaderLock))
     {
         return ConvertDispatchCellInfo_Inner(
             module,
             cellInfo);
     }
 }