CustomAttributeWriter(ICustomAttributeWriterHelper helper) {
			this.helper = helper;
			this.recursionCounter = new RecursionCounter();
			this.outStream = new MemoryStream();
			this.writer = new BinaryWriter(outStream);
			this.genericArguments = null;
		}
 SignatureWriter(ISignatureWriterHelper helper)
 {
     this.helper = helper;
     this.recursionCounter = new RecursionCounter();
     this.outStream = new MemoryStream();
     this.writer = new BinaryWriter(outStream);
 }
Example #3
0
		void FixOffsets(RecursionCounter counter, DbiScope scope) {
			if (!counter.Increment())
				return;

			scope.BeginOffset -= Address.Offset;
			scope.EndOffset -= Address.Offset;
			foreach (var child in scope.Children)
				FixOffsets(counter, child);

			counter.Decrement();
		}
Example #4
0
        void FixOffsets(RecursionCounter counter, DbiScope scope)
        {
            if (!counter.Increment())
            {
                return;
            }

            scope.BeginOffset -= Address.Offset;
            scope.EndOffset   -= Address.Offset;
            foreach (var child in scope.Children)
            {
                FixOffsets(counter, child);
            }

            counter.Decrement();
        }
Example #5
0
		public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) {
			if (!counter.Increment())
				throw new PdbException("Scopes too deep");

			while (stream.Position < scopeEnd) {
				var size = stream.ReadUInt16();
				var begin = stream.Position;
				var end = begin + size;

				var type = (SymbolType)stream.ReadUInt16();
				DbiScope child = null;
				uint? childEnd = null;
				switch (type) {
					case SymbolType.S_BLOCK32: {
						stream.Position += 4;
						childEnd = stream.ReadUInt32();
						var len = stream.ReadUInt32();
						var addr = PdbAddress.ReadAddress(stream);
						var name = PdbReader.ReadCString(stream);
						child = new DbiScope(name, addr.Offset, len);
						break;
					}
					case SymbolType.S_UNAMESPACE:
						Namespaces.Add(new DbiNamespace(PdbReader.ReadCString(stream)));
						break;
					case SymbolType.S_MANSLOT: {
						var variable = new DbiVariable();
						variable.Read(stream);
						Variables.Add(variable);
						break;
					}
				}

				stream.Position = end;
				if (child != null) {
					child.Read(counter, stream, childEnd.Value);
					Children.Add(child);
					child = null;
				}
			}
			counter.Decrement();
			if (stream.Position != scopeEnd)
				Debugger.Break();
		}
Example #6
0
        internal TableQueryMap(Dictionary <string, string> usedPrefixes, string tableName, RecursionCounter recInfo)
        {
            Columns          = new Dictionary <string, ColumnInfo>();
            ReferenceColumns = new Dictionary <string, JoinColumnQueryMap>();
            Table            = tableName;

            if (recInfo == null)
            {
                recInfo = new RecursionCounter();
            }

            this.recInfo = recInfo;

            if (usedPrefixes == null)
            {
                usedPrefixes = new Dictionary <string, string>();
            }

            this.usedPrefixes = usedPrefixes;

            Prefix = GetNextPrefix(usedPrefixes, tableName, recInfo);
        }
