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); }
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(); }
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(); }
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(); }
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); }
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(); } }
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); }
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"); }
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); }
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(); }