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; }
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); }
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))); }
public DummyTypeInfo GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) { _resolver.AddModuleTokenForType((TypeDesc)_contextModule.GetObject(handle), new ModuleToken(_contextModule, handle)); return(DummyTypeInfo.Instance); }
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 = ¶mSignatureEntry.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)); }
public EcmaModule GetModuleFromIndex(int index) { return(EcmaModule.GetObject(MetadataTokens.EntityHandle(((int)CorTokenType.mdtAssemblyRef) | index)) as EcmaModule); }