private void AddBlob(Blob blob) { var blobVertex = new BlobVertex(blob); _contents.AddVertex(blobVertex); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, Array.Empty <ISymbolDefinitionNode>())); } ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory; NativeWriter hashtableWriter = new NativeWriter(); Section hashtableSection = hashtableWriter.NewSection(); VertexHashtable vertexHashtable = new VertexHashtable(); hashtableSection.Place(vertexHashtable); Dictionary <byte[], BlobVertex> uniqueFixups = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); Dictionary <byte[], BlobVertex> uniqueSignatures = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); foreach (MethodWithGCInfo method in r2rFactory.EnumerateCompiledMethods()) { if (method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation) { int methodIndex = r2rFactory.RuntimeFunctionsTable.GetIndex(method); ModuleToken moduleToken = method.SignatureContext.GetModuleTokenForMethod(method.Method.GetTypicalMethodDefinition()); if (moduleToken.Module != r2rFactory.InputModuleContext.GlobalContext) { // TODO: encoding of instance methods relative to other modules within the version bubble continue; } ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder(); signatureBuilder.EmitMethodSignature( new MethodWithToken(method.Method, moduleToken, constrainedType: null), enforceDefEncoding: true, method.SignatureContext, isUnboxingStub: false, isInstantiatingStub: false); byte[] signature = signatureBuilder.ToArray(); BlobVertex signatureBlob; if (!uniqueSignatures.TryGetValue(signature, out signatureBlob)) { signatureBlob = new BlobVertex(signature); hashtableSection.Place(signatureBlob); uniqueSignatures.Add(signature, signatureBlob); } byte[] fixup = method.GetFixupBlob(factory); BlobVertex fixupBlob = null; if (fixup != null && !uniqueFixups.TryGetValue(fixup, out fixupBlob)) { fixupBlob = new BlobVertex(fixup); hashtableSection.Place(fixupBlob); uniqueFixups.Add(fixup, fixupBlob); } EntryPointVertex entryPointVertex = new EntryPointWithBlobVertex((uint)methodIndex, fixupBlob, signatureBlob); hashtableSection.Place(entryPointVertex); vertexHashtable.Append(unchecked ((uint)ReadyToRunHashCode.MethodHashCode(method.Method)), entryPointVertex); } } MemoryStream hashtableContent = new MemoryStream(); hashtableWriter.Save(hashtableContent); return(new ObjectData( data: hashtableContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } NativeWriter writer = new NativeWriter(); Section section = writer.NewSection(); VertexArray vertexArray = new VertexArray(section); section.Place(vertexArray); Dictionary <byte[], BlobVertex> blobCache = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); foreach (MethodWithGCInfo method in factory.EnumerateCompiledMethods()) { MemoryStream methodDebugBlob = new MemoryStream(); byte[] bounds = method.DebugLocInfos; byte[] vars = method.DebugVarInfos; NibbleWriter nibbleWriter = new NibbleWriter(); nibbleWriter.WriteUInt((uint)(bounds?.Length ?? 0)); nibbleWriter.WriteUInt((uint)(vars?.Length ?? 0)); byte[] header = nibbleWriter.ToArray(); methodDebugBlob.Write(header, 0, header.Length); if (bounds?.Length > 0) { methodDebugBlob.Write(bounds, 0, bounds.Length); } if (vars?.Length > 0) { methodDebugBlob.Write(vars, 0, vars.Length); } byte[] debugBlobArrayKey = methodDebugBlob.ToArray(); if (!blobCache.TryGetValue(debugBlobArrayKey, out BlobVertex debugBlob)) { debugBlob = new BlobVertex(methodDebugBlob.ToArray()); blobCache.Add(debugBlobArrayKey, debugBlob); } vertexArray.Set(factory.RuntimeFunctionsTable.GetIndex(method), new DebugInfoVertex(debugBlob)); } vertexArray.ExpandLayout(); MemoryStream writerContent = new MemoryStream(); writer.Save(writerContent); return(new ObjectData( data: writerContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, Array.Empty <ISymbolDefinitionNode>())); } List <EntryPoint> ridToEntryPoint = new List <EntryPoint>(); foreach (MethodWithGCInfo method in factory.EnumerateCompiledMethods(_module, CompiledMethodCategory.NonInstantiated)) { Debug.Assert(method.Method is EcmaMethod); EcmaMethod ecmaMethod = (EcmaMethod)method.Method; Debug.Assert(ecmaMethod.Module == _module); // Strip away the token type bits, keep just the low 24 bits RID uint rid = SignatureBuilder.RidFromToken((mdToken)MetadataTokens.GetToken(ecmaMethod.Handle)); Debug.Assert(rid != 0); rid--; while (ridToEntryPoint.Count <= rid) { ridToEntryPoint.Add(EntryPoint.Null); } int methodIndex = factory.RuntimeFunctionsTable.GetIndex(method); ridToEntryPoint[(int)rid] = new EntryPoint(methodIndex, method); } NativeWriter writer = new NativeWriter(); Section arraySection = writer.NewSection(); VertexArray vertexArray = new VertexArray(arraySection); arraySection.Place(vertexArray); Dictionary <byte[], BlobVertex> uniqueFixups = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); for (int rid = 0; rid < ridToEntryPoint.Count; rid++) { EntryPoint entryPoint = ridToEntryPoint[rid]; if (!entryPoint.IsNull) { byte[] fixups = entryPoint.Method.GetFixupBlob(factory); BlobVertex fixupBlobVertex = null; if (fixups != null && !uniqueFixups.TryGetValue(fixups, out fixupBlobVertex)) { fixupBlobVertex = new BlobVertex(fixups); uniqueFixups.Add(fixups, fixupBlobVertex); } EntryPointVertex entryPointVertex = new EntryPointVertex((uint)entryPoint.MethodIndex, fixupBlobVertex); vertexArray.Set(rid, entryPointVertex); } } vertexArray.ExpandLayout(); MemoryStream arrayContent = new MemoryStream(); writer.Save(arrayContent); return(new ObjectData( data: arrayContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, Array.Empty <ISymbolDefinitionNode>())); } NativeWriter hashtableWriter = new NativeWriter(); Section hashtableSection = hashtableWriter.NewSection(); VertexHashtable vertexHashtable = new VertexHashtable(); hashtableSection.Place(vertexHashtable); Dictionary <byte[], BlobVertex> uniqueFixups = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); Dictionary <byte[], BlobVertex> uniqueSignatures = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); foreach (MethodWithGCInfo method in factory.EnumerateCompiledMethods(null, CompiledMethodCategory.Instantiated)) { Debug.Assert(method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation); int methodIndex = factory.RuntimeFunctionsTable.GetIndex(method); // In composite R2R format, always enforce owning type to let us share generic instantiations among modules EcmaMethod typicalMethod = (EcmaMethod)method.Method.GetTypicalMethodDefinition(); ModuleToken moduleToken = new ModuleToken(typicalMethod.Module, typicalMethod.Handle); ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder(); signatureBuilder.EmitMethodSignature( new MethodWithToken(method.Method, moduleToken, constrainedType: null, unboxing: false), enforceDefEncoding: true, enforceOwningType: _factory.CompilationModuleGroup.EnforceOwningType(moduleToken.Module), factory.SignatureContext, isInstantiatingStub: false); byte[] signature = signatureBuilder.ToArray(); BlobVertex signatureBlob; if (!uniqueSignatures.TryGetValue(signature, out signatureBlob)) { signatureBlob = new BlobVertex(signature); hashtableSection.Place(signatureBlob); uniqueSignatures.Add(signature, signatureBlob); } byte[] fixup = method.GetFixupBlob(factory); BlobVertex fixupBlob = null; if (fixup != null && !uniqueFixups.TryGetValue(fixup, out fixupBlob)) { fixupBlob = new BlobVertex(fixup); hashtableSection.Place(fixupBlob); uniqueFixups.Add(fixup, fixupBlob); } EntryPointVertex entryPointVertex = new EntryPointWithBlobVertex((uint)methodIndex, fixupBlob, signatureBlob); hashtableSection.Place(entryPointVertex); vertexHashtable.Append(unchecked ((uint)ReadyToRunHashCode.MethodHashCode(method.Method)), entryPointVertex); } MemoryStream hashtableContent = new MemoryStream(); hashtableWriter.Save(hashtableContent); return(new ObjectData( data: hashtableContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }