Esempio n. 1
0
        private RemoveAction GetAction(MethodDesc method)
        {
            TypeDesc owningType = method.OwningType;

            if ((_removedFeature & RemovedFeature.Etw) != 0)
            {
                if (!method.Signature.IsStatic)
                {
                    if (IsEventSourceType(owningType))
                    {
                        if (method.IsConstructor)
                        {
                            return(RemoveAction.ConvertToStub);
                        }

                        if (method.Name == "IsEnabled" || method.IsFinalizer || method.Name == "Dispose")
                        {
                            return(RemoveAction.ConvertToStub);
                        }

                        return(RemoveAction.ConvertToThrow);
                    }
                    else if (IsEventSourceImplementation(owningType))
                    {
                        if (method.IsFinalizer)
                        {
                            return(RemoveAction.ConvertToStub);
                        }

                        if (method.IsConstructor)
                        {
                            return(RemoveAction.ConvertToStub);
                        }

                        if (method.HasCustomAttribute("System.Diagnostics.Tracing", "NonEventAttribute"))
                        {
                            return(RemoveAction.Nothing);
                        }

                        return(RemoveAction.ConvertToThrow);
                    }
                }
            }

            if ((_removedFeature & RemovedFeature.FrameworkResources) != 0)
            {
                if (method.Signature.IsStatic &&
                    owningType is Internal.TypeSystem.Ecma.EcmaType mdType &&
                    mdType.Name == "SR" && mdType.Namespace == "System" &&
                    FrameworkStringResourceBlockingPolicy.IsFrameworkAssembly(mdType.EcmaModule))
                {
                    if (method.Name == "UsingResourceKeys")
                    {
                        return(RemoveAction.ConvertToTrueStub);
                    }
                    else if (method.Name == "GetResourceString" && method.Signature.Length == 2)
                    {
                        return(RemoveAction.ConvertToGetResourceStringStub);
                    }

                    return(RemoveAction.Nothing);
                }
            }

            return(RemoveAction.Nothing);
        }
Esempio n. 2
0
        private TypeDesc MarshalArgument(TypeDesc type)
        {
            if (IsBlittableType(type))
            {
                return(type.UnderlyingType);
            }

            if (type.IsSzArray)
            {
                var arrayType = (ArrayType)type;
                if (IsBlittableType(arrayType.ParameterType))
                {
                    return(EmitArrayMarshalling(arrayType));
                }

                if (arrayType.ParameterType == _context.GetWellKnownType(WellKnownType.Char))
                {
                    if (GetCharSet() == PInvokeAttributes.CharSetUnicode)
                    {
                        return(EmitArrayMarshalling(arrayType));
                    }
                }
            }

            if (type.IsByRef)
            {
                var byRefType = (ByRefType)type;
                if (IsBlittableType(byRefType.ParameterType))
                {
                    return(EmitByRefMarshalling(byRefType));
                }

                if (byRefType.ParameterType == _context.GetWellKnownType(WellKnownType.Char))
                {
                    if (GetCharSet() == PInvokeAttributes.CharSetUnicode)
                    {
                        return(EmitByRefMarshalling(byRefType));
                    }
                }
            }

            if (type.IsString)
            {
                return(EmitStringMarshalling());
            }

            if (type.Category == TypeFlags.Boolean)
            {
                return(EmitBooleanMarshalling());
            }

            if (type is MetadataType)
            {
                var metadataType = (MetadataType)type;

                if (metadataType.Module == _context.SystemModule)
                {
                    var nameSpace = metadataType.Namespace;
                    var name      = metadataType.Name;

                    if (name == "StringBuilder" && nameSpace == "System.Text")
                    {
                        return(EmitStringBuilderMarshalling());
                    }
                }
            }

            if (IsSafeHandle(type))
            {
                return(EmitSafeHandleMarshalling(type));
            }

            throw new NotSupportedException();
        }
Esempio n. 3
0
 public GenericDefinitionEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type)
 {
     Debug.Assert(type.IsGenericDefinition);
 }