Example #7
0
        public void RecursionCounter_does_not_share_state_across_threads()
        {
            var threads = 15;
            var barrier = new Barrier(threads);
            var counter = new RecursionCounter();

            Enumerable.Range(1, threads).ForEach(i => new Thread(() =>
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                barrier.SignalAndWait(10000);

                Assert.That(counter.Depth, Is.EqualTo(0));
                using (counter.Enter())
                {
                    Assert.That(counter.Depth, Is.EqualTo(1));
                    using (counter.Enter())
                    {
                        Assert.That(counter.Depth, Is.EqualTo(2));
                    }
                }
                Assert.That(counter.Depth, Is.EqualTo(0));
            }).Start());
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="GenericArgumentResolver"/> class.
 /// </summary>
 public GenericArgumentResolver()
 {
     genericArguments = new GenericArguments();
     recursionCounter = new RecursionCounter();
 }
        public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd)
        {
            if (!counter.Increment())
            {
                throw new PdbException("Scopes too deep");
            }

            while (reader.Position < scopeEnd)
            {
                var size  = reader.ReadUInt16();
                var begin = reader.Position;
                var end   = begin + size;

                var      type     = (SymbolType)reader.ReadUInt16();
                DbiScope child    = null;
                uint?    childEnd = null;
                string   name;
                switch (type)
                {
                case SymbolType.S_BLOCK32: {
                    reader.Position += 4;
                    childEnd         = reader.ReadUInt32();
                    var len  = reader.ReadUInt32();
                    var addr = PdbAddress.ReadAddress(ref reader);
                    name  = PdbReader.ReadCString(ref reader);
                    child = new DbiScope(method, this, name, addr.Offset, len);
                    break;
                }

                case SymbolType.S_UNAMESPACE:
                    namespacesList.Add(new DbiNamespace(PdbReader.ReadCString(ref reader)));
                    break;

                case SymbolType.S_MANSLOT: {
                    var variable = new DbiVariable();
                    if (variable.Read(ref reader))
                    {
                        localsList.Add(variable);
                    }
                    break;
                }

                case SymbolType.S_OEM:
                    if ((ulong)reader.Position + 20 > end)
                    {
                        break;
                    }
                    if (!ReadAndCompareBytes(ref reader, end, dotNetOemGuid))
                    {
                        Debug.Fail("Unknown OEM record GUID, not .NET GUID");
                        break;
                    }
                    reader.Position += 4;                            // typeIndex or 0
                    name             = ReadUnicodeString(ref reader, end);
                    Debug.Assert(name != null);
                    if (name == null)
                    {
                        break;
                    }
                    var data = reader.ReadBytes((int)(end - reader.Position));
                    if (oemInfos == null)
                    {
                        oemInfos = new List <OemInfo>(1);
                    }
                    oemInfos.Add(new OemInfo(name, data));
                    break;

                case SymbolType.S_MANCONSTANT:
                    uint   signatureToken = reader.ReadUInt32();
                    object value;
                    if (!NumericReader.TryReadNumeric(ref reader, end, out value))
                    {
                        break;
                    }
                    name = PdbReader.ReadCString(ref reader);
                    if (constants == null)
                    {
                        constants = new List <ConstantInfo>();
                    }
                    constants.Add(new ConstantInfo(name, signatureToken, value));
                    break;

                case SymbolType.S_END:
                    break;

                default:
                    break;
                }

                reader.Position = end;
                if (child != null)
                {
                    child.Read(counter, ref reader, childEnd.Value);
                    childrenList.Add(child);
                    child = null;
                }
            }
            counter.Decrement();
            if (reader.Position != scopeEnd)
            {
                Debugger.Break();
            }
        }
Example #10
0
        public void Perf_experiment_comparing_methods_of_tracking_recursion_depth_across_multiple_threads()
        {
            var simpleCounter = new RecursionCounter();

            int iterations = 1000000;

            Timer.TimeOperation(i =>
            {
                using (simpleCounter.Enter())
                using (simpleCounter.Enter())
                using (simpleCounter.Enter())
                {
                    Assert.That(simpleCounter.Depth, Is.EqualTo(3));
                }
            }, iterations, "simple counter", true);
        }
Example #11
0
        public void Perf_experiment_comparing_methods_of_tracking_recursion_depth()
        {
            var threadStaticCounter = new RecursionCounter();

            int iterations = 100000;

            Timer.TimeOperation(i =>
            {
                using (threadStaticCounter.Enter())
                using (threadStaticCounter.Enter())
                using (threadStaticCounter.Enter())
                {
                    Assert.That(threadStaticCounter.Depth, Is.EqualTo(3));
                }
            }, iterations, "simple counter");
        }
Example #12
0
        static string GetNextPrefix(Dictionary <string, string> usedPrefixes, string tableName, RecursionCounter recInfo)
        {
            if (recInfo.Iteration >= 650)
            {
                recInfo.Iteration = 0;
                recInfo.Recursion = recInfo.Recursion + 1;
            }
            var pref = CreatePrefix(recInfo.Iteration, recInfo.Recursion);

            while (usedPrefixes.ContainsKey(pref))
            {
                recInfo.Iteration = recInfo.Iteration + 1;
                if (recInfo.Iteration >= 650)
                {
                    recInfo.Iteration = 0;
                    recInfo.Recursion = recInfo.Recursion + 1;
                }

                pref = CreatePrefix(recInfo.Iteration, recInfo.Recursion);
            }

            usedPrefixes.Add(pref, tableName);
            return(pref);
        }
