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);
        }
Example #2
0
        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));
        }
Example #3
0
        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);
            }
        }
Example #4
0
 protected override int GetOrAddStandAloneSignatureIndex(BlobIdx blobIndex)
 {
     return(_standAloneSignatureIndex.GetOrAdd(blobIndex));
 }
 public int ResolveBlobIndex(BlobIdx index)
 {
     return((index.HeapPosition == 0) ? 0 : _blobHeapStartOffset + index.HeapPosition);
 }