Esempio n. 4
0
        public static TypeDesc MergeTypesToCommonParent(TypeDesc ta, TypeDesc tb)
        {
            if (ta == tb)
            {
                return(ta);
            }

            // Handle the array case
            if (ta.IsArray)
            {
                if (tb.IsArray)
                {
                    return(MergeArrayTypesToCommonParent((ArrayType)ta, (ArrayType)tb));
                }
                else if (tb.IsInterface)
                {
                    // Check to see if we can merge the array to a common interface (such as Derived[] and IList<Base>)
                    if (ta.CanCastTo(tb))
                    {
                        return(tb);
                    }
                }
                // keep merging from here
                ta = ta.Context.GetWellKnownType(WellKnownType.Array);
            }
            else if (tb.IsArray)
            {
                if (ta.IsInterface && tb.CanCastTo(ta))
                {
                    return(ta);
                }

                tb = tb.Context.GetWellKnownType(WellKnownType.Array);
            }

            Debug.Assert(ta.IsDefType);
            Debug.Assert(tb.IsDefType);

            if (tb.IsInterface)
            {
                if (ta.IsInterface)
                {
                    //
                    // Both classes are interfaces.  Check that if one
                    // interface extends the other.
                    //
                    // Does tb extend ta ?
                    //
                    if (tb.ImplementsEquivalentInterface(ta))
                    {
                        return(ta);
                    }

                    //
                    // Does tb extend ta ?
                    //
                    if (ta.ImplementsEquivalentInterface(tb))
                    {
                        return(tb);
                    }

                    // No compatible merge found - using Object
                    return(ta.Context.GetWellKnownType(WellKnownType.Object));
                }
                else
                {
                    return(MergeClassWithInterface(ta, tb));
                }
            }
            else if (ta.IsInterface)
            {
                return(MergeClassWithInterface(tb, ta));
            }

            int aDepth = 0;
            int bDepth = 0;

            // find the depth in the class hierarchy for each class
            for (TypeDesc searchType = ta; searchType != null; searchType = searchType.BaseType)
            {
                aDepth++;
            }

            for (TypeDesc searchType = tb; searchType != null; searchType = searchType.BaseType)
            {
                bDepth++;
            }

            // for whichever class is lower down in the hierarchy, walk up the superclass chain
            // to the same level as the other class
            while (aDepth > bDepth)
            {
                ta = ta.BaseType;
                aDepth--;
            }

            while (bDepth > aDepth)
            {
                tb = tb.BaseType;
                bDepth--;
            }

            while (ta != tb)
            {
                ta = ta.BaseType;
                tb = tb.BaseType;
            }

            // If no compatible merge is found, we end up using Object

            Debug.Assert(ta != null);

            return(ta);
        }
Esempio n. 5
0
        private ulong BuildBuckets(double timeScale, double maxAge)
        {
            ReadNewLog log = liveObjectTable.readNewLog;
            bool useMarkers = markersRadioButton.Checked;
            if (this.useMarkers != useMarkers)
            {
                this.useMarkers = useMarkers;
                bucketTable = null;
            }
            int bucketCount;
            if (useMarkers)
            {
                for (bucketCount = 0; bucketCount < log.commentEventList.count; bucketCount++)
                    if (log.commentEventList.eventTickIndex[bucketCount] >= liveObjectTable.lastTickIndex)
                        break;
                bucketCount++;
            }
            else
            {
                bucketCount = (int)Math.Ceiling(maxAge/timeScale);
                if (bucketCount == 0)
                    bucketCount = 1;
            }
            if (bucketTable == null || bucketTable.Length != bucketCount)
            {
                bucketTable = new Bucket[bucketCount];
                double nowTime = log.TickIndexToTime(liveObjectTable.lastTickIndex);
                double age = 0;
                for (int i = 0; i < bucketTable.Length; i++)
                {
                    bucketTable[i].totalSize = 0;
                    bucketTable[i].typeDescToSizeCount = new Dictionary<TypeDesc, SizeCount>();
                    bucketTable[i].minAge = age;
                    if (useMarkers)
                    {
                        int markerIndex = bucketTable.Length - i - 1;
                        if (i > 0)
                            bucketTable[i].minComment = log.commentEventList.eventString[markerIndex];
                        age = nowTime;
                        if (markerIndex > 0)
                        {
                            bucketTable[i].maxComment = log.commentEventList.eventString[markerIndex-1];
                            age -= log.TickIndexToTime(log.commentEventList.eventTickIndex[markerIndex-1]);                        
                        }
                    }
                    else
                    {
                        age += timeScale;
                    }
                    bucketTable[i].maxAge = age;
                }

                if (typeIndexToTypeDesc == null || typeIndexToTypeDesc.Length < log.typeName.Length)
                    typeIndexToTypeDesc = new TypeDesc[log.typeName.Length];
                else
                {
                    foreach (TypeDesc t in typeIndexToTypeDesc)
                    {
                        if (t != null)
                            t.totalSize = 0;
                    }
                }
                LiveObjectTable.LiveObject o;
                for (liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue; liveObjectTable.GetNextObject(o.id + o.size, ulong.MaxValue, out o))
                {
                    int bucketIndex;
                    double allocTime = log.TickIndexToTime(o.allocTickIndex);
                    age = nowTime - allocTime;
                    bucketIndex = (int)(age/timeScale);
                    if (bucketIndex >= bucketTable.Length)
                        bucketIndex = bucketTable.Length - 1;
                    else if (bucketIndex < 0)
                        bucketIndex = 0;
                    while (bucketIndex < bucketTable.Length - 1 && age >= bucketTable[bucketIndex].maxAge)
                        bucketIndex++;
                    while (bucketIndex > 0 && age < bucketTable[bucketIndex].minAge)
                        bucketIndex--;
                    bucketTable[bucketIndex].totalSize += o.size;
                    TypeDesc t = typeIndexToTypeDesc[o.typeIndex];
                    if (t == null)
                    {
                        t = new TypeDesc(log.typeName[o.typeIndex]);
                        typeIndexToTypeDesc[o.typeIndex] = t;
                    }
                    t.totalSize += o.size;
                    SizeCount sizeCount;
                    if (!bucketTable[bucketIndex].typeDescToSizeCount.TryGetValue(t, out sizeCount))
                    {
                        sizeCount = new SizeCount();
                        bucketTable[bucketIndex].typeDescToSizeCount[t] = sizeCount;
                    }
                    sizeCount.size += o.size;
                    sizeCount.count += 1;
                }
            }

            ulong maxBucketSize = 0;
            foreach (Bucket b in bucketTable)
            {
                if (maxBucketSize < b.totalSize)
                    maxBucketSize = b.totalSize;
            }

            totalSize = 0;
            sortedTypeTable = new ArrayList();
            foreach (TypeDesc t in typeIndexToTypeDesc)
            {
                if (t != null)
                {
                    sortedTypeTable.Add(t);
                    totalSize += t.totalSize;
                }
            }

            sortedTypeTable.Sort();

            return maxBucketSize;
        }
        void BuildAddressRangesTypeTable()
        {
            rangeList = null;
            rangeCount = 0;

            if (typeIndexToTypeDesc == null || typeIndexToTypeDesc.Length < typeName.Length)
                typeIndexToTypeDesc = new TypeDesc[typeName.Length];
            else
            {
                foreach (TypeDesc t in typeIndexToTypeDesc)
                {
                    if (t != null)
                    {
                        t.totalSize = 0;
                        t.selectedSize = 0;
                    }
                }
            }

            ulong totalAllocated = 0;
            ulong totalSelected = 0;
            LiveObjectTable.LiveObject o;
            bool prevLOH = false;
            for (liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue; liveObjectTable.GetNextObject(o.id + o.size, ulong.MaxValue, out o))
            {
                int gen = liveObjectTable.GenerationOfObject(ref o);
                if (gen > generations-1)
                    gen = generations-1;

                bool thisLOH = gen == generations-1;

                // Check whether we can fit this object into the last range we created.
                // We assume the liveObjectList is sorted, so the object can only attach
                // at the end of this range.
                if (rangeList != null && o.id - rangeList.hiAddr <= allowableGap && prevLOH == thisLOH)
                {
                    Debug.Assert(o.id >= rangeList.hiAddr);
                    rangeList.hiAddr = o.id + o.size;
                }
                else
                {
                    rangeList = new AddressRange(o.id, o.id + o.size, rangeList, rangeCount++);
                }
                prevLOH = thisLOH;

                TypeDesc t = typeIndexToTypeDesc[o.typeIndex];
                if (t == null)
                {
                    t = new TypeDesc(o.typeIndex, typeName[o.typeIndex]);
                    typeIndexToTypeDesc[o.typeIndex] = t;
                }
                t.totalSize += o.size;
                totalAllocated += o.size;
                if (InsideSelection(o.id) != 0)
                {
                    t.selectedSize += o.size;
                    totalSelected += o.size;
                }
                
                if (rangeList.genLoAddr[gen] > o.id)
                    rangeList.genLoAddr[gen] = o.id;
                if (rangeList.genHiAddr[gen] < o.id + o.size)
                    rangeList.genHiAddr[gen] = o.id + o.size;
            }

            sortedTypeTable = new ArrayList();
            foreach (TypeDesc t in typeIndexToTypeDesc)
                if (t != null)
                    sortedTypeTable.Add(t);
            sortedTypeTable.Sort();

            foreach (TypeDesc t in sortedTypeTable)
            {
                t.percentage = 0.0;
                if (totalAllocated > 0)
                    t.percentage = 100.0*t.totalSize/totalAllocated;
                t.selectedPercentage = 0.0;
                if (totalSelected > 0)
                    t.selectedPercentage = 100*t.selectedSize/totalSelected;
            }
        }
