Пример #1
0
            public GraphBuilder(EcmaModule assembly)
            {
                _graph          = new Graph <EcmaGenericParameter>();
                _metadataReader = assembly.MetadataReader;

                foreach (TypeDefinitionHandle typeHandle in _metadataReader.TypeDefinitions)
                {
                    TypeDefinition typeDefinition = _metadataReader.GetTypeDefinition(typeHandle);

                    // Only things that deal with some sort of genericness could form cycles.
                    // Do not look at any types/member where genericness is not involved.
                    // Do not even bother getting type system entities for those that are not generic.
                    bool isGenericType = typeDefinition.GetGenericParameters().Count > 0;
                    if (isGenericType)
                    {
                        try
                        {
                            var ecmaType = (EcmaType)assembly.GetObject(typeHandle);
                            WalkAncestorTypes(ecmaType);
                        }
                        catch (TypeSystemException)
                        {
                        }
                    }

                    foreach (MethodDefinitionHandle methodHandle in typeDefinition.GetMethods())
                    {
                        // We need to look at methods on generic types, or generic methods.
                        bool needsScanning = isGenericType;

                        if (!needsScanning)
                        {
                            MethodDefinition methodDefinition = _metadataReader.GetMethodDefinition(methodHandle);
                            BlobReader       sigBlob          = _metadataReader.GetBlobReader(methodDefinition.Signature);
                            needsScanning = sigBlob.ReadSignatureHeader().IsGeneric;
                        }

                        if (needsScanning)
                        {
                            try
                            {
                                var ecmaMethod = (EcmaMethod)assembly.GetObject(methodHandle);
                                WalkMethod(ecmaMethod);

                                if (ecmaMethod.IsVirtual)
                                {
                                    LookForVirtualOverrides(ecmaMethod);
                                }
                            }
                            catch (TypeSystemException)
                            {
                            }
                        }
                    }
                }
                return;
            }
Пример #2
0
 public EcmaModule GetModuleFromIndex(int index)
 {
     if (EcmaModule.MetadataReader.GetTableRowCount(TableIndex.AssemblyRef) < index)
     {
         return(null);
     }
     return(EcmaModule.GetObject(MetadataTokens.EntityHandle(((int)CorTokenType.mdtAssemblyRef) | index)) as EcmaModule);
 }
Пример #3
0
        public override object GetObject(int token)
        {
            // UserStrings cannot be wrapped in EntityHandle
            if ((token & 0xFF000000) == 0x70000000)
            {
                return(_module.GetUserString(MetadataTokens.UserStringHandle(token)));
            }

            return(_module.GetObject(MetadataTokens.EntityHandle(token)));
        }
Пример #4
0
 public DummyTypeInfo GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
 {
     _resolver.AddModuleTokenForType((TypeDesc)_contextModule.GetObject(handle), new ModuleToken(_contextModule, handle));
     return(DummyTypeInfo.Instance);
 }
