internal BlobIdx GetBlobIndex(ImmutableArray <byte> blob) { BlobIdx index; if (!_blobs.TryGetValue(blob, out index)) { Debug.Assert(!_streamsAreComplete); index = new BlobIdx(_blobHeapSize); _blobs.Add(blob, index); _blobHeapSize += BlobWriterImpl.GetCompressedIntegerSize(blob.Length) + blob.Length; } return(index); }
private BlobIdx SerializeDocumentName(string name) { Debug.Assert(name != null); var writer = new BlobBuilder(); int c1 = Count(name, Separator1[0]); int c2 = Count(name, Separator2[0]); char[] separator = (c1 >= c2) ? Separator1 : Separator2; writer.WriteByte((byte)separator[0]); // TODO: avoid allocations foreach (var part in name.Split(separator)) { BlobIdx partIndex = _debugHeapsOpt.GetBlobIndex(ImmutableArray.Create(s_utf8Encoding.GetBytes(part))); writer.WriteCompressedInteger((uint)_debugHeapsOpt.ResolveBlobIndex(partIndex)); } return(_debugHeapsOpt.GetBlobIndex(writer)); }
private void SerializeMethodDebugInfo(IMethodBody bodyOpt, int methodRid, int localSignatureRowId) { if (bodyOpt == null) { _methodBodyTable.Add(default(MethodBodyRow)); return; } bool isIterator = bodyOpt.StateMachineTypeName != null; bool emitDebugInfo = isIterator || bodyOpt.HasAnySequencePoints; if (!emitDebugInfo) { _methodBodyTable.Add(default(MethodBodyRow)); return; } var bodyImportScope = bodyOpt.ImportScope; int importScopeRid = (bodyImportScope != null) ? GetImportScopeIndex(bodyImportScope, _scopeIndex) : 0; // documents & sequence points: BlobIdx sequencePointsBlob = SerializeSequencePoints(localSignatureRowId, bodyOpt.GetSequencePoints(), _documentIndex); _methodBodyTable.Add(new MethodBodyRow { SequencePoints = sequencePointsBlob }); // Unlike native PDB we don't emit an empty root scope. // scopes are already ordered by StartOffset ascending then by EndOffset descending (the longest scope first). if (bodyOpt.LocalScopes.Length == 0) { // TODO: the compiler should produce a scope for each debuggable method _localScopeTable.Add(new LocalScopeRow { Method = (uint)methodRid, ImportScope = (uint)importScopeRid, VariableList = (uint)_localVariableTable.Count + 1, ConstantList = (uint)_localConstantTable.Count + 1, StartOffset = 0, Length = (uint)bodyOpt.IL.Length }); } else { foreach (LocalScope scope in bodyOpt.LocalScopes) { _localScopeTable.Add(new LocalScopeRow { Method = (uint)methodRid, ImportScope = (uint)importScopeRid, VariableList = (uint)_localVariableTable.Count + 1, ConstantList = (uint)_localConstantTable.Count + 1, StartOffset = (uint)scope.StartOffset, Length = (uint)scope.Length }); foreach (ILocalDefinition local in scope.Variables) { Debug.Assert(local.SlotIndex >= 0); _localVariableTable.Add(new LocalVariableRow { Attributes = (ushort)local.PdbAttributes, Index = (ushort)local.SlotIndex, Name = _debugHeapsOpt.GetStringIndex(local.Name) }); SerializeDynamicLocalInfo(local, rowId: _localVariableTable.Count, isConstant: false); } foreach (ILocalDefinition constant in scope.Constants) { var mdConstant = constant.CompileTimeValue; Debug.Assert(mdConstant != null); _localConstantTable.Add(new LocalConstantRow { Name = _debugHeapsOpt.GetStringIndex(constant.Name), Signature = SerializeLocalConstantSignature(constant) }); SerializeDynamicLocalInfo(constant, rowId: _localConstantTable.Count, isConstant: true); } } } var asyncDebugInfo = bodyOpt.AsyncDebugInfo; if (asyncDebugInfo != null) { _stateMachineMethodTable.Add(new StateMachineMethodRow { MoveNextMethod = (uint)methodRid, KickoffMethod = (uint)GetMethodDefIndex(asyncDebugInfo.KickoffMethod) }); SerializeAsyncMethodSteppingInfo(asyncDebugInfo, methodRid); } SerializeStateMachineLocalScopes(bodyOpt, methodRid); // delta doesn't need this information - we use information recorded by previous generation emit if (Context.ModuleBuilder.CommonCompilation.Options.EnableEditAndContinue && !IsFullMetadata) { SerializeEncMethodDebugInformation(bodyOpt, methodRid); } }
protected override int GetOrAddStandAloneSignatureIndex(BlobIdx blobIndex) { return(_standAloneSignatureIndex.GetOrAdd(blobIndex)); }
public int ResolveBlobIndex(BlobIdx index) { return((index.HeapPosition == 0) ? 0 : _blobHeapStartOffset + index.HeapPosition); }