Esempio n. 7
0
 public static bool IsSystemGuid(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "Guid"));
 }
 private void AddToTypeTable(int typeIndex, int lifeTime)
 {
     TypeDesc t = typeIndexToTypeDesc[typeIndex];
     if (t == null)
     {
         t = new TypeDesc(typeName[typeIndex]);
         typeIndexToTypeDesc[typeIndex] = t;
     }
     t.totalSize += lifeTime;
 }
Esempio n. 9
0
 public static bool IsStringBuilder(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System.Text", "StringBuilder"));
 }
Esempio n. 10
0
 public static bool IsSystemDecimal(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "Decimal"));
 }
Esempio n. 11
0
 public static bool IsSystemDateTime(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "DateTime"));
 }
Esempio n. 12
0
 public static bool IsHandleRef(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System.Runtime.InteropServices", "HandleRef"));
 }
Esempio n. 13
0
 public static bool IsCriticalHandle(TypeSystemContext context, TypeDesc type)
 {
     return(IsOrDerivesFromType(type, GetCriticalHandle(context)));
 }
Esempio n. 14
0
 public PropertySignature(bool isStatic, TypeDesc[] parameters, TypeDesc returnType)
 {
     IsStatic = isStatic;
     _parameters = parameters;
     ReturnType = returnType;
 }