Пример #5
0
        public ProfileData ParseIBCDataFromModule(EcmaModule ecmaModule)
        {
            ResourceData peResources = new ResourceData(ecmaModule);

            byte[] ibcDataSection = peResources.FindResource("PROFILE_DATA", "IBC", 0);
            if (ibcDataSection == null)
            {
                // If we don't have profile data, return empty ProfileData object
                return(EmptyProfileData.Singleton);
            }

            var          reader          = new IBCDataReader();
            int          pos             = 0;
            bool         basicBlocksOnly = false;
            AssemblyData parsedData      = reader.Read(ibcDataSection, ref pos, out bool minified);

            if (parsedData.FormatMajorVersion == 1)
            {
                throw new Exception("Unsupported V1 IBC Format");
            }

            Dictionary <IBCBlobKey, BlobEntry> blobs = GetIBCBlobs(parsedData.BlobStream, out HashSet <uint> ignoredIbcMethodSpecTokens);

            List <MethodProfileData> methodProfileData = new List <MethodProfileData>();

            IBCModule ibcModule = new IBCModule(ecmaModule, blobs);

            // Parse the token lists
            IBCData.SectionIteratorKind iteratorKind = basicBlocksOnly ? IBCData.SectionIteratorKind.BasicBlocks : IBCData.SectionIteratorKind.TokenFlags;
            foreach (SectionFormat section in IBCData.SectionIterator(iteratorKind))
            {
                if (!parsedData.Tokens.TryGetValue(section, out List <TokenData> TokenList) ||
                    TokenList.Count == 0)
                {
                    continue;
                }

                // In V1 and minified V3+ files, tokens aren't stored with a
                // scenario mask. In minified V3+ files, it can be treated as
                // anything nonzero--minified files make no guarantee about
                // preserving scenario information, but the flags must be left
                // alone.

                const uint           scenarioMaskIfMissing = 1u;
                HashSet <MethodDesc> methodsFoundInData    = new HashSet <MethodDesc>();

                foreach (TokenData entry in TokenList)
                {
                    //
                    // Discard any token list entries which refer to the ParamMethodSpec blob stream entries
                    // (if any) which were thrown away above.  Note that the MethodProfilingData token list is
                    // the only place anywhere in the IBC data which can ever contain an embedded ibcMethodSpec
                    // token.
                    //

                    if (section == SectionFormat.MethodProfilingData)
                    {
                        if (ignoredIbcMethodSpecTokens.Contains(entry.Token))
                        {
                            continue;
                        }
                    }

                    uint scenarioMask = entry.ScenarioMask ?? scenarioMaskIfMissing;

                    // scenarioMask will be 0 in unprocessed or V1 IBC data.
                    if (scenarioMask == 0)
                    {
                        // TODO Compute RunOnce and RunNever from basic block data
                        scenarioMask = scenarioMaskIfMissing;

                        /*                        Debug.Assert(fullScenarioMask == 1, "Token entry not owned by one scenario");
                         *                      // We have to compute the RunOnceMethod and RunNeverMethod flags.
                         *                      entry.Flags = result.GetFlags(entry.Flags, section, entry.Token);
                         *                      scenarioMask = defaultScenarioMask;*/
                    }

                    //                    Debug.Assert(((~fullScenarioMask & scenarioMask) == 0), "Illegal scenarios mask");

                    MethodDesc associatedMethod = null;

                    switch (Cor.Macros.TypeFromToken(entry.Token))
                    {
                    case CorTokenType.mdtMethodDef:
                    case CorTokenType.mdtMemberRef:
                    case CorTokenType.mdtMethodSpec:
                        object metadataObject = ecmaModule.GetObject(System.Reflection.Metadata.Ecma335.MetadataTokens.EntityHandle((int)entry.Token));
                        if (metadataObject is MethodDesc)
                        {
                            associatedMethod = (MethodDesc)metadataObject;
                        }
                        else
                        {
                            if (_logger.IsVerbose)
                            {
                                _logger.Writer.WriteLine($"Token {(int)entry.Token:x} does not refer to a method");
                            }
                        }
                        break;

                    case CorTokenType.ibcMethodSpec:
                    {
                        if (!blobs.TryGetValue(new IBCBlobKey(entry.Token, BlobType.ParamMethodSpec), out BlobEntry blobEntry))
                        {
                            throw new Exception($"Missing blob entry for ibcMethodSpec {entry.Token:x}");
                        }
                        BlobEntry.SignatureEntry paramSignatureEntry = blobEntry as BlobEntry.SignatureEntry;
                        if (paramSignatureEntry == null)
                        {
                            throw new Exception($"Blob entry for {entry.Token:x} is invalid");
                        }
                        unsafe
                        {
                            fixed(byte *pb = &paramSignatureEntry.Signature[0])
                            {
                                BlobReader br = new BlobReader(pb, paramSignatureEntry.Signature.Length);

                                associatedMethod = GetSigMethodInstantiationFromIBCMethodSpec(ibcModule, br);
                            }
                        }
                    }
                    break;
                    }

                    if (associatedMethod != null)
                    {
                        if (methodsFoundInData.Add(associatedMethod))
                        {
                            methodProfileData.Add(new MethodProfileData(associatedMethod, (MethodProfilingDataFlags)entry.Flags, 0, null, scenarioMask, null));
                        }
                        else
                        {
                            if (_logger.IsVerbose)
                            {
                                _logger.Writer.WriteLine($"Multiple copies of data for method '{associatedMethod}' found.");
                            }
                        }
                    }
                }
            }

            return(new IBCProfileData(parsedData.PartialNGen, methodProfileData));
        }
Пример #6
0
 public EcmaModule GetModuleFromIndex(int index)
 {
     return(EcmaModule.GetObject(MetadataTokens.EntityHandle(((int)CorTokenType.mdtAssemblyRef) | index)) as EcmaModule);
 }