Example #13
0
        static void CreateDisplayName(StringBuilder sb, RecursionCounter recu, TypeSig sig, bool fullName)
        {
            if (sig == null)
            {
                sb.Append("<<<NULL>>>");
                return;
            }
            if (!recu.Increment())
            {
                sb.Append("<<<INFRECURSION>>>");
                return;
            }

            switch (sig.ElementType)
            {
            case ElementType.Void:
            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.Object:
            case ElementType.ValueType:
            case ElementType.Class:
                var type = ((TypeDefOrRefSig)sig).TypeDefOrRef;
                if (fullName)
                {
                    sb.Append(type.ReflectionFullName);
                }
                else
                {
                    sb.Append(type.Name ?? "<<<NULL>>>");
                }
                break;

            case ElementType.Ptr:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                sb.Append('*');
                break;

            case ElementType.ByRef:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                sb.Append('&');
                break;

            case ElementType.Array: {
                CreateDisplayName(sb, recu, sig.Next, fullName);
                var arraySig = (ArraySig)sig;
                sb.Append('[');
                uint rank = arraySig.Rank;
                if (rank == 0)
                {
                    sb.Append("<RANK0>");                             // Not allowed
                }
                else if (rank == 1)
                {
                    sb.Append('*');
                }
                else
                {
                    for (int i = 0; i < (int)rank; i++)
                    {
                        if (i != 0)
                        {
                            sb.Append(", ");
                        }

                        const int  NO_LOWER = int.MinValue;
                        const uint NO_SIZE  = uint.MaxValue;
                        int        lower    = arraySig.LowerBounds.Get(i, NO_LOWER);
                        uint       size     = arraySig.Sizes.Get(i, NO_SIZE);
                        if (lower != NO_LOWER)
                        {
                            sb.Append(lower);
                            sb.Append("..");
                            if (size != NO_SIZE)
                            {
                                sb.Append(lower + (int)size - 1);
                            }
                            else
                            {
                                sb.Append('.');
                            }
                        }
                    }
                }
                sb.Append(']');
                break;
            }

            case ElementType.SZArray:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                sb.Append("[]");
                break;

            case ElementType.CModReqd:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                sb.Append(" modreq(");
                sb.Append(((ModifierSig)sig).Modifier.Name ?? "<<<NULL>>>");
                sb.Append(")");
                break;

            case ElementType.CModOpt:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                sb.Append(" modopt(");
                sb.Append(((ModifierSig)sig).Modifier.Name ?? "<<<NULL>>>");
                sb.Append(")");
                break;

            case ElementType.Pinned:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                break;

            case ElementType.ValueArray:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                var valueArraySig = (ValueArraySig)sig;
                sb.Append(" ValueArray(");
                sb.Append(valueArraySig.Size);
                sb.Append(')');
                break;

            case ElementType.Module:
                CreateDisplayName(sb, recu, sig.Next, fullName);
                var moduleSig = (ModuleSig)sig;
                sb.Append(" Module(");
                sb.Append(moduleSig.Index);
                sb.Append(')');
                break;

            case ElementType.GenericInst: {
                var genericInstSig = (GenericInstSig)sig;
                var typeGenArgs    = genericInstSig.GenericArguments;
                CreateDisplayName(sb, recu, genericInstSig.GenericType, fullName);
                sb.Append('<');
                int i = -1;
                foreach (var genArg in typeGenArgs.GetSafeEnumerable())
                {
                    i++;
                    if (i != 0)
                    {
                        sb.Append(", ");
                    }
                    CreateDisplayName(sb, recu, genArg, false);
                }
                sb.Append('>');
            }
            break;

            case ElementType.Var:
            case ElementType.MVar:
                var gs = (GenericSig)sig;
                var gp = gs.GenericParam;
                if (gp == null || UTF8String.IsNullOrEmpty(gp.Name))
                {
                    sb.Append(gs.IsMethodVar ? "!!" : "!");
                    sb.Append(gs.Number);
                }
                else
                {
                    sb.Append(gp.Name);
                }
                break;

            case ElementType.FnPtr:
                sb.Append("(fnptr)");
                break;

            case ElementType.Sentinel:
                break;

            case ElementType.End:
            case ElementType.R:
            case ElementType.Internal:
            default:
                break;
            }

            recu.Decrement();
        }
Example #14
0
        public void RecursionCounter_does_not_share_state_across_threads()
        {
            var threads = 15;
            var barrier = new Barrier(threads);
            var counter = new RecursionCounter();

            Enumerable.Range(1, threads).ForEach(i => new Thread(() =>
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                barrier.SignalAndWait(10000);

                Assert.That(counter.Depth, Is.EqualTo(0));
                using (counter.Enter())
                {
                    Assert.That(counter.Depth, Is.EqualTo(1));
                    using (counter.Enter())
                    {
                        Assert.That(counter.Depth, Is.EqualTo(2));
                    }
                }
                Assert.That(counter.Depth, Is.EqualTo(0));
            }).Start());
        }