Esempio n. 15
0
 public void AddCompilationRoot(TypeDesc type, string reason)
 {
     _rootAdder(_factory.ConstructedTypeSymbol(type), reason);
 }
        void BuildSizeRangesAndTypeTable(int[] typeSizeStacktraceToCount)
        {
            BuildBuckets();

            totalSize = 0;
            totalCount = 0;

            if (typeIndexToTypeDesc == null)
                typeIndexToTypeDesc = new TypeDesc[histogram.readNewLog.typeName.Length];
            else
            {
                foreach (TypeDesc t in typeIndexToTypeDesc)
                {
                    if (t != null)
                    {
                        t.totalSize = 0;
                        t.count = 0;
                    }
                }
            }

            for (int i = 0; i < typeSizeStacktraceToCount.Length; i++)
            {
                int count = typeSizeStacktraceToCount[i];
                if (count == 0)
                    continue;

                int[] stacktrace = histogram.readNewLog.stacktraceTable.IndexToStacktrace(i);
                int typeIndex = stacktrace[0];
                int size = stacktrace[1];

                TypeDesc t = (TypeDesc)typeIndexToTypeDesc[typeIndex];
                if (t == null)
                {
                    t = new TypeDesc(typeName[typeIndex]);
                    typeIndexToTypeDesc[typeIndex] = t;
                }
                t.totalSize += (ulong)size*(ulong)count;
                t.count += count;

                totalSize += (ulong)size * (ulong)count;
                totalCount += count;

                AddToBuckets(t, size, count);
            }

            if (totalSize == 0)
                totalSize = 1;
            if (totalCount == 0)
                totalCount = 1;

            TrimEmptyBuckets();

            sortedTypeTable = new ArrayList();
            foreach (TypeDesc t in typeIndexToTypeDesc)
                if (t != null)
                    sortedTypeTable.Add(t);
            sortedTypeTable.Sort();
        }
Esempio n. 17
0
 internal bool IsInheritanceChainLayoutFixedInCurrentVersionBubble(TypeDesc type)
 {
     // TODO: implement
     return(true);
 }
Esempio n. 18
0
 internal ByRefType(TypeDesc parameter)
     : base(parameter)
 {
 }
Esempio n. 19
0
 public bool IsEffectivelySealed(TypeDesc type)
 {
     return(_devirtualizationManager.IsEffectivelySealed(type));
 }
 private void RedrawType(TypeDesc t)
 {
     DrawTypeDescription(typeLegendPanel.CreateGraphics(), t);
     Graphics g = graphPanel.CreateGraphics();
     DrawLiveObjects(g, t, 0, ulong.MaxValue);
     Pen pen = new Pen(Color.Black);
     DrawSelectionHorizontalLine(g, pen, selectedHighAddr);
     DrawSelectionHorizontalLine(g, pen, selectedLowAddr);
 }
Esempio n. 21
0
 public MethodDesc ResolveVirtualMethod(MethodDesc declMethod, TypeDesc implType)
 {
     return(_devirtualizationManager.ResolveVirtualMethod(declMethod, implType));
 }
Esempio n. 22
0
 public void AddCompilationRoot(TypeDesc type, string reason)
 {
     _graph.AddRoot(_factory.MaximallyConstructableType(type), reason);
 }
Esempio n. 23
0
 public bool IsVectorOfT(TypeDesc type)
 {
     return(IsSimdType(type) &&
            ((MetadataType)type).Name == "Vector`1" &&
            ((MetadataType)type).Namespace == "System.Numerics");
 }
Esempio n. 24
0
 /// <summary>
 /// Wrapper helper function around the IsCanonicalDefinitionType API on the TypeSystemContext
 /// </summary>
 public static bool IsCanonicalDefinitionType(this TypeDesc type, CanonicalFormKind kind)
 {
     return(type.Context.IsCanonicalDefinitionType(type, kind));
 }
Esempio n. 25
0
        private Object ResolveMemberReference(MemberReferenceHandle handle)
        {
            MemberReference memberReference = _metadataReader.GetMemberReference(handle);

            Object parent = GetObject(memberReference.Parent, NotFoundBehavior.ReturnResolutionFailure);

            if (parent is ResolutionFailure)
            {
                return(parent);
            }

            TypeDesc parentTypeDesc = parent as TypeDesc;

            if (parentTypeDesc != null)
            {
                BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature);

                EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure);

                string name = _metadataReader.GetString(memberReference.Name);

                if (parser.IsFieldSignature)
                {
                    FieldDesc field = parentTypeDesc.GetField(name);
                    if (field != null)
                    {
                        return(field);
                    }

                    return(ResolutionFailure.GetMissingFieldFailure(parentTypeDesc, name));
                }
                else
                {
                    MethodSignature sig = parser.ParseMethodSignature();
                    if (sig == null)
                    {
                        return(parser.ResolutionFailure);
                    }
                    TypeDesc      typeDescToInspect = parentTypeDesc;
                    Instantiation substitution      = default(Instantiation);

                    // Try to resolve the name and signature in the current type, or any of the base types.
                    do
                    {
                        MethodDesc method = typeDescToInspect.GetMethod(name, sig, substitution);
                        if (method != null)
                        {
                            // If this resolved to one of the base types, make sure it's not a constructor.
                            // Instance constructors are not inherited.
                            if (typeDescToInspect != parentTypeDesc && method.IsConstructor)
                            {
                                break;
                            }

                            return(method);
                        }
                        var baseType = typeDescToInspect.BaseType;
                        if (baseType != null)
                        {
                            if (!baseType.HasInstantiation)
                            {
                                substitution = default(Instantiation);
                            }
                            else
                            {
                                // If the base type is generic, any signature match for methods on the base type with the generic details from
                                // the deriving type
                                Instantiation newSubstitution = typeDescToInspect.GetTypeDefinition().BaseType.Instantiation;
                                if (!substitution.IsNull)
                                {
                                    TypeDesc[] newSubstitutionTypes = new TypeDesc[newSubstitution.Length];
                                    for (int i = 0; i < newSubstitution.Length; i++)
                                    {
                                        newSubstitutionTypes[i] = newSubstitution[i].InstantiateSignature(substitution, default(Instantiation));
                                    }
                                    newSubstitution = new Instantiation(newSubstitutionTypes);
                                }
                                substitution = newSubstitution;
                            }
                        }
                        typeDescToInspect = baseType;
                    } while (typeDescToInspect != null);

                    return(ResolutionFailure.GetMissingMethodFailure(parentTypeDesc, name, sig));
                }
            }
            else if (parent is MethodDesc)
            {
                ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramVararg, (MethodDesc)parent);
            }
            else if (parent is ModuleDesc)
            {
                throw new NotImplementedException("MemberRef to a global function or variable.");
            }

            ThrowHelper.ThrowBadImageFormatException();
            return(null);
        }
Esempio n. 26
0
        private static TypeDesc GetTypeThatMeetsConstraints(GenericParameterDesc genericParam, bool allowCanon)
        {
            TypeSystemContext context = genericParam.Context;

            // Universal canon is the best option if it's supported
            if (allowCanon && context.SupportsUniversalCanon)
            {
                return(context.UniversalCanonType);
            }

            // Not nullable type is the only thing where we can't substitute reference types
            GenericConstraints constraints = genericParam.Constraints;

            if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0)
            {
                return(null);
            }

            // If canon is allowed, we can use that
            if (allowCanon && context.SupportsCanon)
            {
                foreach (var c in genericParam.TypeConstraints)
                {
                    // Could be e.g. "where T : U"
                    // We could try to dig into the U and solve it, but that just opens us up to
                    // recursion and it's just not worth it.
                    if (c.IsSignatureVariable)
                    {
                        return(null);
                    }

                    if (!c.IsGCPointer)
                    {
                        return(null);
                    }
                }

                return(genericParam.Context.CanonType);
            }

            // If canon is not allowed, we're limited in our choices.
            TypeDesc constrainedType = null;

            foreach (var c in genericParam.TypeConstraints)
            {
                // Can't do multiple constraints
                if (constrainedType != null)
                {
                    return(null);
                }

                // Could be e.g. "where T : IFoo<U>" or "where T : U"
                if (c.ContainsSignatureVariables())
                {
                    return(null);
                }

                constrainedType = c;
            }

            return(constrainedType ?? genericParam.Context.GetWellKnownType(WellKnownType.Object));
        }
Esempio n. 27
0
 public bool HasFixedSlotVTable(TypeDesc type)
 {
     return(true);
 }
Esempio n. 28
0
        /// <summary>
        /// Provides method bodies for intrinsics recognized by the compiler that
        /// are specialized per instantiation. It can return null if the intrinsic
        /// is not recognized.
        /// </summary>
        private MethodIL TryGetPerInstantiationIntrinsicMethodIL(MethodDesc method)
        {
            Debug.Assert(method.IsIntrinsic);

            MetadataType owningType = method.OwningType.GetTypeDefinition() as MetadataType;

            if (owningType == null)
            {
                return(null);
            }

            string methodName = method.Name;

            switch (owningType.Name)
            {
            case "RuntimeHelpers":
            {
                if ((methodName == "IsReferenceOrContainsReferences" || methodName == "IsReference") &&
                    owningType.Namespace == "System.Runtime.CompilerServices")
                {
                    TypeDesc elementType = method.Instantiation[0];

                    // Fallback to non-intrinsic implementation for universal generics
                    if (elementType.IsCanonicalSubtype(CanonicalFormKind.Universal))
                    {
                        return(null);
                    }

                    bool result = elementType.IsGCPointer;
                    if (methodName == "IsReferenceOrContainsReferences")
                    {
                        result |= (elementType.IsDefType ? ((DefType)elementType).ContainsGCPointers : false);
                    }

                    return(new ILStubMethodIL(method, new byte[] {
                            result ? (byte)ILOpcode.ldc_i4_1 : (byte)ILOpcode.ldc_i4_0,
                            (byte)ILOpcode.ret
                        },
                                              Array.Empty <LocalVariableDefinition>(), null));
                }
            }
            break;

            case "Comparer`1":
            {
                if (methodName == "Create" && owningType.Namespace == "System.Collections.Generic")
                {
                    return(ComparerIntrinsics.EmitComparerCreate(method));
                }
            }
            break;

            case "EqualityComparer`1":
            {
                if (methodName == "Create" && owningType.Namespace == "System.Collections.Generic")
                {
                    return(ComparerIntrinsics.EmitEqualityComparerCreate(method));
                }
            }
            break;

            case "EqualityComparerHelpers":
            {
                if (owningType.Namespace != "Internal.IntrinsicSupport")
                {
                    return(null);
                }

                if (methodName == "EnumOnlyEquals")
                {
                    // EnumOnlyEquals would basically like to do this:
                    // static bool EnumOnlyEquals<T>(T x, T y) where T: struct => x == y;
                    // This is not legal though.
                    // We don't want to do this:
                    // static bool EnumOnlyEquals<T>(T x, T y) where T: struct => x.Equals(y);
                    // Because it would box y.
                    // So we resort to some per-instantiation magic.

                    TypeDesc elementType = method.Instantiation[0];
                    if (!elementType.IsEnum)
                    {
                        return(null);
                    }

                    ILOpcode convInstruction;
                    if (((DefType)elementType).InstanceFieldSize.AsInt <= 4)
                    {
                        convInstruction = ILOpcode.conv_i4;
                    }
                    else
                    {
                        Debug.Assert(((DefType)elementType).InstanceFieldSize.AsInt == 8);
                        convInstruction = ILOpcode.conv_i8;
                    }

                    return(new ILStubMethodIL(method, new byte[] {
                            (byte)ILOpcode.ldarg_0,
                            (byte)convInstruction,
                            (byte)ILOpcode.ldarg_1,
                            (byte)convInstruction,
                            (byte)ILOpcode.prefix1, unchecked ((byte)ILOpcode.ceq),
                            (byte)ILOpcode.ret,
                        },
                                              Array.Empty <LocalVariableDefinition>(), null));
                }
                else if (methodName == "GetComparerForReferenceTypesOnly")
                {
                    TypeDesc elementType = method.Instantiation[0];
                    if (!elementType.IsRuntimeDeterminedSubtype &&
                        !elementType.IsCanonicalSubtype(CanonicalFormKind.Any) &&
                        !elementType.IsGCPointer)
                    {
                        return(new ILStubMethodIL(method, new byte[] {
                                (byte)ILOpcode.ldnull,
                                (byte)ILOpcode.ret
                            },
                                                  Array.Empty <LocalVariableDefinition>(), null));
                    }
                }
                else if (methodName == "StructOnlyEquals")
                {
                    TypeDesc elementType = method.Instantiation[0];
                    if (!elementType.IsRuntimeDeterminedSubtype &&
                        !elementType.IsCanonicalSubtype(CanonicalFormKind.Any) &&
                        !elementType.IsGCPointer)
                    {
                        Debug.Assert(elementType.IsValueType);

                        TypeSystemContext context    = elementType.Context;
                        MetadataType      helperType = context.SystemModule.GetKnownType("Internal.IntrinsicSupport", "EqualityComparerHelpers");

                        MethodDesc methodToCall = null;
                        if (elementType.IsEnum)
                        {
                            methodToCall = helperType.GetKnownMethod("EnumOnlyEquals", null).MakeInstantiatedMethod(elementType);
                        }
                        else if (elementType.IsNullable && ComparerIntrinsics.ImplementsIEquatable(elementType.Instantiation[0]))
                        {
                            methodToCall = helperType.GetKnownMethod("StructOnlyEqualsNullable", null).MakeInstantiatedMethod(elementType.Instantiation[0]);
                        }
                        else if (ComparerIntrinsics.ImplementsIEquatable(elementType))
                        {
                            methodToCall = helperType.GetKnownMethod("StructOnlyEqualsIEquatable", null).MakeInstantiatedMethod(elementType);
                        }

                        if (methodToCall != null)
                        {
                            return(new ILStubMethodIL(method, new byte[]
                                {
                                    (byte)ILOpcode.ldarg_0,
                                    (byte)ILOpcode.ldarg_1,
                                    (byte)ILOpcode.call, 1, 0, 0, 0,
                                    (byte)ILOpcode.ret
                                },
                                                      Array.Empty <LocalVariableDefinition>(), new object[] { methodToCall }));
                        }
                    }
                }
            }
            break;
            }

            return(null);
        }
Esempio n. 29
0
 public DelegateCreationInfo GetDelegateCtor(TypeDesc delegateType, MethodDesc target, bool followVirtualDispatch)
 {
     return(DelegateCreationInfo.Create(delegateType, target, NodeFactory, followVirtualDispatch));
 }
Esempio n. 30
0
        public MethodIL EmitIL()
        {
            MethodSignature targetMethodSignature = _targetMethod.Signature;

            // We have 4 code streams:
            // - _marshallingCodeStream is used to convert each argument into a native type and
            // store that into the local
            // - callsiteSetupCodeStream is used to used to load each previously generated local
            // and call the actual target native method.
            // - _returnValueMarshallingCodeStream is used to convert the native return value
            // to managed one.
            // - _unmarshallingCodestream is used to propagate [out] native arguments values to
            // managed ones.
            _emitter = new ILEmitter();
            ILCodeStream fnptrLoadStream = _emitter.NewCodeStream();

            _marshallingCodeStream = _emitter.NewCodeStream();
            ILCodeStream callsiteSetupCodeStream = _emitter.NewCodeStream();

            _returnValueMarshallingCodeStream = _emitter.NewCodeStream();
            _unmarshallingCodestream          = _emitter.NewCodeStream();

            TypeDesc[] nativeParameterTypes = new TypeDesc[targetMethodSignature.Length];

            //
            // Parameter marshalling
            //

            //
            // Convert each argument to something we can pass to native and store it in a local.
            // Then load the local in the second code stream.
            //
            for (int i = 0; i < targetMethodSignature.Length; i++)
            {
                // TODO: throw if there's custom marshalling

                _marshallingCodeStream.EmitLdArg(i);

                TypeDesc nativeType = MarshalArgument(targetMethodSignature[i]);

                nativeParameterTypes[i] = nativeType;

                ILLocalVariable vMarshalledTypeTemp = _emitter.NewLocal(nativeType);
                _marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);

                callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
            }

            //
            // Return value marshalling
            //

            // TODO: throw if SetLastError is true
            // TODO: throw if there's custom marshalling

            TypeDesc nativeReturnType = MarshalReturnValue(targetMethodSignature.ReturnType);

            if (UseLazyResolution(_targetMethod, _importMetadata.Module))
            {
                MetadataType lazyHelperType   = _targetMethod.Context.GetHelperType("InteropHelpers");
                FieldDesc    lazyDispatchCell = new PInvokeLazyFixupField((DefType)_targetMethod.OwningType, _importMetadata);
                fnptrLoadStream.Emit(ILOpcode.ldsflda, _emitter.NewToken(lazyDispatchCell));
                fnptrLoadStream.Emit(ILOpcode.call, _emitter.NewToken(lazyHelperType.GetKnownMethod("ResolvePInvoke", null)));

                MethodSignatureFlags unmanagedCallConv = PInvokeMetadata.GetUnmanagedCallingConvention(_importMetadata.Attributes);

                MethodSignature nativeCalliSig = new MethodSignature(
                    targetMethodSignature.Flags | unmanagedCallConv, 0, nativeReturnType, nativeParameterTypes);

                ILLocalVariable vNativeFunctionPointer = _emitter.NewLocal(_targetMethod.Context.GetWellKnownType(WellKnownType.IntPtr));
                fnptrLoadStream.EmitStLoc(vNativeFunctionPointer);
                callsiteSetupCodeStream.EmitLdLoc(vNativeFunctionPointer);
                callsiteSetupCodeStream.Emit(ILOpcode.calli, _emitter.NewToken(nativeCalliSig));
            }
            else
            {
                // Eager call
                PInvokeMetadata nativeImportMetadata =
                    new PInvokeMetadata(_importMetadata.Module, _importMetadata.Name ?? _targetMethod.Name, _importMetadata.Attributes);

                MethodSignature nativeSig = new MethodSignature(
                    targetMethodSignature.Flags, 0, nativeReturnType, nativeParameterTypes);

                MethodDesc nativeMethod =
                    new PInvokeTargetNativeMethod(_targetMethod.OwningType, nativeSig, nativeImportMetadata);

                callsiteSetupCodeStream.Emit(ILOpcode.call, _emitter.NewToken(nativeMethod));
            }

            _unmarshallingCodestream.Emit(ILOpcode.ret);

            return(_emitter.Link(_targetMethod));
        }
Esempio n. 31
0
 public bool HasLazyStaticConstructor(TypeDesc type)
 {
     return(type.HasStaticConstructor);
 }
 void AddToBuckets(TypeDesc t, int size, int count)
 {
     for (int i = 0; i < buckets.Length; i++)
     {
         if (buckets[i].minSize <= size && size <= buckets[i].maxSize)
         {
             ulong totalSize = (ulong)size*(ulong)count;
             buckets[i].totalSize += totalSize;
             SizeCount sizeCount;
             if (!buckets[i].typeDescToSizeCount.TryGetValue(t, out sizeCount))
             {
                 sizeCount = new SizeCount();
                 buckets[i].typeDescToSizeCount[t] = sizeCount;
             }
             sizeCount.size += totalSize;
             sizeCount.count += count;
             break;
         }
     }
 }
Esempio n. 33
0
 internal ByRefType(TypeDesc parameter)
     : base(parameter)
 {
 }
Esempio n. 34
0
        public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
        {
            MethodDesc method = this;

            TypeDesc owningType = method.OwningType;
            TypeDesc instantiatedOwningType = owningType.InstantiateSignature(typeInstantiation, methodInstantiation);
            if (owningType != instantiatedOwningType)
                method = instantiatedOwningType.Context.ResolveRuntimeMethod(UnboxingStub, (DefType)instantiatedOwningType, _nameAndSignature, IntPtr.Zero, false);

            Instantiation instantiation = method.Instantiation;
            TypeDesc[] clone = null;

            for (int i = 0; i < instantiation.Length; i++)
            {
                TypeDesc uninst = instantiation[i];
                TypeDesc inst = uninst.InstantiateSignature(typeInstantiation, methodInstantiation);
                if (inst != uninst)
                {
                    if (clone == null)
                    {
                        clone = new TypeDesc[instantiation.Length];
                        for (int j = 0; j < clone.Length; j++)
                        {
                            clone[j] = instantiation[j];
                        }
                    }
                    clone[i] = inst;
                }
            }

            return (clone == null) ? method : method.Context.GetInstantiatedMethod(method.GetMethodDefinition(), new Instantiation(clone));
        }
Esempio n. 35
0
 public DelegateCreationInfo GetDelegateCtor(TypeDesc delegateType, MethodDesc target)
 {
     return(DelegateCreationInfo.Create(delegateType, target, NodeFactory));
 }
Esempio n. 36
0
 public LocalVariableDefinition(TypeDesc type, bool isPinned)
 {
     IsPinned = isPinned;
     Type = type;
 }
Esempio n. 37
0
 public bool HasLazyStaticConstructor(TypeDesc type)
 {
     return(TypeSystemContext.HasLazyStaticConstructor(type));
 }
Esempio n. 38
0
 internal PointerType(TypeDesc parameterType)
     : base(parameterType)
 {
 }
Esempio n. 39
0
 internal abstract VTableSliceNode GetSlice(TypeDesc type);
 private void DrawTypeDescription(Graphics g, TypeDesc t)
 {
     int dotOffset = (font.Height - dotSize)/2;
     g.FillRectangle(t.brushes[t.selected], t.rect.Left, t.rect.Top+dotOffset, dotSize, dotSize);
     g.DrawString(t.typeName, font, blackBrush, t.rect.Left + dotSize*2, t.rect.Top);
     string s = string.Format(" ({0:n0} bytes, {1:f2}% - {2:n0} bytes, {3:f2}% selected)",
                                  t.totalSize,  t.percentage,      t.selectedSize, t.selectedPercentage);
     g.DrawString(s, font, blackBrush, t.rect.Left + dotSize*2, t.rect.Top + font.Height);
 }
Esempio n. 41
0
 internal override VTableSliceNode GetSlice(TypeDesc type)
 {
     return(new LazilyBuiltVTableSliceNode(type));
 }
 private string ComputeObjectsDescription(TypeDesc selectedType, ulong selectedLowAddr, ulong selectedHighAddr)
 {
     string description = "";
     if (selectedType != null)
         description += selectedType.typeName + " ";
     description += "objects ";
     if (selectedLowAddr > 0)
         description += string.Format("between {0} and {1}", FormatAddress(selectedLowAddr), FormatAddress(selectedHighAddr));
     return description;
 }
Esempio n. 43
0
 public AppContextInitializerMethod(TypeDesc owningType, IEnumerable <string> switches)
 {
     _owningType = owningType;
     _switches   = new List <string>(switches);
 }
        private void DrawLiveObjects(Graphics g, TypeDesc selectedType, ulong lowAddr, ulong highAddr)
        {
            Pen freePen = new Pen(Color.White);

            RectangleF clipRect = g.VisibleClipBounds;
            for (AddressRange r = rangeList; r != null; r = r.next)
            {
                // figure out base x for this range
                int x1 = leftMargin + r.index*(heapWidth + gap);
                int x2 = x1 + heapWidth;
                if (x2 < clipRect.Left || clipRect.Right < x1)
                    continue;
                ulong visibleStartAddr = VisibleYToAddress(r, outerGraphPanel.Size.Height);
                ulong visibleEndAddr = VisibleYToAddress(r, 0);
                if (clipRect.Height < outerGraphPanel.Size.Height)
                {
                    visibleStartAddr = VisibleYToAddress(r, (int)clipRect.Bottom + graphPanel.Top + 1);
                    visibleEndAddr = VisibleYToAddress(r, (int)clipRect.Top + graphPanel.Top - 1);
                }

                IntersectIntervals(lowAddr, highAddr, ref visibleStartAddr, ref visibleEndAddr);
                IntersectIntervals(r.loAddr, r.hiAddr, ref visibleStartAddr, ref visibleEndAddr);

                LiveObjectTable.LiveObject o;
                ulong addr = liveObjectTable.FindObjectBackward(visibleStartAddr);
                liveObjectTable.GetNextObject(addr, visibleStartAddr, out o);
                if (o.id + o.size + align - 1 < visibleStartAddr)
                    addr = visibleStartAddr;
                visibleEndAddr += align - 1;
                for (liveObjectTable.GetNextObject(addr, visibleEndAddr, out o); o.id < visibleEndAddr; liveObjectTable.GetNextObject(addr, visibleEndAddr, out o))
                {
                    // fill any space between this object and the end of the previous one
                    // (or the start of the range, as the case may be) in white
                    if (addr + align - 1 < o.id)
                    {
                        FillSpace(g, r, freePen, addr, o.id);
                    }

                    LiveObjectTable.LiveObject oo;
                    for (addr = o.id + o.size; addr < visibleEndAddr; )
                    {
                        // extend this range if oo is adjacent, of the same type, and still in the range
                        liveObjectTable.GetNextObject(addr, visibleEndAddr, out oo);
                        if (oo.id < visibleEndAddr && addr + align - 1 >= oo.id && oo.typeIndex == o.typeIndex)
                        {
                            addr = oo.id + oo.size;
                        }
                        else
                            break;
                    }

                    // figure out what type the object is
                    TypeDesc t = typeIndexToTypeDesc[o.typeIndex];

                    // fill the space in the type's color
                    FillSpace(g, r, t.pens[t.selected], o.id, addr);
                }
                if (addr + align - 1 < visibleEndAddr)
                {
                    FillSpace(g, r, freePen, addr, visibleEndAddr);
                }
            }
        }
 /// <summary>
 /// Compute the RuntimeInterfaces for a TypeDesc, is permitted to depend on 
 /// RuntimeInterfaces of base type, but must not depend on any other
 /// details of the base type.
 /// </summary>
 public abstract DefType[] ComputeRuntimeInterfaces(TypeDesc type);